Compare commits

...

42 Commits
main ... mgy

Author SHA1 Message Date
Dawn1Ocean 04e616c477 fix: mainpage avatar & layout 2024-05-10 12:54:21 +08:00
Dawn1Ocean 3242b16e3d fix: ticketList service 2024-05-10 12:41:02 +08:00
Dawn1Ocean 6f960d46a8 fix: default dutyRecoverTime 2024-05-10 12:04:21 +08:00
Dawn1Ocean 669896d253 fix: alter message when inDutyCnt === 0 2024-05-10 11:27:32 +08:00
Dawn1Ocean fc9347e7c1 fix: changestatus 2024-05-10 11:14:23 +08:00
Dawn1Ocean 96dc81bd82 fix: dutyinfo display in mainpage 2024-05-10 10:42:44 +08:00
Dawn_Ocean 54d9dc45b4 fix: comment type 2024-05-09 17:39:41 +08:00
Dawn_Ocean 206eb49893 add member/checklogin in getInfo 2024-05-09 17:33:53 +08:00
Dawn_Ocean 590db1f3fd fix: add space in my continuing tickets; dutyinfo data process 2024-05-09 17:08:56 +08:00
Dawn_Ocean 5cc3387008 fix: get ticket id from url: string -> number 2024-05-09 16:50:17 +08:00
Dawn_Ocean fbe7b9d7de fix: dutyinfo when in duty 2024-04-24 00:19:46 +08:00
Dawn_Ocean 7e3ad80121 fix: memberDutyInfo api; dutyInfo card in MainPage 2024-04-23 17:10:22 +08:00
Dawn1Ocean 0dc87d06d6 fix: dutyinfo display; relaunch to Loading page 2024-04-23 15:59:22 +08:00
Dawn1Ocean 86398ff9a9 fix: request without token; request before getting id in detailframework 2024-04-23 10:17:02 +08:00
Dawn1Ocean 8b2ed25109 fix: request before getting token 2024-04-22 21:05:27 +08:00
Dawn1Ocean fb9f4b4342 small changes to test with ate 2024-04-21 23:06:06 +08:00
Dawn1Ocean 3313307e84 fix: wrong api & services 2024-04-12 01:51:22 +08:00
Dawn1Ocean b68e3db0a3 add conclusion page 2024-04-12 01:42:54 +08:00
Dawn1Ocean d7cdf46026 fix askleave locale & layout 2024-04-12 01:11:07 +08:00
Dawn1Ocean 6325147e81 refactor PicUploader from TicketDetail/Comment 2024-04-12 00:35:45 +08:00
Dawn1Ocean be687d0372 add entry for conclusion page 2024-04-11 19:34:05 +08:00
Dawn1Ocean 0351819fa2 add confirm modal in AskLeave 2024-04-11 17:01:08 +08:00
Dawn_Ocean a12c69cdc0 add entry for AskLeave 2024-04-11 16:14:01 +08:00
Dawn_Ocean 1702b5aa6a add AskLeave page 2024-04-11 15:26:11 +08:00
Dawn_Ocean 952a6caa24 add askleave api&service 2024-04-11 09:13:27 +08:00
Dawn_Ocean d1d01f0ad1 add pic upload service 2024-04-08 18:57:13 +08:00
Dawn_Ocean 51407930bb add pic uploader in ticketnote 2024-04-08 18:48:09 +08:00
Dawn_Ocean 097f6832e3 refactor: split ExpandItem from Mainpage 2024-04-08 15:55:01 +08:00
Dawn_Ocean 4d6eca0434 add pic preview in ticketnote 2024-04-08 15:42:02 +08:00
Dawn_Ocean ab52ffe7ae add pic display in ticketnote 2024-04-08 14:56:51 +08:00
Dawn_Ocean c487187451 change ticketinfo api 2024-04-08 14:20:21 +08:00
Dawn_Ocean 3fd0ebf9c8 refactor: split comment layout from ticketdetail 2024-04-08 14:10:26 +08:00
Dawn1Ocean 7a198cfe03 change /duty/info api 2024-04-07 12:29:07 +08:00
Dawn1Ocean ff926676bd change mytickets mock; add ignore for eslint error: unused state for statusToBe in ticketdetail 2024-04-06 02:27:16 +08:00
Dawn1Ocean 01614c9163 add hint for mytickets in repairpage 2024-04-06 02:05:01 +08:00
Dawn1Ocean 3375e00b37 refactor state structure in ticketdetail 2024-04-06 01:47:12 +08:00
Dawn1Ocean b14d9c363d add locale for reminder 2024-04-05 23:37:52 +08:00
Dawn1Ocean 7f017a0b47 add reminder structure in ticketdetail 2024-04-05 21:34:13 +08:00
Dawn1Ocean 5ce1db7693 refactor api for dutyinfo 2024-04-04 01:39:58 +08:00
Dawn1Ocean d34564980f change index page layout 2024-04-03 20:53:05 +08:00
Dawn1Ocean 5bd07e0ca7 refactor plain-text 2024-04-03 20:41:20 +08:00
Dawn1Ocean a07545b841 change pagination to icon; change updatedutycnt text 2024-03-30 15:56:52 +08:00
68 changed files with 1967 additions and 519 deletions

View File

@ -1,3 +1,4 @@
# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config # 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config
TARO_APP_ID="wx636eb7cf2b84f305" TARO_APP_ID="wx636eb7cf2b84f305"
TARO_APP_API="http://127.0.0.1:9527" TARO_APP_API="https://ate.zjueva.net"
# TARO_APP_API="http://127.0.0.1:9527"

View File

@ -44,9 +44,12 @@ data:
{ {
"isInDuty": true, "isInDuty": true,
"inDutyCnt": 3, "inDutyCnt": 3,
"currentDuty": "2", "currentDuty": "1",
"place": "东三-204", "place": "", // 只有当 currentDuty 为 others 时place 和 值班时间 才不为空
"otherDutyTime": "" "otherDutyStart": "",
"otherDutyEnd": "",
"offDutyReason": "",
"dutyRecoverTime": ""
} }
``` ```
@ -59,8 +62,11 @@ data:
"isInDuty": true, "isInDuty": true,
"inDutyCnt": 3, "inDutyCnt": 3,
"currentDuty": "others", "currentDuty": "others",
"place": "蓝田", "place": "蓝田", // 只有当 currentDuty 为 others 时place 才不为空
"otherDutyTime": "9:30-11:30" "otherDutyStart": "2024-03-07T11:52:48.523303", // Timestamp
"otherDutyEnd": "2024-03-07T13:52:48.523303",
"offDutyReason": "",
"dutyRecoverTime": ""
} }
``` ```
@ -71,11 +77,33 @@ data:
```json ```json
{ {
"isInDuty": false, "isInDuty": false,
"inDutyCnt": 0,
"currentDuty": "0", // '0' 代表正常值班时间下班,'others' 代表其他值班时间下班
"place": "",
"otherDutyStart": "",
"otherDutyEnd": "",
"offDutyReason": "学园维修", "offDutyReason": "学园维修",
"dutyRecoverTime": "下周一" "dutyRecoverTime": "下周一"
} }
``` ```
#### 当前值班暂停
data:
```json
{
"isInDuty": false,
"inDutyCnt": 0,
"currentDuty": "off", // 'off' 代表当前值班暂停
"place": "",
"otherDutyStart": "",
"otherDutyEnd": "",
"offDutyReason": "考试周",
"dutyRecoverTime": "下周一"
}
```
## 账号登陆 ## 账号登陆
### 微信小程序登陆 `POST /login` OK ### 微信小程序登陆 `POST /login` OK
@ -220,7 +248,15 @@ Request
{ {
"token": "token_test", "token": "token_test",
"id": "id", "id": "id",
"content" : "为什么 PD 不能充电呢?" "content": "为什么 PD 不能充电呢?",
}
```
Data
```json
{
"id": "id", // 返回的是评论的 id
} }
``` ```
@ -333,7 +369,8 @@ data (same as oreo):
"op": "宇航员", "op": "宇航员",
"type": 0, "type": 0,
"content": "", "content": "",
"createdTime": "2024-03-07T19:52:48.523305" "createdTime": "2024-03-07T19:52:48.523305",
"pic": [], // 只有当 type = 1 (评论) 时 pic 才有可能非空
}, },
{ {
"avatar": "https://....jpg", "avatar": "https://....jpg",
@ -341,7 +378,8 @@ data (same as oreo):
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "1", "content": "1",
"createdTime": "2024-03-07T19:58:27.838816" "createdTime": "2024-03-07T19:58:27.838816",
"pic": [], // 只有当 type = 1 (评论) 时 pic 才有可能非空
}, },
{ {
"avatar": "https://....jpg", "avatar": "https://....jpg",
@ -349,7 +387,8 @@ data (same as oreo):
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "4", "content": "4",
"createdTime": "2024-03-07T20:28:12.070707" "createdTime": "2024-03-07T20:28:12.070707",
"pic": [], // 只有当 type = 1 (评论) 时 pic 才有可能非空
}, },
{ {
"avatar": "https://....jpg", "avatar": "https://....jpg",
@ -357,7 +396,20 @@ data (same as oreo):
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "5", "content": "5",
"createdTime": "2024-03-07T20:30:15.770486" "createdTime": "2024-03-07T20:30:15.770486",
"pic": [], // 只有当 type = 1 (评论) 时 pic 才有可能非空
},
{
"avatar": "https://....jpg",
"id": 21374,
"op": "宇航员",
"type": 1,
"content": "清灰换硅脂",
"createdTime": "2024-03-07T20:30:15.780486",
"pic": [
"https://....jpg",
...
]
} }
], ],
"accessories": [2], "accessories": [2],
@ -409,9 +461,14 @@ data:
```json ```json
{ {
"isInDuty": true, "isInDuty": true, // 指示成员其当前是否在值班
"inDutyCnt": 3, "inDutyCnt": 3,
"currentDuty": "2" "currentDuty": "others",
"place": "蓝田", // 只有当 currentDuty 为 others 时place 才不为空
"otherDutyStart": "2024-03-07T11:52:48.523303", // Timestamp
"otherDutyEnd": "2024-03-07T13:52:48.523303",
"offDutyReason": "",
"dutyRecoverTime": ""
} }
``` ```
@ -422,7 +479,50 @@ data:
```json ```json
{ {
"isInDuty": false, "isInDuty": false,
"offDutyReason": "学园维修", "inDutyCnt": 0,
"currentDuty": "off", // "0" => 正常值班下班,"others" => 其他值班下班,"off" => 值班暂停
"place": "", // 只有当 currentDuty 为 others 时place 才不为空
"otherDutyStart": "",
"otherDutyEnd": "",
"offDutyReason": "期中考试周",
"dutyRecoverTime": "下周一" "dutyRecoverTime": "下周一"
} }
``` ```
### 成员请假 `POST /member/askleave`
Request
```json
{
"token": "token_test",
"week": "1",
"shift": "2",
"reason": "家庭原因",
"substitute": "晓洋" // 未找人代班则为空
}
```
### 值班总结上传 `POST /member/conclusion`
Request
```json
{
"token": "token_test",
"week": "2",
"shift": "3",
"conclusion": "周四第三班,一人请假,共收两台电脑,均劝退已取回。由上一班交接两台电脑,其中一台维修成功已取回,一台仍在维修。"
}
```
### 修改值班人数 `POST /member/dutycnt`
Request
```json
{
"token": "token_test",
"dutycnt": 5,
}
```

View File

@ -14,18 +14,19 @@ export default {
'GET /duty/info': { 'GET /duty/info': {
success: true, success: true,
data: { data: {
token: 'token_test',
isInDuty: true, isInDuty: true,
inDutyCnt: 3, inDutyCnt: 3,
currentDuty: 'others', currentDuty: 'others',
otherDutyTime: '9:30-11:30', otherDutyStart: '2024-03-07T09:30:48.523303',
otherDutyEnd: '2024-03-07T13:30:48.523303',
place: '蓝田', place: '蓝田',
offDutyReason: '',
dutyRecoverTime: '',
}, },
}, },
'GET /user/info': { 'GET /user/info': {
success: true, success: true,
data: { data: {
token: 'token_test',
name: '马保国', name: '马保国',
phone: 13333333333, phone: 13333333333,
}, },
@ -58,7 +59,9 @@ export default {
}, },
'POST /tickets/addnote': { 'POST /tickets/addnote': {
success: true, success: true,
data: {}, data: {
id: 114,
},
}, },
'POST /tickets/create': { 'POST /tickets/create': {
success: true, success: true,
@ -116,13 +119,19 @@ export default {
'GET /member/duty/info': { 'GET /member/duty/info': {
success: true, success: true,
data: { data: {
token: 'token_test',
isInDuty: true, isInDuty: true,
inDutyCnt: 6, inDutyCnt: 3,
currentDuty: '3', currentDuty: 'others',
place: '204', otherDutyStart: '2024-03-07T09:30:48.523303',
otherDutyEnd: '2024-03-07T13:30:48.523303',
place: '蓝田',
offDutyReason: '',
dutyRecoverTime: '',
}, },
}, },
'POST /member/askleave': {
success: true,
},
'POST /login': { 'POST /login': {
success: true, success: true,
data: { data: {
@ -132,7 +141,19 @@ export default {
'GET /checklogin': { 'GET /checklogin': {
success: true, success: true,
data: { data: {
islogin: false, islogin: true,
}, },
}, },
'POST /upload/pic': {
success: true,
},
'POST /member/conclusion': {
success: true,
data: {
id: 514,
},
},
'POST /member/dutycnt': {
success: true,
},
}; };

View File

@ -3,13 +3,24 @@
{ {
"id": 6830, "id": 6830,
"type": 1, "type": 1,
"status": 2, "status": 3,
"device": "主机", "device": "主机",
"deviceModel": "技嘉", "deviceModel": "技嘉",
"owner": "武技栏", "owner": "武技栏",
"phone": "18888888888", "phone": "18888888888",
"createdTime": "2024-03-06T19:49:27.043865", "createdTime": "2024-03-06T19:49:27.043865",
"isConfirmed": false "isConfirmed": false
},
{
"id": 6831,
"type": 1,
"status": 2,
"device": "ROG",
"deviceModel": "幻 14",
"owner": "晓洋",
"phone": "18888888887",
"createdTime": "2024-03-06T19:49:27.043865",
"isConfirmed": false
} }
] ]
} }

View File

@ -8,7 +8,7 @@
"description": "清灰", "description": "清灰",
"workers": ["宇航员"], "workers": ["宇航员"],
"createdTime": "2024-03-07T19:52:48.523303", "createdTime": "2024-03-07T19:52:48.523303",
"status": 5, "status": 4,
"isConfirmed": false, "isConfirmed": false,
"notes": [ "notes": [
{ {
@ -17,7 +17,8 @@
"op": "宇航员", "op": "宇航员",
"type": 0, "type": 0,
"content": "", "content": "",
"createdTime": "2024-03-07T19:52:48.523305" "createdTime": "2024-03-07T19:52:48.523305",
"pic": []
}, },
{ {
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png", "avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
@ -25,7 +26,8 @@
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "1", "content": "1",
"createdTime": "2024-03-07T19:58:27.838816" "createdTime": "2024-03-07T19:58:27.838816",
"pic": []
}, },
{ {
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png", "avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
@ -33,7 +35,8 @@
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "4", "content": "4",
"createdTime": "2024-03-07T20:28:12.070707" "createdTime": "2024-03-07T20:28:12.070707",
"pic": []
}, },
{ {
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png", "avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
@ -41,7 +44,21 @@
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "5", "content": "5",
"createdTime": "2024-03-07T20:30:15.770486" "createdTime": "2024-03-07T20:30:15.770486",
"pic": []
},
{
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
"id": 21374,
"op": "宇航员",
"type": 1,
"content": "清灰换硅脂",
"createdTime": "2024-03-07T20:30:15.780486",
"pic": [
"https://storage.360buyimg.com/mtd/home/111543234387022.jpg",
"https://storage.360buyimg.com/mtd/home/221543234387016.jpg",
"https://storage.360buyimg.com/mtd/home/331543234387025.jpg"
]
} }
], ],
"accessories": [2], "accessories": [2],

View File

@ -9,7 +9,7 @@
"enhance": false, "enhance": false,
"compileHotReLoad": false, "compileHotReLoad": false,
"postcss": false, "postcss": false,
"minified": false, "minified": true,
"babelSetting": { "babelSetting": {
"ignore": [], "ignore": [],
"disablePlugins": [], "disablePlugins": [],

View File

@ -3,7 +3,7 @@
"projectname": "EVA-Notify", "projectname": "EVA-Notify",
"setting": { "setting": {
"compileHotReLoad": true, "compileHotReLoad": true,
"urlCheck": false, "urlCheck": true,
"bigPackageSizeSupport": true "bigPackageSizeSupport": true
} }
} }

View File

@ -1,5 +1,6 @@
export default defineAppConfig({ export default defineAppConfig({
pages: [ pages: [
'pages/Loading/Loading',
'pages/index/index', 'pages/index/index',
'pages/repair/repair', 'pages/repair/repair',
'pages/user/user', 'pages/user/user',
@ -10,6 +11,8 @@ export default defineAppConfig({
'pages/user/member/member', 'pages/user/member/member',
'pages/TicketDetail/TicketDetail', 'pages/TicketDetail/TicketDetail',
'pages/TicketList/TicketList', 'pages/TicketList/TicketList',
'pages/AskLeave/AskLeave',
'pages/Conclusion/Conclusion',
'pages/404/404', 'pages/404/404',
], ],
window: { window: {

View File

@ -109,7 +109,7 @@ export default class DetailFramework extends Component<
marginLeft: '3%', marginLeft: '3%',
}} }}
> >
<AtCard isFull title={pt.get().ticketDetail.descTitle}> <AtCard isFull title={pt.get().ticketDetail.desc.title}>
<View className='at-article__h3'> <View className='at-article__h3'>
{this.state.ticketInfo.description} {this.state.ticketInfo.description}
</View> </View>
@ -160,12 +160,13 @@ export default class DetailFramework extends Component<
notelist: this.props.isInfoShow['notelist'] ? ( notelist: this.props.isInfoShow['notelist'] ? (
this.props.isInfoShow['showAllNotes'] ? ( this.props.isInfoShow['showAllNotes'] ? (
<View style={{ padding: '20rpx' }}> <View style={{ padding: '20rpx' }}>
<NoteList noteList={this.state.notes} /> <NoteList noteList={this.state.notes} showPic />
</View> </View>
) : ( ) : (
<View style={{ padding: '20rpx' }}> <View style={{ padding: '20rpx' }}>
<NoteList <NoteList
noteList={[this.state.notes[this.state.notes.length - 1]]} noteList={[this.state.notes[this.state.notes.length - 1]]}
showPic={false}
/> />
</View> </View>
) )

View File

@ -0,0 +1,3 @@
export default {
component: true,
};

View File

@ -0,0 +1,31 @@
import { View } from '@tarojs/components';
import { Component, ReactNode } from 'react';
import { AtAccordion } from 'taro-ui';
export class ExpandItem extends Component {
state = {
open: false,
};
props = {
title: '',
content: <View></View>,
};
handleClick(value: boolean) {
this.setState({ open: value });
}
render(): ReactNode {
return (
<View>
<AtAccordion
open={this.state.open}
onClick={this.handleClick.bind(this)}
title={this.props.title}
>
{this.props.content}
</AtAccordion>
</View>
);
}
}

View File

@ -3,40 +3,75 @@ import { Component, ReactNode } from 'react';
import { TicketNote, StatusStr } from '@/pages/TicketDetail/TicketNote'; import { TicketNote, StatusStr } from '@/pages/TicketDetail/TicketNote';
import pt from '@/plain-text'; import pt from '@/plain-text';
import { timeFormat } from '@/utils'; import { timeFormat } from '@/utils';
import Taro from '@tarojs/taro';
import './NoteCard.scss'; import './NoteCard.scss';
interface NoteCardProps { interface NoteCardProps {
note: TicketNote; note: TicketNote;
showPic: boolean;
} }
export default class NoteCard extends Component<NoteCardProps, {}> { export default class NoteCard extends Component<NoteCardProps, {}> {
props: Readonly<NoteCardProps> = { props: Readonly<NoteCardProps> = {
note: new TicketNote(), note: new TicketNote(),
showPic: true,
}; };
render(): ReactNode { render(): ReactNode {
var message = ''; let message = '';
let pic: string[] = [];
const note = this.props.note; const note = this.props.note;
const td = pt.get().ticketDetail; const td = pt.get().ticketDetail;
const createMessage = td.createTicketMessage; const createMessage = td.comment.createTicketMessage;
const modifyMessage = td.statusModifyMessage; const modifyMessage = td.statusModifyMessage;
const prefix = td.statusModifyPrefix; const prefix = td.comment.statusModifyPrefix;
switch (note.type) { switch (note.type) {
case 0: case 0:
message = createMessage; message = createMessage;
break; break;
case 1: case 1:
message = note.content; message = pt.get().ticketDetail.comment.picked;
break; break;
case 2: case 2:
message = prefix + modifyMessage.get(note.content as StatusStr) || ''; message = prefix + modifyMessage.get(note.content as StatusStr) || '';
break; break;
case 3:
message = note.content;
pic = note.pic;
break;
} }
const showPicDetail = (url: string) => {
Taro.previewImage({
current: url,
urls: [url],
});
};
const notePicRenderer = (
<View>
<View className='at-row' style={{ marginLeft: '30rpx' }}>
{pic.map((url, idx) => (
<View className='at-col at-col-4' key={idx}>
<Image
style='width: 160rpx; height: 160rpx;'
src={url}
mode='aspectFit'
onClick={showPicDetail.bind(this, url)}
/>
</View>
))}
</View>
</View>
);
return ( return (
<View className='at-row at-row__align--center'> <View className='at-row at-row__align--start'>
<View className='at-col at-col-1 at-col--auto'> <View
className='at-col at-col-1 at-col--auto'
style={{ marginTop: '80rpx' }}
>
<Image <Image
style='width: 70rpx; height: 70rpx; border-radius: 35px;' style='width: 70rpx; height: 70rpx; border-radius: 35px;'
src={note.avatar} src={note.avatar}
@ -55,7 +90,10 @@ export default class NoteCard extends Component<NoteCardProps, {}> {
<View className='at-article__info'> <View className='at-article__info'>
{note.createdTime.format(timeFormat)} {note.createdTime.format(timeFormat)}
</View> </View>
<View className='at-article__h3'>{message}</View> <View className='at-article__h3' style={{ marginBottom: '20rpx' }}>
{message}
</View>
{this.props.showPic ? notePicRenderer : null}
</View> </View>
</View> </View>
); );

View File

@ -7,11 +7,13 @@ import pt from '@/plain-text';
interface NoteListProps { interface NoteListProps {
noteList: Array<TicketNote>; noteList: Array<TicketNote>;
showPic: boolean;
} }
export default class NoteList extends Component<NoteListProps, {}> { export default class NoteList extends Component<NoteListProps, {}> {
props: Readonly<NoteListProps> = { props: Readonly<NoteListProps> = {
noteList: [], noteList: [],
showPic: true,
}; };
render(): ReactNode { render(): ReactNode {
return ( return (
@ -23,7 +25,7 @@ export default class NoteList extends Component<NoteListProps, {}> {
/> />
{this.props.noteList.map((note, idx) => ( {this.props.noteList.map((note, idx) => (
<View key={idx}> <View key={idx}>
<NoteCard note={note} /> <NoteCard note={note} showPic={this.props.showPic} />
</View> </View>
))} ))}
</View> </View>

View File

@ -0,0 +1,3 @@
export default {
component: true,
};

View File

@ -0,0 +1,66 @@
import { picUpload } from '@/service/picUpload';
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { Component, ReactNode } from 'react';
import { AtImagePicker } from 'taro-ui';
import { File } from 'taro-ui/types/image-picker';
const reLaunchInterval = 1000;
interface PicUploaderState {
files: File[];
}
interface PicUploaderProps {
source: string;
id: number;
superId?: number;
}
export default class PicUploader extends Component<
PicUploaderProps,
PicUploaderState
> {
state = {
files: [] as File[],
};
onUpload() {
if (this.state.files.length !== 0) {
for (let file of this.state.files) {
picUpload(this, file.url);
}
}
if (this.props.source == 'comment') {
setTimeout(() => {
Taro.reLaunch({
url: '/pages/TicketDetail/TicketDetail?id=' + this.props.superId,
});
}, reLaunchInterval);
} else if (this.props.source == 'conclusion') {
setTimeout(() => {
Taro.reLaunch({
url: '/pages/index/index',
});
}, reLaunchInterval);
}
}
handlePicChange(files: File[]) {
this.setState({
files: files,
});
return files;
}
render(): ReactNode {
return (
<View>
<AtImagePicker
showAddBtn={this.state.files.length !== 3}
count={3}
files={this.state.files}
sizeType={['compressed']}
onChange={this.handlePicChange.bind(this)}
/>
</View>
);
}
}

View File

@ -19,14 +19,14 @@ export default class NotFoundPage extends Component {
style={{ marginTop: '150rpx', marginBottom: '240rpx' }} style={{ marginTop: '150rpx', marginBottom: '240rpx' }}
> >
<View className='at-article__h1' style={{ fontWeight: 'bold' }}> <View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{pt.get().notFound.titleZhCn} {pt.get().notFound.title.ZhCn}
</View> </View>
<View className='at-article__h2'>{pt.get().notFound.descZhCn}</View> <View className='at-article__h2'>{pt.get().notFound.desc.ZhCn}</View>
<View style={{ height: '150rpx' }}></View> <View style={{ height: '150rpx' }}></View>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}> <View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{pt.get().notFound.titleEnUs} {pt.get().notFound.title.EnUs}
</View> </View>
<View className='at-article__h2'>{pt.get().notFound.descEnUs}</View> <View className='at-article__h2'>{pt.get().notFound.desc.EnUs}</View>
</View> </View>
<PageFooter /> <PageFooter />
</View> </View>

View File

@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});

View File

View File

@ -0,0 +1,187 @@
import {
AtTextarea,
AtButton,
AtForm,
AtMessage,
AtInput,
AtList,
AtListItem,
AtModal,
} from 'taro-ui';
import { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import { Picker, View } from '@tarojs/components';
import { askLeave } from '@/service/askleave';
import './AskLeave.scss';
const submitInterval = 5000;
export default class AskLeavePage extends Component {
state = {
isLoading: false,
isDisable: false,
showModal: false,
range: [pt.get().askLeave.shift.week, pt.get().askLeave.shift.shift],
shift: [0, 0],
reason: '',
substitute: '',
};
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.askLeave,
});
}
onShiftSelect(event) {
this.setState({
shift: event.detail.value,
});
console.log(event);
}
onModalClose() {
this.setState({
showModal: false,
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
onModalCancel() {
this.setState({
showModal: false,
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
onModalConfirm() {
this.setState({
showModal: false,
});
askLeave(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
handleReasonChange(reason: string) {
this.setState({
reason,
});
}
handleSubstituteChange(substitute: string) {
this.setState({
substitute,
});
}
onSubmit() {
this.setState({
isDisable: true,
});
if (this.state.reason == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
return;
}
if (this.state.substitute == '') {
this.setState({
showModal: true,
});
return;
}
askLeave(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
render(): ReactNode {
return (
<View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}>
<AtMessage />
<AtModal
isOpened={this.state.showModal}
title={pt.get().askLeave.modal.title}
cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm}
onClose={this.onModalClose.bind(this)}
onCancel={this.onModalCancel.bind(this)}
onConfirm={this.onModalConfirm.bind(this)}
content={pt.get().askLeave.modal.content}
/>
<AtForm onSubmit={this.onSubmit.bind(this)}>
<View style={{ width: '98%', marginLeft: '1%' }}>
<Picker
mode='multiSelector'
range={this.state.range}
onChange={this.onShiftSelect.bind(this)}
value={this.state.shift}
>
<AtList>
<AtListItem
title={pt.get().askLeave.shift.title}
extraText={
pt.get().askLeave.shift.week[this.state.shift[0]] +
pt.get().askLeave.shift.shift[this.state.shift[1]]
}
/>
</AtList>
</Picker>
</View>
<View
className='at-article__h3'
style={{ marginTop: '20rpx', marginBottom: '20rpx' }}
>
{pt.get().askLeave.reason.title}
</View>
<AtTextarea
value={this.state.reason}
onChange={this.handleReasonChange.bind(this)}
maxLength={200}
placeholder={pt.get().askLeave.reason.placeHolder}
/>
<AtInput
name='substitute'
title={pt.get().askLeave.substitute.title}
type='text'
placeholder={pt.get().askLeave.substitute.placeHolder}
value={this.state.substitute}
onChange={this.handleSubstituteChange.bind(this)}
/>
<View>
<AtButton
loading={this.state.isLoading}
formType='submit'
type='primary'
disabled={this.state.isDisable}
>
{pt.get().button.buttonText.submit}
</AtButton>
</View>
</AtForm>
</View>
);
}
}

View File

@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});

View File

@ -0,0 +1,129 @@
import {
AtTextarea,
AtButton,
AtForm,
AtMessage,
AtList,
AtListItem,
} from 'taro-ui';
import React, { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import { Picker, View } from '@tarojs/components';
import PicUploader from '@/components/PicUploader/PicUploader';
import { conclude } from '@/service/conclude';
import './Conclusion.scss';
const submitInterval = 5000;
export default class ConclusionPage extends Component {
state = {
isLoading: false,
isDisable: false,
conclusion: '',
conclusionId: 0,
range: [pt.get().askLeave.shift.week, pt.get().askLeave.shift.shift],
shift: [0, 0],
};
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.conclusion,
});
}
uploaderRef = React.createRef<PicUploader>();
handleConclusionChange(conclusion: string) {
this.setState({
conclusion,
});
}
onShiftSelect(event) {
this.setState({
shift: event.detail.value,
});
console.log(event);
}
onSubmit() {
this.setState({
isDisable: true,
});
if (this.state.conclusion == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
return;
}
conclude(this);
this.uploaderRef.current?.onUpload();
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
render(): ReactNode {
return (
<View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}>
<AtMessage />
<AtForm onSubmit={this.onSubmit.bind(this)}>
<View style={{ width: '98%', marginLeft: '1%' }}>
<Picker
mode='multiSelector'
range={this.state.range}
onChange={this.onShiftSelect.bind(this)}
value={this.state.shift}
>
<AtList>
<AtListItem
title={pt.get().askLeave.shift.title}
extraText={
pt.get().askLeave.shift.week[this.state.shift[0]] +
pt.get().askLeave.shift.shift[this.state.shift[1]]
}
/>
</AtList>
</Picker>
</View>
<View
className='at-article__h3'
style={{ marginTop: '20rpx', marginBottom: '20rpx' }}
>
{pt.get().conclusion.title}
</View>
<AtTextarea
value={this.state.conclusion}
onChange={this.handleConclusionChange.bind(this)}
maxLength={200}
height={400}
placeholder={pt.get().conclusion.placeHolder}
/>
<PicUploader
ref={this.uploaderRef}
source='conclusion'
id={this.state.conclusionId}
/>
<View>
<AtButton
loading={this.state.isLoading}
formType='submit'
type='primary'
disabled={this.state.isDisable}
>
{pt.get().button.buttonText.submit}
</AtButton>
</View>
</AtForm>
</View>
);
}
}

View File

@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});

View File

View File

@ -0,0 +1,30 @@
import { AtActivityIndicator } from 'taro-ui';
import { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import { View } from '@tarojs/components';
import wechatUser from '@/wechat';
import './Loading.scss';
export default class LoadingPage extends Component {
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.loading,
});
if (wechatUser.getToken()) {
Taro.reLaunch({
url: '/pages/index/index',
});
}
}
render(): ReactNode {
return (
<View>
<AtActivityIndicator
mode='center'
content={pt.get().actIndicator.loading}
></AtActivityIndicator>
</View>
);
}
}

View File

@ -0,0 +1,101 @@
import { ExpandItem } from '@/components/ExpandItem/ExpandItem';
import PicUploader from '@/components/PicUploader/PicUploader';
import pt from '@/plain-text';
import { submitComment } from '@/service/submitComment';
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import React, { Component, ReactNode } from 'react';
import { AtButton, AtForm, AtTextarea } from 'taro-ui';
const submitInterval = 5000;
export interface commentData {
content: string;
id: number;
}
export class Comment extends Component {
state = {
isLoading: false,
isDisable: false,
comment: '',
commentId: 0,
};
uploaderRef = React.createRef<PicUploader>();
props = {
setFloatLayout: (_: boolean) => {},
id: 0,
didMount: false,
};
handleCommentChange(comment: string) {
this.setState({
comment: comment,
});
return comment;
}
onCommentSubmit() {
this.setState({
isDisable: true,
});
this.props.setFloatLayout(false);
if (this.state.comment == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
return;
}
submitComment(this);
this.uploaderRef.current?.onUpload();
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
render(): ReactNode {
return this.props.didMount ? (
<AtForm onSubmit={this.onCommentSubmit.bind(this)}>
<AtTextarea
value={this.state.comment}
onChange={this.handleCommentChange.bind(this)}
maxLength={200}
height='400rpx'
placeholder={pt.get().ticketDetail.comment.placeholder}
/>
<ExpandItem
title={pt.get().ticketDetail.comment.uploadPic.title}
content={
<PicUploader
ref={this.uploaderRef}
source='comment'
superId={this.props.id}
id={this.state.commentId}
/>
}
/>
<AtButton
loading={this.state.isLoading}
disabled={this.state.isDisable}
formType='submit'
type='primary'
>
{pt.get().button.buttonText.submit}
</AtButton>
<View style={{ marginBottom: '20rpx' }}></View>
</AtForm>
) : (
<View></View>
);
}
}

View File

@ -6,15 +6,14 @@ import {
AtActionSheet, AtActionSheet,
AtActionSheetItem, AtActionSheetItem,
AtButton, AtButton,
AtCheckbox,
AtFloatLayout, AtFloatLayout,
AtForm, AtForm,
AtMessage, AtMessage,
AtModal, AtModal,
AtTextarea,
} from 'taro-ui'; } from 'taro-ui';
import DetailFramework from '@/components/DetailFramework/DetailFramework'; import DetailFramework from '@/components/DetailFramework/DetailFramework';
import PageFooter from '@/components/PageFooter/PageFooter'; import PageFooter from '@/components/PageFooter/PageFooter';
import { submitComment } from '@/service/submitComment';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import { addToOreo } from '@/service/addToOreo'; import { addToOreo } from '@/service/addToOreo';
@ -22,139 +21,270 @@ import { pickTicket } from '@/service/pickTicket';
import { retrieve } from '@/service/retrieve'; import { retrieve } from '@/service/retrieve';
import { changeStatus } from '@/service/changeStatus'; import { changeStatus } from '@/service/changeStatus';
import { getDisable } from '@/service/getDisable'; import { getDisable } from '@/service/getDisable';
import { StatusStr } from './TicketNote';
import { Comment } from './Comment';
const submitInterval = 5000; const submitInterval = 5000;
interface TicketDetailState { interface TicketDetailState {
id: number; id: number;
isMember: boolean; isMember: boolean;
showOreoModal: boolean; show: {
showCommentLayout: boolean; modal: {
showRetrieveModal: boolean; oreo: boolean;
showStatusSheet: boolean; retrieve: boolean;
showPickModal: boolean; pick: boolean;
comment: string; };
isOreoLoading: boolean; layout: {
isOreoDisable: boolean; comment: boolean;
isOreoDisable_main: boolean; reminder: boolean;
isPickLoading: boolean; };
isPickDisable: boolean; actionSheet: {
isPickDisable_main: boolean; status: boolean;
isRetrieveLoading: boolean; };
isRetrieveDisable: boolean; };
isRetrieveDisable_main: boolean; isLoading: {
isStatusLoading: boolean; oreo: boolean;
isStatusDisable: boolean; pick: boolean;
isCommentLoading: boolean; retrieve: boolean;
isCommentDisable: boolean; comment: boolean;
isCommentDisable_main: boolean; status: boolean;
reminder: boolean;
framework: boolean;
};
isDisable: {
oreo: boolean;
pick: boolean;
retrieve: boolean;
comment: boolean;
status: boolean;
reminder: boolean;
};
isDisable_main: {
oreo: boolean;
pick: boolean;
retrieve: boolean;
comment: boolean;
};
reminderList: Array<number>;
statusToBe: number;
} }
export default class TicketDetail extends Component<{}, TicketDetailState> { export default class TicketDetail extends Component<{}, TicketDetailState> {
state: Readonly<TicketDetailState> = { state: Readonly<TicketDetailState> = {
id: 0, id: 0,
isMember: false, isMember: false,
showOreoModal: false, show: {
showCommentLayout: false, modal: {
showRetrieveModal: false, oreo: false,
showStatusSheet: false, retrieve: false,
showPickModal: false, pick: false,
comment: '', },
isOreoLoading: false, layout: {
isOreoDisable: false, comment: false,
isOreoDisable_main: false, reminder: false,
isPickLoading: false, },
isPickDisable: false, actionSheet: {
isPickDisable_main: false, status: false,
isRetrieveLoading: false, },
isRetrieveDisable: false, },
isRetrieveDisable_main: false, isLoading: {
isStatusLoading: false, oreo: false,
isStatusDisable: false, pick: false,
isCommentLoading: false, retrieve: false,
isCommentDisable: false, comment: false,
isCommentDisable_main: false, status: false,
reminder: false,
framework: true,
},
isDisable: {
oreo: false,
pick: false,
retrieve: false,
comment: false,
status: false,
reminder: false,
},
isDisable_main: {
oreo: false,
pick: false,
retrieve: false,
comment: false,
},
reminderList: [],
// eslint-disable-next-line react/no-unused-state
statusToBe: 0,
}; };
componentDidMount(): void { componentDidMount(): void {
const { router } = getCurrentInstance(); const { router } = getCurrentInstance();
const id = router?.params.id as number; const id = Number(router?.params.id);
this.setState({ this.setState({
id: id, id: id,
isMember: wechatUser.getAccess(), isMember: wechatUser.getAccess(),
}); });
getDisable(this, id); getDisable(this, id);
this.setState({
isLoading: {
...this.state.isLoading,
framework: false,
},
});
} }
onAddToOreo(): void { onAddToOreo(): void {
this.setState({ this.setState({
showOreoModal: true, show: {
...this.state.show,
modal: {
...this.state.show.modal,
oreo: true,
},
},
}); });
} }
onAddComment(): void { onAddComment(): void {
this.setState({ this.setState({
showCommentLayout: true, show: {
...this.state.show,
layout: {
...this.state.show.layout,
comment: true,
},
},
}); });
} }
onRetrieved(): void { onRetrieved(): void {
this.setState({ this.setState({
showRetrieveModal: true, show: {
...this.state.show,
modal: {
...this.state.show.modal,
retrieve: true,
},
},
}); });
} }
onPick(): void { onPick(): void {
this.setState({ this.setState({
showPickModal: true, show: {
...this.state.show,
modal: {
...this.state.show.modal,
pick: true,
},
},
}); });
} }
onChangeStatus(): void { onChangeStatus(): void {
this.setState({ this.setState({
showStatusSheet: true, show: {
...this.state.show,
actionSheet: {
...this.state.show.actionSheet,
status: true,
},
},
}); });
} }
handleOreoCancel(): void { handleOreoCancel(): void {
this.setState({ this.setState({
showOreoModal: false, show: {
...this.state.show,
modal: {
...this.state.show.modal,
oreo: false,
},
},
}); });
} }
handleCommentCancel(): void { handleCommentCancel(): void {
this.setState({ this.setState({
showCommentLayout: false, show: {
...this.state.show,
layout: {
...this.state.show.layout,
comment: false,
},
},
});
}
handleReminderCancel(): void {
this.setState({
show: {
...this.state.show,
layout: {
...this.state.show.layout,
reminder: false,
},
},
}); });
} }
handleRetrieveCancel(): void { handleRetrieveCancel(): void {
this.setState({ this.setState({
showRetrieveModal: false, show: {
...this.state.show,
modal: {
...this.state.show.modal,
retrieve: false,
},
},
}); });
} }
handleStatusCancel(): void { handleStatusCancel(): void {
this.setState({ this.setState({
showStatusSheet: false, show: {
...this.state.show,
actionSheet: {
...this.state.show.actionSheet,
status: false,
},
},
}); });
} }
handlePickCancel(): void { handlePickCancel(): void {
this.setState({ this.setState({
showPickModal: false, show: {
...this.state.show,
modal: {
...this.state.show.modal,
pick: false,
},
},
}); });
} }
handleOreoConfirm(): void { handleOreoConfirm(): void {
this.setState({ this.setState({
isOreoDisable: true, isDisable: {
showOreoModal: false, ...this.state.isDisable,
oreo: true,
},
show: {
...this.state.show,
modal: {
...this.state.show.modal,
oreo: false,
},
},
}); });
addToOreo(this); addToOreo(this);
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isOreoDisable: false, isDisable: {
...this.state.isDisable,
oreo: false,
},
}); });
}, submitInterval); }, submitInterval);
return; return;
@ -162,13 +292,25 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
handleRetrieveConfirm(): void { handleRetrieveConfirm(): void {
this.setState({ this.setState({
isRetrieveDisable: true, isDisable: {
showRetrieveModal: false, ...this.state.isDisable,
retrieve: true,
},
show: {
...this.state.show,
modal: {
...this.state.show.modal,
retrieve: false,
},
},
}); });
retrieve(this); retrieve(this);
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isRetrieveDisable: false, isDisable: {
...this.state.isDisable,
retrieve: false,
},
}); });
}, submitInterval); }, submitInterval);
return; return;
@ -176,64 +318,159 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
handlePickConfirm(): void { handlePickConfirm(): void {
this.setState({ this.setState({
isPickDisable: true, isDisable: {
showPickModal: false, ...this.state.isDisable,
pick: true,
},
show: {
...this.state.show,
modal: {
...this.state.show.modal,
pick: false,
},
},
}); });
pickTicket(this); pickTicket(this);
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isPickDisable: false, isDisable: {
...this.state.isDisable,
pick: false,
},
}); });
}, submitInterval); }, submitInterval);
return; return;
} }
handleStatusChange(status: number): void { handleStatusChange(status: number): void {
if (status >= 3 && status <= 7) {
this.setState({ this.setState({
showStatusSheet: false, isDisable: {
isStatusDisable: true, ...this.state.isDisable,
status: true,
},
show: {
...this.state.show,
actionSheet: {
...this.state.show.actionSheet,
status: false,
},
layout: {
...this.state.show.layout,
reminder: true,
},
},
// eslint-disable-next-line react/no-unused-state
statusToBe: status,
});
} else {
this.setState({
isDisable: {
...this.state.isDisable,
status: true,
},
show: {
...this.state.show,
actionSheet: {
...this.state.show.actionSheet,
status: false,
},
},
// eslint-disable-next-line react/no-unused-state
statusToBe: status,
}); });
changeStatus(this, status); changeStatus(this, status);
}
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isStatusDisable: false, isDisable: {
...this.state.isDisable,
status: false,
},
}); });
}, submitInterval); }, submitInterval);
return; return;
} }
handleCommentChange(comment: string) { setFloatLayout(show: boolean) {
this.setState({ this.setState({
comment: comment, show: {
...this.state.show,
layout: {
...this.state.show.layout,
comment: show,
},
},
}); });
return comment;
} }
onCommentSubmit() { handleReminderChange(reminderList: Array<number>) {
this.setState({ this.setState({
isCommentDisable: true, reminderList: reminderList,
showCommentLayout: false, });
return reminderList;
}
onReminderSubmit() {
if (
this.state.reminderList.includes(1) &&
this.state.reminderList.includes(3)
) {
this.setState({
isDisable: {
...this.state.isDisable,
reminder: true,
},
show: {
...this.state.show,
layout: {
...this.state.show.layout,
reminder: false,
},
},
});
changeStatus(this, this.state.statusToBe);
} else {
this.setState({
isDisable: {
...this.state.isDisable,
reminder: true,
},
}); });
if (this.state.comment == '') {
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.blank, message: pt.get().ticketDetail.reminder.error,
type: 'error', type: 'error',
}); });
setTimeout(() => {
this.setState({
isCommentDisable: false,
});
}, submitInterval);
return;
} }
submitComment(this);
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isCommentDisable: false, isDisable: {
...this.state.isDisable,
reminder: false,
},
}); });
}, submitInterval); }, submitInterval);
} }
reminderOption = [
{
value: 0,
label: pt.get().ticketDetail.reminder.r0,
},
{
value: 1,
label: pt.get().ticketDetail.reminder.r1,
},
{
value: 2,
label: pt.get().ticketDetail.reminder.r2,
},
{
value: 3,
label: pt.get().ticketDetail.reminder.r3,
},
];
render(): ReactNode { render(): ReactNode {
const middleButton = this.state.isMember ? ( const middleButton = this.state.isMember ? (
<View> <View>
@ -246,14 +483,14 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }} style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
> >
<AtButton <AtButton
loading={this.state.isPickLoading} loading={this.state.isLoading.pick}
disabled={ disabled={
this.state.isPickDisable || this.state.isPickDisable_main this.state.isDisable.pick || this.state.isDisable_main.pick
} }
type='secondary' type='secondary'
onClick={this.onPick.bind(this)} onClick={this.onPick.bind(this)}
> >
{pt.get().ticketDetail.pick} {pt.get().ticketDetail.button.pick}
</AtButton> </AtButton>
</View> </View>
<View <View
@ -261,14 +498,14 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }} style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
> >
<AtButton <AtButton
loading={this.state.isOreoLoading} loading={this.state.isLoading.oreo}
disabled={ disabled={
this.state.isOreoDisable || this.state.isOreoDisable_main this.state.isDisable.oreo || this.state.isDisable_main.oreo
} }
type='primary' type='primary'
onClick={this.onAddToOreo.bind(this)} onClick={this.onAddToOreo.bind(this)}
> >
{pt.get().ticketDetail.addToOreo} {pt.get().ticketDetail.button.addToOreo}
</AtButton> </AtButton>
</View> </View>
</View> </View>
@ -281,12 +518,12 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }} style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
> >
<AtButton <AtButton
loading={this.state.isStatusLoading} loading={this.state.isLoading.status}
disabled={this.state.isStatusDisable} disabled={this.state.isDisable.status}
type='primary' type='primary'
onClick={this.onChangeStatus.bind(this)} onClick={this.onChangeStatus.bind(this)}
> >
{pt.get().ticketDetail.status.button} {pt.get().ticketDetail.button.status}
</AtButton> </AtButton>
</View> </View>
<View <View
@ -295,13 +532,14 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
> >
<AtButton <AtButton
disabled={ disabled={
this.state.isCommentDisable || this.state.isCommentDisable_main this.state.isDisable.comment ||
this.state.isDisable_main.comment
} }
loading={this.state.isCommentLoading} loading={this.state.isLoading.comment}
type='secondary' type='secondary'
onClick={this.onAddComment.bind(this)} onClick={this.onAddComment.bind(this)}
> >
{pt.get().ticketDetail.addNote} {pt.get().ticketDetail.button.addNote}
</AtButton> </AtButton>
</View> </View>
</View> </View>
@ -316,14 +554,15 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }} style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
> >
<AtButton <AtButton
loading={this.state.isRetrieveLoading} loading={this.state.isLoading.retrieve}
disabled={ disabled={
this.state.isRetrieveDisable || this.state.isRetrieveDisable_main this.state.isDisable.retrieve ||
this.state.isDisable_main.retrieve
} }
type='primary' type='primary'
onClick={this.onRetrieved.bind(this)} onClick={this.onRetrieved.bind(this)}
> >
{pt.get().ticketDetail.tookAway} {pt.get().ticketDetail.button.tookAway}
</AtButton> </AtButton>
</View> </View>
<View <View
@ -332,18 +571,38 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
> >
<AtButton <AtButton
disabled={ disabled={
this.state.isCommentDisable || this.state.isCommentDisable_main this.state.isDisable.comment || this.state.isDisable_main.comment
} }
loading={this.state.isCommentLoading} loading={this.state.isLoading.comment}
type='secondary' type='secondary'
onClick={this.onAddComment.bind(this)} onClick={this.onAddComment.bind(this)}
> >
{pt.get().ticketDetail.addNote} {pt.get().ticketDetail.button.addNote}
</AtButton> </AtButton>
</View> </View>
</View> </View>
); );
const actionSheetItemList: Array<StatusStr> = [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
];
const sheetItemsRenderer = actionSheetItemList.map((item, idx) => (
<AtActionSheetItem
key={idx}
onClick={this.handleStatusChange.bind(this, idx)}
>
{pt.get().ticketDetail.statusModifyMessage.get(item)}
</AtActionSheetItem>
));
const isInfoShow = { const isInfoShow = {
device: true, device: true,
createdTime: true, createdTime: true,
@ -352,13 +611,14 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
current: true, current: true,
notelist: true, notelist: true,
showAllNotes: true, showAllNotes: true,
pic: true,
}; };
return ( return (
<View> <View>
<AtMessage /> <AtMessage />
<AtModal <AtModal
isOpened={this.state.showOreoModal} isOpened={this.state.show.modal.oreo}
title={pt.get().modal.addToOreo.title} title={pt.get().modal.addToOreo.title}
cancelText={pt.get().modal.cancel} cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm} confirmText={pt.get().modal.confirm}
@ -367,7 +627,7 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
content={pt.get().modal.addToOreo.content} content={pt.get().modal.addToOreo.content}
/> />
<AtModal <AtModal
isOpened={this.state.showRetrieveModal} isOpened={this.state.show.modal.retrieve}
title={pt.get().modal.retrieve.title} title={pt.get().modal.retrieve.title}
cancelText={pt.get().modal.cancel} cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm} confirmText={pt.get().modal.confirm}
@ -376,7 +636,7 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
content={pt.get().modal.retrieve.content} content={pt.get().modal.retrieve.content}
/> />
<AtModal <AtModal
isOpened={this.state.showPickModal} isOpened={this.state.show.modal.pick}
title={pt.get().modal.pick.title} title={pt.get().modal.pick.title}
cancelText={pt.get().modal.cancel} cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm} confirmText={pt.get().modal.confirm}
@ -385,60 +645,53 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
content={pt.get().modal.pick.content} content={pt.get().modal.pick.content}
/> />
<AtFloatLayout <AtFloatLayout
isOpened={this.state.showCommentLayout} isOpened={this.state.show.layout.comment}
title={pt.get().ticketDetail.comment.title} title={pt.get().ticketDetail.comment.title}
onClose={this.handleCommentCancel.bind(this)} onClose={this.handleCommentCancel.bind(this)}
> >
<AtForm onSubmit={this.onCommentSubmit.bind(this)}> <Comment
<AtTextarea setFloatLayout={this.setFloatLayout.bind(this)}
value={this.state.comment} id={this.state.id}
onChange={this.handleCommentChange.bind(this)} didMount={this.state.show.layout.comment}
maxLength={200}
height='400rpx'
placeholder={pt.get().ticketDetail.comment.placeholder}
/> />
<AtButton formType='submit' type='primary'> </AtFloatLayout>
<AtFloatLayout
isOpened={this.state.show.layout.reminder}
title={pt.get().ticketDetail.reminder.title}
onClose={this.handleReminderCancel.bind(this)}
>
<AtForm onSubmit={this.onReminderSubmit.bind(this)}>
<AtCheckbox
options={this.reminderOption}
selectedList={this.state.reminderList}
onChange={this.handleReminderChange.bind(this)}
/>
<AtButton
loading={this.state.isLoading.reminder}
formType='submit'
type='primary'
disabled={this.state.isDisable.reminder}
>
{pt.get().button.buttonText.submit} {pt.get().button.buttonText.submit}
</AtButton> </AtButton>
</AtForm> </AtForm>
</AtFloatLayout> </AtFloatLayout>
<AtActionSheet <AtActionSheet
isOpened={this.state.showStatusSheet} isOpened={this.state.show.actionSheet.status}
cancelText={pt.get().ticketDetail.status.cancel} cancelText={pt.get().ticketDetail.status.cancel}
title={pt.get().ticketDetail.status.title} title={pt.get().ticketDetail.status.title}
onCancel={this.handleStatusCancel.bind(this)} onCancel={this.handleStatusCancel.bind(this)}
onClose={this.handleStatusCancel.bind(this)} onClose={this.handleStatusCancel.bind(this)}
> >
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 0)}> {sheetItemsRenderer}
{pt.get().ticketDetail.status.status0}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 1)}>
{pt.get().ticketDetail.status.status1}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 2)}>
{pt.get().ticketDetail.status.status2}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 3)}>
{pt.get().ticketDetail.status.status3}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 4)}>
{pt.get().ticketDetail.status.status4}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 5)}>
{pt.get().ticketDetail.status.status5}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 6)}>
{pt.get().ticketDetail.status.status6}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 7)}>
{pt.get().ticketDetail.status.status7}
</AtActionSheetItem>
</AtActionSheet> </AtActionSheet>
{!this.state.isLoading.framework && (
<DetailFramework <DetailFramework
middleButton={middleButton} middleButton={middleButton}
id={this.state.id} id={this.state.id}
isInfoShow={isInfoShow} isInfoShow={isInfoShow}
/> />
)}
<PageFooter /> <PageFooter />
</View> </View>
); );

View File

@ -16,9 +16,10 @@ export class TicketNote {
avatar: string; avatar: string;
id: number; id: number;
op: string; op: string;
type: 0 | 1 | 2; type: 0 | 1 | 2 | 3;
content: string; content: string;
createdTime: moment.Moment; createdTime: moment.Moment;
pic: string[];
} }
export class ShowElements { export class ShowElements {
@ -30,4 +31,4 @@ export class ShowElements {
notelist: JSX.Element; notelist: JSX.Element;
} }
export type StatusStr = '1' | '2' | '3' | '4' | '5'; export type StatusStr = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7';

View File

@ -95,6 +95,7 @@ export default class TicketListPage extends Component<{}, TicketListState> {
<AtList>{fixListRenderer}</AtList> <AtList>{fixListRenderer}</AtList>
<View style={{ marginTop: '40rpx' }}> <View style={{ marginTop: '40rpx' }}>
<AtPagination <AtPagination
icon
total={this.state.totalPage} total={this.state.totalPage}
pageSize={this.state.pageSize} pageSize={this.state.pageSize}
current={this.state.currentPage} current={this.state.currentPage}

View File

@ -6,31 +6,33 @@ import tick from '@/assets/icons/MainPage/tick.svg';
import cross from '@/assets/icons/MainPage/cross.svg'; import cross from '@/assets/icons/MainPage/cross.svg';
import clock from '@/assets/icons/MainPage/offduty.svg'; import clock from '@/assets/icons/MainPage/offduty.svg';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import moment from 'moment';
export class DutyData { export class DutyData {
constructor() { constructor() {
this.isInDuty = false; this.isInDuty = false;
this.inDutyCnt = 3; this.inDutyCnt = 3;
this.currentDuty = '2'; this.currentDuty = '1';
this.otherDutyTime = '9:30-11:30'; this.otherDutyStart = '2024-03-07T13:30:48.523303';
this.offDutyReason = '学园维修'; this.otherDutyEnd = '2024-03-07T16:00:48.523303';
this.dutyRecoverTime = '下周一'; this.dutyRecoverTime = '1330';
this.place = '东三-204'; this.place = '东三-204';
} }
isInDuty: boolean; isInDuty: boolean;
inDutyCnt?: number; inDutyCnt: number;
currentDuty?: 'off' | '1' | '2' | '3' | 'others'; currentDuty: 'off' | '0' | '1' | '2' | '3' | 'others';
otherDutyTime?: string; otherDutyStart: string;
offDutyReason?: string; otherDutyEnd: string;
dutyRecoverTime?: string; offDutyReason: string;
dutyRecoverTime: string;
place: string; place: string;
} }
class Card extends Component { class Card extends Component {
props = { props = {
isInDuty: false, isInDuty: false,
place: '东三-204', place: pt.get().common.place,
}; };
render(): ReactNode { render(): ReactNode {
const inDuty = this.props.isInDuty; const inDuty = this.props.isInDuty;
@ -87,8 +89,18 @@ export class DutyInfo extends Component {
<Card isInDuty={data.isInDuty} place={data.place} /> <Card isInDuty={data.isInDuty} place={data.place} />
<AtTimeline <AtTimeline
items={[ items={[
{ title: od.reason(data.offDutyReason as string) }, {
{ title: od.recoverTime(data.dutyRecoverTime as string) }, title:
data.currentDuty == '0'
? od.reason(pt.get().common.offDutyReason)
: od.reason(data.offDutyReason as string),
},
{
title:
data.currentDuty == '0'
? od.recoverTime(pt.get().common.dutyRecoverTime)
: od.recoverTime(data.dutyRecoverTime as string),
},
]} ]}
/> />
</View> </View>
@ -106,10 +118,19 @@ export class DutyInfo extends Component {
{ {
title: title:
data.currentDuty == 'others' data.currentDuty == 'others'
? id.currentDutyText('others') + data.otherDutyTime ? id.currentDutyText('others') +
moment(data.otherDutyStart).format('H:mm') +
' - ' +
moment(data.otherDutyEnd).format('H:mm')
: id.currentDutyText(data.currentDuty || 'off'), : id.currentDutyText(data.currentDuty || 'off'),
}, },
{ title: id.inDutyCnt(data.inDutyCnt as number) }, {
title: id.inDutyCnt(
data.inDutyCnt === 0
? pt.get().common.zeroMemberOnDuty
: data.inDutyCnt.toString(),
),
},
]} ]}
/> />
</View> </View>

View File

@ -1,35 +1,57 @@
import React from 'react'; import React from 'react';
import { View, Image } from '@tarojs/components'; import { View, Image } from '@tarojs/components';
import { AtButton } from 'taro-ui';
import pt from '@/plain-text'; import pt from '@/plain-text';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import Taro from '@tarojs/taro';
const logo = 'https://wiki.zjueva.net/images/evalogo_hd.png'; const logo = 'https://wiki.zjueva.net/images/evalogo_hd.png';
export default class TitleCard extends React.Component { export default class TitleCard extends React.Component {
onAskLeave() {
Taro.redirectTo({
url: '/pages/AskLeave/AskLeave',
});
}
render(): React.ReactNode { render(): React.ReactNode {
const mainPage = pt.get().mainPage; const mainPage = pt.get().mainPage;
const memberPage = pt.get().memberPage; const memberPage = pt.get().memberPage;
return ( return (
<View className='at-row at-row__align--center'> <View className='at-row at-row__align--center at-row__justify--start'>
<View className='at-col at-col-1 at-col--auto'> <View className='at-col at-col-1 at-col--auto'>
<Image <Image
style='width: 100rpx; height: 100rpx; margin-left: 30rpx;' style='width: 100rpx; height: 100rpx; margin-left: 30rpx; border-radius: 50rpx'
src={wechatUser.getAccess() ? wechatUser.getInfo().avatar : logo} src={wechatUser.getAccess() ? wechatUser.getInfo().avatar : logo}
mode='aspectFit' mode='aspectFit'
/> />
</View> </View>
<View className='page-title'> <View
className={
wechatUser.getAccess()
? 'at-col page-title at-col-1 at-col--auto'
: 'at-col page-title at-col-10 at-col--wrap'
}
>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}> <View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{wechatUser.getAccess() {wechatUser.getAccess()
? memberPage.mainTitleLine + wechatUser.getInfo().name ? memberPage.titleLine.main.index + wechatUser.getInfo().name
: mainPage.mainTitleLine} : mainPage.titleLine.main}
</View> </View>
<View className='at-article__h2'> <View className='at-article__h2'>
{wechatUser.getAccess() {wechatUser.getAccess()
? memberPage.subTitleLine ? memberPage.titleLine.sub.index
: mainPage.subTitleLine} : mainPage.titleLine.sub}
</View> </View>
</View> </View>
{wechatUser.getAccess() ? (
<View className='at-col at-col-1 at-col--auto'>
<AtButton type='secondary' onClick={this.onAskLeave}>
{pt.get().mainPage.askLeave}
</AtButton>
</View>
) : (
<View></View>
)}
</View> </View>
); );
} }

View File

@ -3,7 +3,6 @@ import { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import { import {
AtCard, AtCard,
AtAccordion,
AtInputNumber, AtInputNumber,
AtButton, AtButton,
AtList, AtList,
@ -23,6 +22,7 @@ import { getMemberDutyInfo } from '@/service/memberDutyInfo';
import { getUncompletedTicketList } from '@/service/uncompletedTicket'; import { getUncompletedTicketList } from '@/service/uncompletedTicket';
import { changeDutyCnt } from '@/service/changeDutyCount'; import { changeDutyCnt } from '@/service/changeDutyCount';
import { TicketListItem } from '@/components/TicketListItem/TicketListItem'; import { TicketListItem } from '@/components/TicketListItem/TicketListItem';
import { ExpandItem } from '@/components/ExpandItem/ExpandItem';
import './index.scss'; import './index.scss';
import TitleCard from './TitleCard'; import TitleCard from './TitleCard';
import { DutyInfo, DutyData } from './DutyInfo'; import { DutyInfo, DutyData } from './DutyInfo';
@ -47,39 +47,10 @@ function mainPageCard(c: CardContent): JSX.Element {
); );
} }
class ExpandItem extends Component {
state = {
open: false,
};
props = {
title: '',
content: <View></View>,
};
handleClick(value: boolean) {
this.setState({ open: value });
}
render(): ReactNode {
return (
<View>
<AtAccordion
open={this.state.open}
onClick={this.handleClick.bind(this)}
title={this.props.title}
>
{this.props.content}
</AtAccordion>
</View>
);
}
}
interface MainPageState { interface MainPageState {
fixList: Array<TicketListItem>; fixList: Array<TicketListItem>;
rs: RequestState; rs: RequestState;
dutyData: DutyData; dutyData: DutyData;
inDutyCnt: number;
dutyInfoCard: CardContent; dutyInfoCard: CardContent;
stepInfoCard: CardContent; stepInfoCard: CardContent;
tipsInfoCard: CardContent; tipsInfoCard: CardContent;
@ -90,7 +61,6 @@ interface MainPageState {
export default class MainPage extends Component<{}, MainPageState> { export default class MainPage extends Component<{}, MainPageState> {
state = { state = {
dutyData: new DutyData(), dutyData: new DutyData(),
inDutyCnt: 0,
dutyInfoCard: { dutyInfoCard: {
title: '', title: '',
note: '', note: '',
@ -119,7 +89,6 @@ export default class MainPage extends Component<{}, MainPageState> {
const ptPage = wechatUser.getAccess() ? 'memberPage' : 'mainPage'; const ptPage = wechatUser.getAccess() ? 'memberPage' : 'mainPage';
this.setState({ this.setState({
dutyData: new DutyData(), dutyData: new DutyData(),
inDutyCnt: 0,
dutyInfoCard: { dutyInfoCard: {
title: pt.get()[ptPage].cardTitle.dutyInfo, title: pt.get()[ptPage].cardTitle.dutyInfo,
note: pt.get()[ptPage].cardTips.dutyInfo, note: pt.get()[ptPage].cardTips.dutyInfo,
@ -158,7 +127,10 @@ export default class MainPage extends Component<{}, MainPageState> {
handleCnt(inDutyCnt: number) { handleCnt(inDutyCnt: number) {
this.setState({ this.setState({
dutyData: {
...this.state.dutyData,
inDutyCnt: inDutyCnt, inDutyCnt: inDutyCnt,
},
}); });
return inDutyCnt; return inDutyCnt;
} }
@ -181,6 +153,12 @@ export default class MainPage extends Component<{}, MainPageState> {
}); });
} }
conclusionPage() {
Taro.navigateTo({
url: '/pages/Conclusion/Conclusion',
});
}
render(): ReactNode { render(): ReactNode {
const mainPage = pt.get().mainPage; const mainPage = pt.get().mainPage;
const memberPage = pt.get().memberPage; const memberPage = pt.get().memberPage;
@ -213,6 +191,7 @@ export default class MainPage extends Component<{}, MainPageState> {
<ExpandItem <ExpandItem
title={memberPage.expandTitle.admin} title={memberPage.expandTitle.admin}
content={ content={
<View style={{ marginBottom: '40rpx' }}>
<View <View
style={{ style={{
display: 'flex', display: 'flex',
@ -238,7 +217,7 @@ export default class MainPage extends Component<{}, MainPageState> {
min={0} min={0}
max={10} max={10}
step={1} step={1}
value={this.state.inDutyCnt} value={this.state.dutyData.inDutyCnt}
onChange={this.handleCnt.bind(this)} onChange={this.handleCnt.bind(this)}
/> />
</View> </View>
@ -254,6 +233,12 @@ export default class MainPage extends Component<{}, MainPageState> {
</AtButton> </AtButton>
</View> </View>
</View> </View>
<View>
<AtButton type='primary' onClick={this.conclusionPage}>
{pt.get().button.indexText.conclusion}
</AtButton>
</View>
</View>
} }
/> />
) : ( ) : (
@ -265,12 +250,20 @@ export default class MainPage extends Component<{}, MainPageState> {
/> />
</View> </View>
{wechatUser.getAccess() ? ( {wechatUser.getAccess() ? (
<View> <View style={{ marginTop: '40rpx' }}>
<View
className='at-article__h3'
style={{ marginBottom: '20rpx', fontWeight: 'bold' }}
>
{(this.state.fixList.length === 0
? memberPage.ticketList.nohint
: '') + memberPage.ticketList.hint}
</View>
<AtList>{fixListRenderer}</AtList> <AtList>{fixListRenderer}</AtList>
<AtList> <AtList>
<AtListItem <AtListItem
title={pt.get().mainPage.ticketList.title} title={pt.get().memberPage.ticketList.title}
note={pt.get().mainPage.ticketList.note} note={pt.get().memberPage.ticketList.note}
arrow='right' arrow='right'
thumb={clockIcon} thumb={clockIcon}
onClick={this.ticketListPage} onClick={this.ticketListPage}

View File

@ -184,11 +184,18 @@ export default class RepairPage extends Component<{}, RepairPageState> {
} }
render(): ReactNode { render(): ReactNode {
const ticketsRenderer = const hasContinuingticket = this.state.currentTicketsIdName.length !== 0;
this.state.currentTicketsIdName.length !== 0 ? ( const ticketsRenderer = hasContinuingticket ? (
this.state.currentTicketsIdName.map((pair, idx) => ( <View>
<View
className='at-article__h3'
style={{ marginBottom: '20rpx', fontWeight: 'bold' }}
>
{pt.get().repairPage.currentTicket.hint}
</View>
{this.state.currentTicketsIdName.map((pair, idx) => (
<View key={idx} style={{ marginBottom: '20rpx' }}>
<AtCard <AtCard
key={idx}
title={pair.values().next().value} //pair.keys().next().value == ticket['device'] + ' ' + ticket['deviceModel'] title={pair.values().next().value} //pair.keys().next().value == ticket['device'] + ' ' + ticket['deviceModel']
extra={pt.get().repairPage.currentTicket.extra} extra={pt.get().repairPage.currentTicket.extra}
onClick={() => { onClick={() => {
@ -210,9 +217,16 @@ export default class RepairPage extends Component<{}, RepairPageState> {
middleButton={middleButton} middleButton={middleButton}
/> />
</AtCard> </AtCard>
)) </View>
))}
</View>
) : ( ) : (
<View></View> <View
className='at-article__h3'
style={{ marginBottom: '20rpx', fontWeight: 'bold' }}
>
{pt.get().repairPage.currentTicket.nohint}
</View>
); );
return ( return (
<View style={{ width: '94%', marginLeft: '3%' }}> <View style={{ width: '94%', marginLeft: '3%' }}>

View File

@ -50,10 +50,10 @@ export default class UserMemberPage extends Component {
<AtMessage /> <AtMessage />
<View className='page-title' style={{ marginBottom: '40rpx' }}> <View className='page-title' style={{ marginBottom: '40rpx' }}>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}> <View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{pt.get().memberPage.loginMainTitleLine} {pt.get().memberPage.titleLine.main.login}
</View> </View>
<View className='at-article__h2'> <View className='at-article__h2'>
{pt.get().memberPage.loginSubTitleLine} {pt.get().memberPage.titleLine.sub.login}
</View> </View>
</View> </View>
<AtButton <AtButton
@ -70,10 +70,10 @@ export default class UserMemberPage extends Component {
<AtMessage /> <AtMessage />
<View className='page-title' style={{ marginBottom: '40rpx' }}> <View className='page-title' style={{ marginBottom: '40rpx' }}>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}> <View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{pt.get().memberPage.logoutMainTitleLine} {pt.get().memberPage.titleLine.main.logout}
</View> </View>
<View className='at-article__h2'> <View className='at-article__h2'>
{pt.get().memberPage.logoutSubTitleLine} {pt.get().memberPage.titleLine.sub.logout}
</View> </View>
</View> </View>
<AtButton type='primary' onClick={this.onLogout.bind(this)}> <AtButton type='primary' onClick={this.onLogout.bind(this)}>

View File

@ -64,6 +64,7 @@ export default class ReportPage extends Component {
<AtMessage /> <AtMessage />
<AtTextarea <AtTextarea
value={this.state.report} value={this.state.report}
height={400}
onChange={this.handleChange.bind(this)} onChange={this.handleChange.bind(this)}
maxLength={200} maxLength={200}
placeholder={pt.get().reportPage.placeHolderText} placeholder={pt.get().reportPage.placeHolderText}
@ -74,7 +75,6 @@ export default class ReportPage extends Component {
style={{ style={{
marginTop: '30rpx', marginTop: '30rpx',
marginRight: '10rpx', marginRight: '10rpx',
marginLeft: '10rpx',
width: '50%', width: '50%',
}} }}
> >
@ -86,7 +86,6 @@ export default class ReportPage extends Component {
className='at-col' className='at-col'
style={{ style={{
marginTop: '30rpx', marginTop: '30rpx',
marginRight: '10rpx',
marginLeft: '10rpx', marginLeft: '10rpx',
width: '50%', width: '50%',
}} }}

View File

@ -43,9 +43,9 @@ export default class UserPage extends Component {
if (this.state.clicks < 3) { if (this.state.clicks < 3) {
this.setState({ this.setState({
toastText: toastText:
pt.get().userPage.memberEntry.front + pt.get().userPage.memberEntry.prefix +
(this.state.clicks + 1).toString() + // React State's feature (this.state.clicks + 1).toString() + // React State's feature
pt.get().userPage.memberEntry.behind, pt.get().userPage.memberEntry.affix,
isToastOpen: true, isToastOpen: true,
}); });
if (this.state.clicks == 0) { if (this.state.clicks == 0) {
@ -123,7 +123,7 @@ export default class UserPage extends Component {
className='at-row at-row__justify--center at-row__align--center' className='at-row at-row__justify--center at-row__align--center'
style='height:120rpx;color:#696969;' style='height:120rpx;color:#696969;'
> >
<Text style={{ fontSize: '32rpx' }}> EVA Eta v1.0.0</Text> <Text style={{ fontSize: '32rpx' }}> EVA Eta v1.1.0</Text>
</View> </View>
<AtList> <AtList>
<AtListItem <AtListItem

View File

@ -1,14 +1,21 @@
export interface NotFoundText { export interface NotFoundText {
titleZhCn: string; title: {
titleEnUs: string; ZhCn: string;
descZhCn: string; EnUs: string;
descEnUs: string; };
desc: {
ZhCn: string;
EnUs: string;
};
} }
export const notFound: NotFoundText = { export const notFound: NotFoundText = {
titleZhCn: '啊哦...请求出错了...', title: {
descZhCn: '请确保处于校网环境后,点击右上角 "...-重新进入小程序"', ZhCn: '啊哦...请求出错了...',
titleEnUs: 'Oops...Network Error...', EnUs: '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"!', desc: {
ZhCn: '请确保处于校网环境后,点击右上角 "...-重新进入小程序"',
EnUs: 'Please make sure you\'re in ZJU\'s school network environment and then click on the top right corner "... - re-enter the applet"!',
},
}; };

View File

@ -0,0 +1,60 @@
export interface AskLeaveText {
modal: {
title: string;
content: string;
};
shift: {
title: string;
week: string[];
shift: string[];
};
reason: {
title: string;
placeHolder: string;
};
substitute: {
title: string;
placeHolder: string;
};
}
export const askLeaveZhCn: AskLeaveText = {
modal: {
title: '确认无代班?',
content: '值班人数少于 4 时须填写代班人员。请假记录将会被上传保存!',
},
shift: {
title: '值班时间',
week: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
shift: ['第一班', '第二班', '第三班'],
},
reason: {
title: '请假原因',
placeHolder: '请在此说明请假原因',
},
substitute: {
title: '替班人员',
placeHolder: '人数少于 4 时必填!',
},
};
export const askLeaveEnUs: AskLeaveText = {
modal: {
title: 'Confirm no substitute?',
content:
'Must have substitute if members are less than 4! The ticket will be uploaded and saved!',
},
shift: {
title: 'Duty time',
week: ['Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.', 'Sun.'],
shift: ['1st Shift', '2nd Shift', '3rd Shift'],
},
reason: {
title: 'Reason',
placeHolder: 'Leave your reason for leaving here',
},
substitute: {
title: 'Substitute',
placeHolder: 'Must have if members are less than 4!',
},
};

View File

@ -13,6 +13,10 @@ export interface ButtonText {
memberText: { memberText: {
auth: string; auth: string;
}; };
indexText: {
conclusion: string;
askLeave: string;
};
loginText: { loginText: {
success: string; success: string;
error: string; error: string;
@ -39,6 +43,10 @@ export const buttonZhCn: ButtonText = {
memberText: { memberText: {
auth: '协会统一身份认证登录', auth: '协会统一身份认证登录',
}, },
indexText: {
conclusion: '提交值班总结',
askLeave: '我要请假',
},
loginText: { loginText: {
success: '登录成功', success: '登录成功',
error: '登录失败', error: '登录失败',
@ -65,6 +73,10 @@ export const buttonEnUs: ButtonText = {
memberText: { memberText: {
auth: 'EVA Auth Login Entry', auth: 'EVA Auth Login Entry',
}, },
indexText: {
conclusion: 'Submit Duty Conclusion',
askLeave: 'Ask for Leave',
},
loginText: { loginText: {
success: 'Login Success', success: 'Login Success',
error: 'Login Failed', error: 'Login Failed',

View File

@ -0,0 +1,16 @@
export interface ConclusionText {
title: string;
placeHolder: string;
}
export const conclusionTextZhCn: ConclusionText = {
title: '值班总结',
placeHolder:
'请在此填写完整的值班情况,包括:几人请假;收到几台电脑;后续的处理情况;上一班交接的电脑情况;下一班对接的电脑情况;另外,请拍照记录值班桌整理情况',
};
export const conclusionTextEnUs: ConclusionText = {
title: 'Duty Conclusion',
placeHolder:
'Please fill in the complete duty situation here, including: how many people were on leave; how many computers were received; how the follow-up was handled; how the computers were handed over by the previous shift; how the computers were docked by the next shift; Also, please take photos to document the organization of the duty desk',
};

View File

@ -1,6 +1,10 @@
export interface MainPageText { export interface MainPageText {
mainTitleLine: string; askLeave: string;
subTitleLine: string; conclusion: string;
titleLine: {
main: string;
sub: string;
};
cardTitle: { cardTitle: {
dutyInfo: string; dutyInfo: string;
stepInfo: string; stepInfo: string;
@ -23,11 +27,6 @@ export interface MainPageText {
stepList: Array<{ title: string }>; stepList: Array<{ title: string }>;
tipsList: Array<{ title: string }>; tipsList: Array<{ title: string }>;
ticketList: {
title: string;
note: string;
};
dutyCard: { dutyCard: {
offDuty: { offDuty: {
title: string; title: string;
@ -36,15 +35,19 @@ export interface MainPageText {
}; };
inDuty: { inDuty: {
title: string; title: string;
currentDutyText: (c: 'off' | '1' | '2' | '3' | 'others') => string; currentDutyText: (c: 'off' | '0' | '1' | '2' | '3' | 'others') => string;
inDutyCnt: (n: number) => string; inDutyCnt: (n: string) => string;
}; };
}; };
} }
export const mainPageZhCn: MainPageText = { export const mainPageZhCn: MainPageText = {
mainTitleLine: '您好这里是E志者协会', askLeave: '我要请假',
subTitleLine: '维修请至【东三-204】实验室', conclusion: '提交值班总结',
titleLine: {
main: '您好这里是E志者协会',
sub: '维修请至【东三-204】实验室',
},
cardTitle: { cardTitle: {
dutyInfo: '值班情况', dutyInfo: '值班情况',
stepInfo: '维修步骤', stepInfo: '维修步骤',
@ -76,10 +79,6 @@ export const mainPageZhCn: MainPageText = {
{ title: '204 也是实验室,请勿在内饮食~' }, { title: '204 也是实验室,请勿在内饮食~' },
{ title: '我们是志愿服务,不收取任何礼物哦~' }, { title: '我们是志愿服务,不收取任何礼物哦~' },
], ],
ticketList: {
title: '预填写工单列表',
note: '在这里查看所有的预填写工单!',
},
dutyCard: { dutyCard: {
offDuty: { offDuty: {
title: '未值班', title: '未值班',
@ -91,7 +90,9 @@ export const mainPageZhCn: MainPageText = {
currentDutyText: (c) => { currentDutyText: (c) => {
switch (c) { switch (c) {
case 'off': case 'off':
return '当前未值班'; return '暂停值班';
case '0':
return '休息中';
case '1': case '1':
return '第一班 13:30-16:00'; return '第一班 13:30-16:00';
case '2': case '2':
@ -108,8 +109,12 @@ export const mainPageZhCn: MainPageText = {
}; };
export const mainPageEnUs: MainPageText = { export const mainPageEnUs: MainPageText = {
mainTitleLine: 'Hi! This is EVA.', askLeave: 'Absence',
subTitleLine: 'For maintenance, please go to [204 Lab, E3 building]', conclusion: 'Submit Duty Conclusion',
titleLine: {
main: 'Hi! This is EVA.',
sub: 'For maintenance, please go to [204 Lab, E3 building]',
},
cardTitle: { cardTitle: {
dutyInfo: 'Duty Situation', dutyInfo: 'Duty Situation',
stepInfo: 'Maintenance Steps', stepInfo: 'Maintenance Steps',
@ -141,10 +146,6 @@ export const mainPageEnUs: MainPageText = {
{ title: '204 is also a laboratory. Do not eat inside.' }, { title: '204 is also a laboratory. Do not eat inside.' },
{ title: 'We are volunteers and do not take any gifts.' }, { 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: { dutyCard: {
offDuty: { offDuty: {
title: 'Off Duty', title: 'Off Duty',
@ -156,7 +157,9 @@ export const mainPageEnUs: MainPageText = {
currentDutyText: (c) => { currentDutyText: (c) => {
switch (c) { switch (c) {
case 'off': case 'off':
return 'Currently not on duty'; return 'Duty paused';
case '0':
return 'Normal Shift';
case '1': case '1':
return '1st Shift 13:30-16:00'; return '1st Shift 13:30-16:00';
case '2': case '2':

View File

@ -1,10 +1,16 @@
export interface MemberPageText { export interface MemberPageText {
mainTitleLine: string; titleLine: {
subTitleLine: string; main: {
loginMainTitleLine: string; index: string;
loginSubTitleLine: string; login: string;
logoutMainTitleLine: string; logout: string;
logoutSubTitleLine: string; };
sub: {
index: string;
login: string;
logout: string;
};
};
cardTitle: { cardTitle: {
dutyInfo: string; dutyInfo: string;
stepInfo: string; stepInfo: string;
@ -22,9 +28,6 @@ export interface MemberPageText {
title: string; title: string;
placeholder: string; placeholder: string;
}; };
uncompletedTicket: {
extra: string;
};
dutyCard: { dutyCard: {
offDuty: { offDuty: {
title: string; title: string;
@ -54,22 +57,34 @@ export interface MemberPageText {
}; };
stepList: Array<{ title: string }>; stepList: Array<{ title: string }>;
tipsList: Array<{ title: string }>; tipsList: Array<{ title: string }>;
ticketList: {
nohint: string;
hint: string;
title: string;
note: string;
};
} }
export const memberPageZhCn: MemberPageText = { export const memberPageZhCn: MemberPageText = {
mainTitleLine: '您好,', titleLine: {
subTitleLine: '祝你满绩每一天', main: {
loginMainTitleLine: '协会成员登录入口', index: '您好,',
loginSubTitleLine: '请使用 EVA 统一身份认证,登录后点击下方按钮以扫描二维码', login: '协会成员登录入口',
logoutMainTitleLine: '协会成员登出', logout: '协会成员登出',
logoutSubTitleLine: '登出后须扫码重新登录!', },
sub: {
index: '祝你满绩每一天',
login: '请使用 EVA 统一身份认证,登录后点击下方按钮以扫描二维码',
logout: '登出后须扫码重新登录!',
},
},
cardTitle: { cardTitle: {
dutyInfo: '值班情况', dutyInfo: '值班情况',
stepInfo: '维修步骤', stepInfo: '维修步骤',
tipsInfo: '注意事项', tipsInfo: '注意事项',
}, },
dutyCount: { dutyCount: {
button: '更新值班人数', button: '更新',
text: '当前值班人数:', text: '当前值班人数:',
}, },
stuidText: { stuidText: {
@ -80,9 +95,6 @@ export const memberPageZhCn: MemberPageText = {
title: '密码', title: '密码',
placeholder: '与 EVA 统一身份认证一致', placeholder: '与 EVA 统一身份认证一致',
}, },
uncompletedTicket: {
extra: '详细信息',
},
dutyCard: { dutyCard: {
offDuty: { offDuty: {
title: '空闲', title: '空闲',
@ -135,23 +147,35 @@ export const memberPageZhCn: MemberPageText = {
{ title: '离开 204 前清点好维修物资!' }, { title: '离开 204 前清点好维修物资!' },
{ title: '螺丝上了吗?电源排线插了吗?' }, { title: '螺丝上了吗?电源排线插了吗?' },
], ],
ticketList: {
nohint: '暂无',
hint: '七日内未完成工单',
title: '预填写工单列表',
note: '在这里查看所有的预填写工单!',
},
}; };
export const memberPageEnUs: MemberPageText = { export const memberPageEnUs: MemberPageText = {
mainTitleLine: 'Hi! ', titleLine: {
subTitleLine: 'Have a great day!', main: {
loginMainTitleLine: 'EVA Member Entry', index: 'Hi! ',
loginSubTitleLine: login: 'EVA Member Entry',
logout: 'EVA Member Logout',
},
sub: {
index: 'Have a great day!',
login:
'Please use EVA Auth, log in and click the button below to scan the QR code', 'Please use EVA Auth, log in and click the button below to scan the QR code',
logoutMainTitleLine: 'EVA Member Logout', logout: 'After logging out, scan the code again to log back in!',
logoutSubTitleLine: 'After logging out, scan the code again to log back in!', },
},
cardTitle: { cardTitle: {
dutyInfo: 'Duty Situation', dutyInfo: 'Duty Situation',
stepInfo: 'Maintenance Steps', stepInfo: 'Maintenance Steps',
tipsInfo: 'Tips', tipsInfo: 'Tips',
}, },
dutyCount: { dutyCount: {
button: 'Update Duty Count', button: 'Update',
text: 'The duty count: ', text: 'The duty count: ',
}, },
stuidText: { stuidText: {
@ -162,9 +186,6 @@ export const memberPageEnUs: MemberPageText = {
title: 'Password', title: 'Password',
placeholder: 'Consistent with EVA Auth', placeholder: 'Consistent with EVA Auth',
}, },
uncompletedTicket: {
extra: 'Details',
},
dutyCard: { dutyCard: {
offDuty: { offDuty: {
title: 'Off Duty', title: 'Off Duty',
@ -221,4 +242,10 @@ export const memberPageEnUs: MemberPageText = {
{ title: '204 is a laboratory. Do not eat inside.' }, { title: '204 is a laboratory. Do not eat inside.' },
{ title: 'Are the screws on? Is the power cable plugged in?' }, { title: 'Are the screws on? Is the power cable plugged in?' },
], ],
ticketList: {
nohint: 'N/A ',
hint: 'Uncompleted tickets in 7 days',
title: 'Pre-filling ticket list',
note: 'Browse for all pre-filling tickets here!',
},
}; };

View File

@ -1,7 +1,10 @@
export interface NavBarTitle { export interface NavBarTitle {
notFound: string; notFound: string;
loading: string;
ticketDetail: string; ticketDetail: string;
ticketList: string; ticketList: string;
askLeave: string;
conclusion: string;
user: { user: {
myTicket: string; myTicket: string;
report: string; report: string;
@ -14,8 +17,11 @@ export interface NavBarTitle {
export const navBarTitleZhCn: NavBarTitle = { export const navBarTitleZhCn: NavBarTitle = {
notFound: '连接失败', notFound: '连接失败',
loading: '加载中',
ticketDetail: '工单详情', ticketDetail: '工单详情',
ticketList: '所有工单', ticketList: '所有工单',
askLeave: '请假单填写',
conclusion: '值班总结',
user: { user: {
myTicket: '我的工单', myTicket: '我的工单',
report: '意见反馈', report: '意见反馈',
@ -28,8 +34,11 @@ export const navBarTitleZhCn: NavBarTitle = {
export const navBarTitleEnUs: NavBarTitle = { export const navBarTitleEnUs: NavBarTitle = {
notFound: 'Failed', notFound: 'Failed',
loading: 'Loading',
ticketDetail: 'Ticket Detail', ticketDetail: 'Ticket Detail',
ticketList: 'All Tickets', ticketList: 'All Tickets',
askLeave: 'Ask for leave',
conclusion: 'Duty Conclusion',
user: { user: {
myTicket: 'My Tickets', myTicket: 'My Tickets',
report: 'Report', report: 'Report',

View File

@ -4,6 +4,8 @@ export interface RepairPageText {
title: string; title: string;
note: string; note: string;
extra: string; extra: string;
hint: string;
nohint: string;
}; };
typeText: { typeText: {
computer: string; computer: string;
@ -51,6 +53,8 @@ export const repairPageZhCn: RepairPageText = {
title: '', title: '',
note: '', note: '',
extra: '详细信息', extra: '详细信息',
hint: '我正在进行的工单',
nohint: '暂无进行中的工单',
}, },
typeText: { typeText: {
computer: '电脑', computer: '电脑',
@ -98,6 +102,8 @@ export const repairPageEnUs: RepairPageText = {
title: '', title: '',
note: '', note: '',
extra: 'Details', extra: 'Details',
hint: 'My continuing tickets',
nohint: 'No continuing tickets',
}, },
typeText: { typeText: {
computer: 'Computer', computer: 'Computer',

View File

@ -6,35 +6,43 @@ type StatusStr = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7';
export interface TicketDetailText { export interface TicketDetailText {
stepItems: Array<StepItem>; stepItems: Array<StepItem>;
createTicketMessage: string;
statusModifyPrefix: string;
statusModifyMessage: Map<StatusStr, string>; statusModifyMessage: Map<StatusStr, string>;
descTitle: string; desc: {
title: string;
};
divider: string; divider: string;
info: { info: {
title: string; title: string;
extra: string; extra: string;
}; };
button: {
tookAway: string; tookAway: string;
addToOreo: string; addToOreo: string;
addNote: string; addNote: string;
pick: string; pick: string;
status: string;
};
reminder: {
title: string;
error: string;
r0: string;
r1: string;
r2: string;
r3: string;
};
comment: { comment: {
title: string; title: string;
placeholder: string; placeholder: string;
picked: string;
createTicketMessage: string;
statusModifyPrefix: string;
uploadPic: {
title: string;
};
}; };
status: { status: {
button: string;
title: string; title: string;
cancel: string; cancel: string;
status0: string;
status1: string;
status2: string;
status3: string;
status4: string;
status5: string;
status6: string;
status7: string;
}; };
} }
@ -45,8 +53,6 @@ export const ticketDetailZhCn: TicketDetailText = {
{ title: '待取回' }, { title: '待取回' },
{ title: '工单完成' }, { title: '工单完成' },
], ],
createTicketMessage: '创建了维修',
statusModifyPrefix: '将维修状态改为:',
statusModifyMessage: new Map<StatusStr, string>([ statusModifyMessage: new Map<StatusStr, string>([
['0', '已创建/交接中'], ['0', '已创建/交接中'],
['1', '维修中'], ['1', '维修中'],
@ -57,32 +63,42 @@ export const ticketDetailZhCn: TicketDetailText = {
['6', '维修翻车待取回'], ['6', '维修翻车待取回'],
['7', '维修翻车已取回'], ['7', '维修翻车已取回'],
]), ]),
descTitle: '问题描述', desc: {
divider: '评论 / 状态', title: '问题描述',
},
info: { info: {
title: '机主姓名', title: '机主姓名',
extra: '联系方式', extra: '联系方式',
}, },
divider: '评论 / 状态',
button: {
tookAway: '我已取回', tookAway: '我已取回',
addToOreo: '加入 Oreo', addToOreo: '加入 Oreo',
addNote: '添加评论', addNote: '添加评论',
pick: '认领', pick: '认领',
status: '改变状态',
},
comment: { comment: {
title: '添加评论', title: '添加评论',
picked: '认领了维修',
placeholder: '可以在这里交流机器情况、维修进度、提出问题~', placeholder: '可以在这里交流机器情况、维修进度、提出问题~',
createTicketMessage: '创建了维修',
statusModifyPrefix: '将维修状态改为:',
uploadPic: {
title: '上传说明图片处',
},
},
reminder: {
title: '注意事项!',
error: '请重新确认机器状况!',
r0: '是否进行维修?',
r1: '螺丝是否装回?排线是否插好?',
r2: '维修后机器是否已正常运行?',
r3: '随机附件是否已经归还?',
}, },
status: { status: {
button: '改变工单状态',
title: '请选择要改变成为的状态', title: '请选择要改变成为的状态',
cancel: '取消', cancel: '取消',
status0: '已创建/交接中',
status1: '维修中',
status2: '劝退待取回',
status3: '劝退已取回',
status4: '维修成功待取回',
status5: '维修成功已取回',
status6: '维修翻车待取回',
status7: '维修翻车已取回',
}, },
}; };
@ -93,8 +109,6 @@ export const ticketDetailEnUs: TicketDetailText = {
{ title: 'Finished' }, { title: 'Finished' },
{ title: 'Retrieved' }, { title: 'Retrieved' },
], ],
createTicketMessage: 'Created ticket',
statusModifyPrefix: 'Modified repair status to: ',
statusModifyMessage: new Map<StatusStr, string>([ statusModifyMessage: new Map<StatusStr, string>([
['0', 'Created / Handovering'], ['0', 'Created / Handovering'],
['1', 'Repairing'], ['1', 'Repairing'],
@ -105,32 +119,42 @@ export const ticketDetailEnUs: TicketDetailText = {
['6', 'Pending Retrieval (Failed)'], ['6', 'Pending Retrieval (Failed)'],
['7', 'Retrieved (Failed)'], ['7', 'Retrieved (Failed)'],
]), ]),
descTitle: 'Description', desc: {
divider: 'Comment / Status', title: 'Description',
},
info: { info: {
title: 'Name', title: 'Name',
extra: 'Contact', extra: 'Contact',
}, },
divider: 'Comment / Status',
button: {
tookAway: 'Already retrieved', tookAway: 'Already retrieved',
addToOreo: 'Add to Oreo', addToOreo: 'Add to Oreo',
addNote: 'Comment', addNote: 'Comment',
pick: 'Pick', pick: 'Pick',
status: 'Change status',
},
comment: { comment: {
title: 'Add Comment', title: 'Add comment',
picked: 'Picked this ticket',
placeholder: placeholder:
'You can exchange information the device, the progress of repairs, and ask questions here.', 'You can exchange information the device, the progress of repairs, and ask questions here.',
createTicketMessage: 'Created ticket',
statusModifyPrefix: 'Modified repair status to: ',
uploadPic: {
title: 'Upload description images',
},
},
reminder: {
title: 'Reminder',
error: 'Please re-confirm the status of the device!',
r0: 'Is the maintenance performed?',
r1: 'Are the srews on? Is the power cable plugged in?',
r2: 'Did the device operate well after maintenance?',
r3: 'Are the attachments reverted?',
}, },
status: { status: {
button: 'Modify Status',
title: 'Please select the status you want to modify to', title: 'Please select the status you want to modify to',
cancel: 'Cancel', cancel: 'Cancel',
status0: 'Created / Handovering',
status1: 'Repairing',
status2: 'Pending Retrieval (Refused)',
status3: 'Retrieved (Refused)',
status4: 'Pending Retrieval (Finished)',
status5: 'Retrieved (Finished)',
status6: 'Pending Retrieval (Failed)',
status7: 'Retrieved (Failed)',
}, },
}; };

View File

@ -1,7 +1,7 @@
export interface UserPageText { export interface UserPageText {
memberEntry: { memberEntry: {
front: string; prefix: string;
behind: string; affix: string;
}; };
ticketColumn: { ticketColumn: {
title: string; title: string;
@ -27,8 +27,8 @@ export interface UserPageText {
export const userPageZhCn: UserPageText = { export const userPageZhCn: UserPageText = {
memberEntry: { memberEntry: {
front: '再点击 ', prefix: '再点击 ',
behind: ' 次以进入协会成员登录页面', affix: ' 次以进入协会成员登录页面',
}, },
ticketColumn: { ticketColumn: {
title: '我的工单', title: '我的工单',
@ -54,8 +54,8 @@ export const userPageZhCn: UserPageText = {
export const userPageEnUs: UserPageText = { export const userPageEnUs: UserPageText = {
memberEntry: { memberEntry: {
front: 'Click ', prefix: 'Click ',
behind: ' more times to enter member login page', affix: ' more times to enter member login page',
}, },
ticketColumn: { ticketColumn: {
title: 'My Tickets', title: 'My Tickets',

View File

@ -1,17 +1,33 @@
import { Moment } from 'moment'; import moment, { Moment } from 'moment';
const dutyStart = moment().format('YYYY-MM-DD').toString() + ' 13:30:00';
export interface CommonText { export interface CommonText {
createdAtText(time: Moment): string; createdAtText(time: Moment): string;
offDutyReason: string;
place: string;
dutyRecoverTime: string;
zeroMemberOnDuty: string;
} }
export const commonTextZhCn: CommonText = { export const commonTextZhCn: CommonText = {
createdAtText(time: Moment): string { createdAtText(time: Moment): string {
return '创建于 ' + time.format('YYYY-MM-DD HH:mm'); return '创建于 ' + time.format('YYYY-MM-DD HH:mm');
}, },
offDutyReason: '正常值班下班',
place: '204',
dutyRecoverTime: moment().isBefore(dutyStart) ? '今天 13:30' : '明天 13:30',
zeroMemberOnDuty: '待更新',
}; };
export const commonTextEnUs: CommonText = { export const commonTextEnUs: CommonText = {
createdAtText(time: Moment): string { createdAtText(time: Moment): string {
return 'Created at ' + time.format('YYYY-MM-DD HH:mm'); return 'Created at ' + time.format('YYYY-MM-DD HH:mm');
}, },
offDutyReason: 'Normal Shift',
place: 'E3-204',
dutyRecoverTime: moment().isBefore(dutyStart)
? '13:30 Today'
: '13:30 Tomorrow',
zeroMemberOnDuty: 'Wait for update',
}; };

View File

@ -25,6 +25,12 @@ import {
actIndicatorZhCn, actIndicatorZhCn,
} from './ActIndicator'; } from './ActIndicator';
import { NotFoundText, notFound } from './404'; import { NotFoundText, notFound } from './404';
import { AskLeaveText, askLeaveEnUs, askLeaveZhCn } from './AskLeave';
import {
ConclusionText,
conclusionTextEnUs,
conclusionTextZhCn,
} from './Conclusion';
interface TextRecord { interface TextRecord {
common: CommonText; common: CommonText;
@ -46,6 +52,8 @@ interface TextRecord {
toast: ToastText; toast: ToastText;
actIndicator: ActIndicatorText; actIndicator: ActIndicatorText;
notFound: NotFoundText; notFound: NotFoundText;
askLeave: AskLeaveText;
conclusion: ConclusionText;
} }
const textZhCn: TextRecord = { const textZhCn: TextRecord = {
@ -68,6 +76,8 @@ const textZhCn: TextRecord = {
toast: toastZhCn, toast: toastZhCn,
actIndicator: actIndicatorZhCn, actIndicator: actIndicatorZhCn,
notFound: notFound, notFound: notFound,
askLeave: askLeaveZhCn,
conclusion: conclusionTextZhCn,
}; };
const textEnUs: TextRecord = { const textEnUs: TextRecord = {
@ -90,6 +100,8 @@ const textEnUs: TextRecord = {
toast: toastEnUs, toast: toastEnUs,
actIndicator: actIndicatorEnUs, actIndicator: actIndicatorEnUs,
notFound: notFound, notFound: notFound,
askLeave: askLeaveEnUs,
conclusion: conclusionTextEnUs,
}; };
// type Lang = 'zh_CN' | 'en_US' | ...; // type Lang = 'zh_CN' | 'en_US' | ...;

View File

@ -6,7 +6,10 @@ import { getUrl } from '.';
export function addToOreo(that: TicketDetail) { export function addToOreo(that: TicketDetail) {
that.setState({ that.setState({
isOreoLoading: true, isLoading: {
...that.state.isLoading,
oreo: true,
},
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/addtooreo'), url: getUrl('/tickets/addtooreo'),
@ -19,7 +22,10 @@ export function addToOreo(that: TicketDetail) {
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isOreoLoading: false, isLoading: {
...that.state.isLoading,
oreo: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
@ -29,7 +35,10 @@ export function addToOreo(that: TicketDetail) {
.catch((err) => { .catch((err) => {
console.log(err.errMsg); console.log(err.errMsg);
that.setState({ that.setState({
isOreoLoading: false, isLoading: {
...that.state.isLoading,
oreo: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg, message: pt.get().button.submitText.error + err.errMsg,

View File

@ -0,0 +1,49 @@
import AskLeavePage from '@/pages/AskLeave/AskLeave';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
import { getUrl } from '.';
const reLaunchInterval = 1000;
export function askLeave(that: AskLeavePage) {
that.setState({
isLoading: true,
});
Taro.request({
url: getUrl('/member/askleave'),
method: 'POST',
data: {
token: wechatUser.getToken(),
week: (that.state.shift[0] + 1).toString(),
shift: (that.state.shift[1] + 1).toString(),
reason: that.state.reason,
substitute: that.state.substitute,
},
})
.then((res) => {
console.log(res.data);
that.setState({
isLoading: false,
});
Taro.atMessage({
message: pt.get().button.submitText.success,
type: 'success',
});
setTimeout(() => {
Taro.reLaunch({
url: '/pages/index/index',
});
}, reLaunchInterval);
})
.catch((err) => {
console.log(err.errMsg);
that.setState({
isLoading: false,
});
Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg,
type: 'error',
});
});
}

View File

@ -11,11 +11,11 @@ export function changeDutyCnt(that: MainPage) {
isLoading: true, isLoading: true,
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/addtooreo'), url: getUrl('/member/dutycnt'),
method: 'POST', method: 'POST',
data: { data: {
token: wechatUser.getToken(), token: wechatUser.getToken(),
dutyCnt: that.state.inDutyCnt, dutyCnt: that.state.dutyData.inDutyCnt,
}, },
}) })
.then((res) => { .then((res) => {

View File

@ -8,7 +8,10 @@ const reLaunchInterval = 1000;
export function changeStatus(that: TicketDetail, status: number) { export function changeStatus(that: TicketDetail, status: number) {
that.setState({ that.setState({
isStatusLoading: true, isLoading: {
...that.state.isLoading,
status: true,
},
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/update'), url: getUrl('/tickets/update'),
@ -22,7 +25,10 @@ export function changeStatus(that: TicketDetail, status: number) {
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isStatusLoading: false, isLoading: {
...that.state.isLoading,
status: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
@ -37,7 +43,10 @@ export function changeStatus(that: TicketDetail, status: number) {
.catch((err) => { .catch((err) => {
console.log(err.errMsg); console.log(err.errMsg);
that.setState({ that.setState({
isStatusLoading: false, isLoading: {
...that.state.isLoading,
status: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg, message: pt.get().button.submitText.error + err.errMsg,

View File

@ -0,0 +1,42 @@
import ConclusionPage from '@/pages/Conclusion/Conclusion';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
import { getUrl } from '.';
export function conclude(that: ConclusionPage) {
that.setState({
isLoading: true,
});
Taro.request({
url: getUrl('/member/conclusion'),
method: 'POST',
data: {
token: wechatUser.getToken(),
conclusion: that.state.conclusion,
week: (that.state.shift[0] + 1).toString(),
shift: (that.state.shift[1] + 1).toString(),
},
})
.then((res) => {
console.log(res.data);
that.setState({
isLoading: false,
conclusionId: res.data.data.id,
});
Taro.atMessage({
message: pt.get().button.submitText.success,
type: 'success',
});
})
.catch((err) => {
console.log(err.errMsg);
that.setState({
isLoading: false,
});
Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg,
type: 'error',
});
});
}

View File

@ -16,6 +16,7 @@ export function getCurrentTicket(that: RepairPage) {
.then((res) => { .then((res) => {
const data = res.data.data; const data = res.data.data;
let newIdNameList: Array<Map<number, string>> = []; let newIdNameList: Array<Map<number, string>> = [];
if (data.list.length !== 0) {
data.list.map((ticket: TicketListItem) => { data.list.map((ticket: TicketListItem) => {
if ( if (
ticket['status'] !== 3 && ticket['status'] !== 3 &&
@ -29,6 +30,7 @@ export function getCurrentTicket(that: RepairPage) {
); );
} }
}); });
}
that.setState({ that.setState({
currentTicketsIdName: newIdNameList, currentTicketsIdName: newIdNameList,
}); });

View File

@ -1,6 +1,7 @@
import MainPage from '@/pages/index'; import MainPage from '@/pages/index';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import pt from '@/plain-text';
import { getUrl } from '.'; import { getUrl } from '.';
export function getDutyInfo(that: MainPage) { export function getDutyInfo(that: MainPage) {
@ -20,25 +21,32 @@ export function getDutyInfo(that: MainPage) {
return; return;
} }
const data = res.data.data; const data = res.data.data;
if (data.isInDuty) {
that.setState({ that.setState({
rs: former.trans(true), rs: former.trans(true),
dutyData: data,
});
if (!data.isInDuty) {
that.setState({
dutyData: { dutyData: {
isInDuty: data.isInDuty, ...data,
inDutyCnt: data.inDutyCnt, offDutyReason: pt.get().common.offDutyReason,
currentDuty: data.currentDuty,
otherDutyTime: data.otherDutyTime,
place: data.place,
}, },
}); });
if (data.currentDuty === '0') {
that.setState({
dutyData: {
...data,
place: pt.get().common.place,
offDutyReason: pt.get().common.offDutyReason,
dutyRecoverTime: pt.get().common.dutyRecoverTime,
},
});
}
} else { } else {
that.setState({ that.setState({
rs: former.trans(true),
dutyData: { dutyData: {
isInDuty: data.isInDuty, ...data,
offDutyReason: data.offDutyReason, place: pt.get().common.place,
dutyRecoverTime: data.dutyRecoverTime,
place: data.place,
}, },
}); });
} }
@ -50,6 +58,10 @@ export function getDutyInfo(that: MainPage) {
rs: former.trans(false), rs: former.trans(false),
dutyData: { dutyData: {
isInDuty: false, isInDuty: false,
inDutyCnt: 0,
currentDuty: '0',
otherDutyStart: '',
otherDutyEnd: '',
offDutyReason: '获取失败Network Error!', offDutyReason: '获取失败Network Error!',
dutyRecoverTime: '获取失败Network Error!', dutyRecoverTime: '获取失败Network Error!',
place: '204', place: '204',

View File

@ -9,23 +9,29 @@ export function getDisable(that: TicketDetail, id: number) {
method: 'GET', method: 'GET',
data: { data: {
id: id, id: id,
token: wechatUser.getToken(),
}, },
}) })
.then((res) => { .then((res) => {
const data = res.data.data; const data = res.data.data;
let isDisable_main = that.state.isDisable_main;
if (data.status === 3 || data.status === 5 || data.status === 7) { if (data.status === 3 || data.status === 5 || data.status === 7) {
that.setState({ isDisable_main.retrieve = true;
isRetrieveDisable_main: true, isDisable_main.comment = true;
isCommentDisable_main: true,
});
} }
if (wechatUser.getAccess()) { if (wechatUser.getAccess()) {
if (data.workers.includes(wechatUser.getInfo().name)) { if (data.workers.includes(wechatUser.getInfo().name)) {
isDisable_main.pick = true;
}
}
that.setState({ that.setState({
isPickDisable_main: true, isDisable_main: {
...that.state.isDisable_main,
retrieve: isDisable_main.retrieve,
comment: isDisable_main.comment,
pick: isDisable_main.pick,
},
}); });
}
}
}) })
.catch((reason) => { .catch((reason) => {
console.log(reason.errMsg); console.log(reason.errMsg);

View File

@ -6,7 +6,7 @@ import { getLocaleData } from './localeData';
export function getInfo() { export function getInfo() {
Taro.request({ Taro.request({
url: getUrl('/member/login'), url: getUrl('/member/checklogin'),
method: 'POST', method: 'POST',
data: { data: {
token: wechatUser.getToken(), token: wechatUser.getToken(),

View File

@ -21,6 +21,9 @@ export function loginAte() {
data: data.token, data: data.token,
}); });
wechatUser.setToken(data.token); wechatUser.setToken(data.token);
Taro.reLaunch({
url: '/pages/index/index',
});
getLocaleData(); getLocaleData();
}) })
.catch((err) => { .catch((err) => {

View File

@ -1,6 +1,7 @@
import MainPage from '@/pages/index'; import MainPage from '@/pages/index';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import pt from '@/plain-text';
import { getUrl } from '.'; import { getUrl } from '.';
export function getMemberDutyInfo(that: MainPage) { export function getMemberDutyInfo(that: MainPage) {
@ -13,32 +14,35 @@ export function getMemberDutyInfo(that: MainPage) {
}) })
.then((res) => { .then((res) => {
const data = res.data.data; const data = res.data.data;
if (data.isInDuty) { that.setState({
dutyData: data,
});
if (!data.isInDuty) {
that.setState({ that.setState({
dutyData: { dutyData: {
isInDuty: data.isInDuty, ...data,
inDutyCnt: data.inDutyCnt, offDutyReason: pt.get().common.offDutyReason,
currentDuty: data.currentDuty,
place: data.place,
}, },
inDutyCnt: data.inDutyCnt,
}); });
} else { if (data.currentDuty === '0') {
that.setState({ that.setState({
dutyData: { dutyData: {
isInDuty: data.isInDuty, ...data,
offDutyReason: data.offDutyReason, place: pt.get().common.place,
dutyRecoverTime: data.dutyRecoverTime,
place: data.place,
}, },
}); });
} }
}
}) })
.catch((err) => { .catch((err) => {
console.log(err.errMsg); console.log(err.errMsg);
that.setState({ that.setState({
dutyData: { dutyData: {
isInDuty: false, isInDuty: false,
inDutyCnt: 0,
currentDuty: '0',
otherDutyStart: '',
otherDutyEnd: '',
offDutyReason: '获取失败Network Error!', offDutyReason: '获取失败Network Error!',
dutyRecoverTime: '获取失败Network Error!', dutyRecoverTime: '获取失败Network Error!',
place: '204', place: '204',

View File

@ -0,0 +1,35 @@
import PicUploader from '@/components/PicUploader/PicUploader';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
import { randomString } from '@/utils/random';
import { getUrl } from '.';
const randomLength = 8;
export function picUpload(that: PicUploader, file: string) {
Taro.uploadFile({
url: getUrl('/upload/pic'),
filePath: file,
name: randomString(randomLength),
formData: {
token: wechatUser.getToken(),
source: that.props.source,
id: that.props.id,
},
})
.then((res) => {
console.log(res.data);
Taro.atMessage({
message: pt.get().button.submitText.success,
type: 'success',
});
})
.catch((err) => {
console.log(err.errMsg);
Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg,
type: 'error',
});
});
}

View File

@ -8,7 +8,10 @@ const reLaunchInterval = 1000;
export function pickTicket(that: TicketDetail) { export function pickTicket(that: TicketDetail) {
that.setState({ that.setState({
isPickLoading: true, isLoading: {
...that.state.isLoading,
pick: true,
},
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/pick'), url: getUrl('/tickets/pick'),
@ -21,7 +24,10 @@ export function pickTicket(that: TicketDetail) {
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isPickLoading: false, isLoading: {
...that.state.isLoading,
pick: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
@ -36,7 +42,10 @@ export function pickTicket(that: TicketDetail) {
.catch((err) => { .catch((err) => {
console.log(err.errMsg); console.log(err.errMsg);
that.setState({ that.setState({
isPickLoading: false, isLoading: {
...that.state.isLoading,
pick: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg, message: pt.get().button.submitText.error + err.errMsg,

View File

@ -8,7 +8,10 @@ const reLaunchInterval = 1000;
export function retrieve(that: TicketDetail) { export function retrieve(that: TicketDetail) {
that.setState({ that.setState({
isRetrieveLoading: true, isLoading: {
...that.state.isLoading,
retrieve: true,
},
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/retrieve'), url: getUrl('/tickets/retrieve'),
@ -21,7 +24,10 @@ export function retrieve(that: TicketDetail) {
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isRetrieveLoading: false, isLoading: {
...that.state.isLoading,
retrieve: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
@ -36,7 +42,10 @@ export function retrieve(that: TicketDetail) {
.catch((err) => { .catch((err) => {
console.log(err.errMsg); console.log(err.errMsg);
that.setState({ that.setState({
isRetrieveLoading: false, isLoading: {
...that.state.isLoading,
retrieve: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg, message: pt.get().button.submitText.error + err.errMsg,

View File

@ -1,42 +1,37 @@
import TicketDetail from '@/pages/TicketDetail/TicketDetail'; import { Comment } from '@/pages/TicketDetail/Comment';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import pt from '@/plain-text'; import pt from '@/plain-text';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import { getUrl } from '.'; import { getUrl } from '.';
const reLaunchInterval = 1000; export function submitComment(that: Comment) {
export function submitComment(that: TicketDetail) {
that.setState({ that.setState({
isCommentLoading: true, isLoading: true,
}); });
Taro.request({ Taro.request({
url: getUrl('/report'), url: getUrl('/tickets/addnote'),
method: 'POST', method: 'POST',
data: { data: {
token: wechatUser.getToken(), token: wechatUser.getToken(),
comment: that.state.comment, content: that.state.comment,
id: that.props.id,
}, },
}) })
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isCommentLoading: false, isLoading: false,
commentId: res.data.data.id,
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
type: 'success', type: 'success',
}); });
setTimeout(() => {
Taro.reLaunch({
url: '/pages/TicketDetail/TicketDetail?id=' + that.state.id,
});
}, reLaunchInterval);
}) })
.catch((err) => { .catch((err) => {
console.log(err.errMsg); console.log(err.errMsg);
that.setState({ that.setState({
isCommentLoading: false, isLoading: false,
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg, message: pt.get().button.submitText.error + err.errMsg,

View File

@ -14,7 +14,7 @@ export function getTicketList(that: TicketListPage) {
token: wechatUser.getToken(), token: wechatUser.getToken(),
pageId: that.state.currentPage, pageId: that.state.currentPage,
count: that.state.pageSize, count: that.state.pageSize,
querytype: 0, queryType: 0,
}, },
}) })
.then((res) => { .then((res) => {
@ -28,7 +28,7 @@ export function getTicketList(that: TicketListPage) {
} }
that.setState({ that.setState({
rs: former.trans(true), rs: former.trans(true),
fixList: data.data.map( fixList: data.list.map(
(item: { (item: {
id: number; id: number;
device: string; device: string;
@ -67,7 +67,7 @@ export function searchTicketList(that: TicketListPage) {
pageId: that.state.currentPage, pageId: that.state.currentPage,
count: that.state.pageSize, count: that.state.pageSize,
value: that.state.search, value: that.state.search,
querytype: 0, queryType: 0,
}, },
}) })
.then((res) => { .then((res) => {

View File

@ -4,6 +4,7 @@ import Taro from '@tarojs/taro';
import moment from 'moment'; import moment from 'moment';
import { FixStatus } from '@/common'; import { FixStatus } from '@/common';
import pt from '@/plain-text'; import pt from '@/plain-text';
import wechatUser from '@/wechat';
import { getUrl } from '.'; import { getUrl } from '.';
const mapStatusStep: Map<FixStatus, 0 | 1 | 2 | 3> = new Map([ const mapStatusStep: Map<FixStatus, 0 | 1 | 2 | 3> = new Map([
@ -23,6 +24,7 @@ export function getTicketInfo(that: DetailFramework, id: number) {
method: 'GET', method: 'GET',
data: { data: {
id: id, id: id,
token: wechatUser.getToken(),
}, },
}) })
.then((res) => { .then((res) => {
@ -56,6 +58,7 @@ export function getTicketInfo(that: DetailFramework, id: number) {
type: 0 | 1 | 2; type: 0 | 1 | 2;
content: string; content: string;
createdTime: string; createdTime: string;
pic: string[];
}) => { }) => {
notes.push({ notes.push({
avatar: item.avatar, avatar: item.avatar,
@ -64,6 +67,7 @@ export function getTicketInfo(that: DetailFramework, id: number) {
type: item.type, type: item.type,
content: item.content, content: item.content,
createdTime: moment(item.createdTime as string), createdTime: moment(item.createdTime as string),
pic: item.pic,
}); });
}, },
); );

View File

@ -1,3 +1,14 @@
export const randomInt = (floor: number, ceiling: number) => { export const randomInt = (floor: number, ceiling: number) => {
return Math.floor(Math.random() * (ceiling - floor + 1) + floor); return Math.floor(Math.random() * (ceiling - floor + 1) + floor);
}; };
export const randomString = (length: number) => {
const chars =
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
const maxPos = chars.length;
let randomStr = '';
for (let i = 0; i < length; i++) {
randomStr += chars.charAt(Math.floor(Math.random() * maxPos));
}
return randomStr;
};