Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9931b23337 | ||
|
|
84507f7214 | ||
|
|
802d008767 | ||
|
|
c070b356fe | ||
|
|
b1c0e5d8b1 | ||
|
|
e82225ecbc | ||
|
|
df71ebf219 | ||
|
|
0dac2ad185 | ||
|
|
e1c3b464a6 | ||
|
|
e11a58dbb5 | ||
|
|
5bafff52ad | ||
|
|
d83136a69c | ||
|
|
b243fc5e4c | ||
|
|
2f6b98b43f | ||
|
|
6cd27cce10 | ||
|
|
7810cbaca1 | ||
|
|
0120da0760 | ||
|
|
f17bfa2a9e | ||
|
|
2e2629fe0a | ||
|
|
eea622b657 | ||
|
|
cd076cd5a4 | ||
|
|
a1aa63635f | ||
|
|
946a312c61 | ||
|
|
388814f9d9 | ||
|
|
9bd6c8f1b4 | ||
|
|
551d93c8b5 | ||
|
|
32ce506764 | ||
|
|
eaa22dcaa5 | ||
|
|
9c6cbd91ff | ||
|
|
6583b51750 | ||
|
|
dd56725575 | ||
|
|
2fd629d479 | ||
|
|
d5b8af7d7b | ||
|
|
aa334d3f93 | ||
|
|
7aaad7563f | ||
|
|
4d6a769fea | ||
|
|
afdedea344 | ||
|
|
2920059ffa | ||
|
|
d2de74578b | ||
|
|
ac23f88cdd | ||
|
|
e1e998628f | ||
|
|
806e7a393c | ||
|
|
fd6a60d1d3 | ||
|
|
36a9a35886 | ||
|
|
51106ead5e | ||
|
|
4e31eb70e2 | ||
|
|
dd770b8ece | ||
|
|
b174304d74 | ||
|
|
cc5af58155 | ||
|
|
88cdb6cb92 | ||
|
|
00977db512 | ||
|
|
1907f1e967 | ||
|
|
39dd945020 | ||
|
|
b603ad24b3 | ||
|
|
dd07c1da10 | ||
|
|
a7fd2b2856 | ||
|
|
0baf91fadf | ||
|
|
c756e74778 | ||
|
|
133d60375a | ||
|
|
bea23f4705 | ||
|
|
229dffa9a1 | ||
|
|
74f644b3ee | ||
|
|
0a98ea71ac | ||
|
|
1a30ff6def | ||
|
|
3232994fb2 | ||
|
|
d995c6ed43 | ||
|
|
6cbd6685bc | ||
|
|
c63b7fcca8 | ||
|
|
34c3753d2c | ||
|
|
a5aa10d6f4 | ||
|
|
f37af7dacd | ||
|
|
21e21f272f | ||
|
|
a408ac9e39 | ||
|
|
162b7a7d09 | ||
|
|
54091bb6b3 | ||
|
|
098ddd3c13 | ||
|
|
64e4b8d6bd | ||
|
|
349f125404 | ||
|
|
d9d005986e | ||
|
|
7cd56d7c79 | ||
|
|
ff880de466 | ||
|
|
11f16b6b06 | ||
|
|
5f2e66546c | ||
|
|
20b9016f51 | ||
|
|
08401dd64d | ||
|
|
a9d9415def | ||
|
|
0841fc91fc | ||
|
|
83d2e8419e | ||
|
|
eb7623917c | ||
|
|
f0fe2f6abf | ||
|
|
7d7d8df7d3 | ||
|
|
419a66fd2b | ||
|
|
b9c20c1dfd | ||
|
|
58ffec6cb6 | ||
|
|
b88beeb9e7 | ||
|
|
a9d318c6e2 | ||
|
|
d6671e055a | ||
|
|
01fc78fb12 | ||
|
|
7f84b72ddc | ||
|
|
08fbd58c61 | ||
|
|
0713644961 | ||
|
|
d15067f2fe | ||
|
|
14b302bd1a | ||
|
|
6f896c8695 |
@@ -1,12 +0,0 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
@@ -1,2 +1,3 @@
|
||||
# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config
|
||||
# TARO_APP_ID="开发环境下的小程序appid"
|
||||
TARO_APP_ID="wx636eb7cf2b84f305"
|
||||
TARO_APP_API="http://127.0.0.1:9527"
|
||||
@@ -1 +1,2 @@
|
||||
# TARO_APP_ID="生产环境下的小程序appid"
|
||||
TARO_APP_ID="wx636eb7cf2b84f305"
|
||||
TARO_APP_API=""
|
||||
@@ -1 +1 @@
|
||||
# TARO_APP_ID="测试环境下的小程序appid"
|
||||
TARO_APP_ID="wx636eb7cf2b84f305"
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
config
|
||||
.husky
|
||||
**/.gitignore
|
||||
dist/
|
||||
deploy_versions/
|
||||
.temp/
|
||||
.rn_temp/
|
||||
node_modules/
|
||||
.DS_Store
|
||||
.swc
|
||||
.husky
|
||||
.prettierignore
|
||||
.env.*
|
||||
**/*.json
|
||||
**/*.svg
|
||||
**/*.scss
|
||||
**/*.md
|
||||
*.config.js
|
||||
index.html
|
||||
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"extends": ["taro/react"],
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"react/jsx-uses-react": "off",
|
||||
"react/react-in-jsx-scope": "off"
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"prettier/prettier": "error"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
_
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
@@ -0,0 +1,14 @@
|
||||
.eslintignore
|
||||
**/.gitignore
|
||||
dist/
|
||||
deploy_versions/
|
||||
.temp/
|
||||
.rn_temp/
|
||||
node_modules/
|
||||
.DS_Store
|
||||
.swc
|
||||
.husky
|
||||
.prettierignore
|
||||
.env.*
|
||||
project.*.json
|
||||
**/*.svg
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"proseWrap": "preserve",
|
||||
"arrowParens": "always",
|
||||
"bracketSpacing": true,
|
||||
"jsxSingleQuote": true,
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
@@ -58,6 +58,7 @@
|
||||
## 主页
|
||||
|
||||
1. 信息显示
|
||||
1. 不显示是哪一班,只显示今日值班时间
|
||||
2. (协会成员)相关信息
|
||||
3. 提醒事项
|
||||
4. 如何联系到协会
|
||||
@@ -68,8 +69,21 @@
|
||||
2. 维修进度提示
|
||||
3. (面向协会成员)维修列表
|
||||
|
||||
## 成员
|
||||
|
||||
1. 最近七天内未取回的工单列表
|
||||
2. 值班组长上传本班相关信息
|
||||
3. 现在自己是否要值班(值班时间显示)
|
||||
|
||||
|
||||
## 我的
|
||||
|
||||
1. 更改手机号等个人信息(手机号可以填写多个)
|
||||
2. (备选)修改用户名、头像
|
||||
3. 设置真名(可帮助预填写工单)
|
||||
|
||||
# 主席团管理页面
|
||||
|
||||
1. 值班表导入、更新
|
||||
2. 成员权限管理
|
||||
3. 特殊维修时间(如学园维修)、值班信息更新
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import TestUtils from '@tarojs/test-utils-react'
|
||||
|
||||
describe('Testing', () => {
|
||||
|
||||
test('Test', async () => {
|
||||
const testUtils = new TestUtils()
|
||||
await testUtils.createApp()
|
||||
await testUtils.PageLifecycle.onShow('pages/index/index')
|
||||
expect(testUtils.html()).toMatchSnapshot()
|
||||
})
|
||||
|
||||
})
|
||||
@@ -2,9 +2,12 @@
|
||||
// https://github.com/NervJS/taro/blob/next/packages/babel-preset-taro/README.md
|
||||
module.exports = {
|
||||
presets: [
|
||||
['taro', {
|
||||
[
|
||||
'taro',
|
||||
{
|
||||
framework: 'react',
|
||||
ts: true
|
||||
}]
|
||||
]
|
||||
}
|
||||
ts: true,
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { UserConfigExport } from "@tarojs/cli";
|
||||
import type { UserConfigExport } from '@tarojs/cli';
|
||||
|
||||
export default {
|
||||
logger: {
|
||||
quiet: false,
|
||||
stats: true
|
||||
stats: true,
|
||||
},
|
||||
mini: {},
|
||||
h5: {}
|
||||
} satisfies UserConfigExport
|
||||
h5: {},
|
||||
} satisfies UserConfigExport;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { defineConfig, type UserConfigExport } from '@tarojs/cli'
|
||||
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'
|
||||
import devConfig from './dev'
|
||||
import prodConfig from './prod'
|
||||
import { defineConfig, type UserConfigExport } from '@tarojs/cli';
|
||||
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
|
||||
import devConfig from './dev';
|
||||
import prodConfig from './prod';
|
||||
|
||||
// https://taro-docs.jd.com/docs/next/config#defineconfig-辅助函数
|
||||
export default defineConfig(async (merge, { command, mode }) => {
|
||||
@@ -13,92 +13,93 @@ export default defineConfig(async (merge, { command, mode }) => {
|
||||
640: 2.34 / 2,
|
||||
750: 1,
|
||||
375: 2,
|
||||
828: 1.81 / 2
|
||||
828: 1.81 / 2,
|
||||
},
|
||||
sourceRoot: 'src',
|
||||
outputRoot: 'dist',
|
||||
plugins: [],
|
||||
defineConstants: {
|
||||
},
|
||||
plugins: ['@tarojs/plugin-mock'],
|
||||
defineConstants: {},
|
||||
copy: {
|
||||
patterns: [
|
||||
],
|
||||
options: {
|
||||
}
|
||||
patterns: [],
|
||||
options: {},
|
||||
},
|
||||
framework: 'react',
|
||||
compiler: 'webpack5',
|
||||
compiler: {
|
||||
type: 'webpack5',
|
||||
prebundle: {
|
||||
exclude: ['taro-ui'],
|
||||
},
|
||||
},
|
||||
cache: {
|
||||
enable: false // Webpack 持久化缓存配置,建议开启。默认配置请参考:https://docs.taro.zone/docs/config-detail#cache
|
||||
enable: false, // Webpack 持久化缓存配置,建议开启。默认配置请参考:https://docs.taro.zone/docs/config-detail#cache
|
||||
},
|
||||
mini: {
|
||||
postcss: {
|
||||
pxtransform: {
|
||||
enable: true,
|
||||
config: {
|
||||
|
||||
}
|
||||
config: {},
|
||||
},
|
||||
url: {
|
||||
enable: true,
|
||||
config: {
|
||||
limit: 1024 // 设定转换尺寸上限
|
||||
}
|
||||
limit: 1024, // 设定转换尺寸上限
|
||||
},
|
||||
},
|
||||
cssModules: {
|
||||
enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
|
||||
config: {
|
||||
namingPattern: 'module', // 转换模式,取值为 global/module
|
||||
generateScopedName: '[name]__[local]___[hash:base64:5]'
|
||||
}
|
||||
}
|
||||
generateScopedName: '[name]__[local]___[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
},
|
||||
webpackChain(chain) {
|
||||
chain.resolve.plugin('tsconfig-paths').use(TsconfigPathsPlugin)
|
||||
}
|
||||
chain.resolve.plugin('tsconfig-paths').use(TsconfigPathsPlugin);
|
||||
},
|
||||
},
|
||||
h5: {
|
||||
esnextModules: ['taro-ui'],
|
||||
publicPath: '/',
|
||||
staticDirectory: 'static',
|
||||
output: {
|
||||
filename: 'js/[name].[hash:8].js',
|
||||
chunkFilename: 'js/[name].[chunkhash:8].js'
|
||||
chunkFilename: 'js/[name].[chunkhash:8].js',
|
||||
},
|
||||
miniCssExtractPluginOption: {
|
||||
ignoreOrder: true,
|
||||
filename: 'css/[name].[hash].css',
|
||||
chunkFilename: 'css/[name].[chunkhash].css'
|
||||
chunkFilename: 'css/[name].[chunkhash].css',
|
||||
},
|
||||
postcss: {
|
||||
autoprefixer: {
|
||||
enable: true,
|
||||
config: {}
|
||||
config: {},
|
||||
},
|
||||
cssModules: {
|
||||
enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
|
||||
config: {
|
||||
namingPattern: 'module', // 转换模式,取值为 global/module
|
||||
generateScopedName: '[name]__[local]___[hash:base64:5]'
|
||||
}
|
||||
}
|
||||
generateScopedName: '[name]__[local]___[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
},
|
||||
webpackChain(chain) {
|
||||
chain.resolve.plugin('tsconfig-paths').use(TsconfigPathsPlugin)
|
||||
}
|
||||
chain.resolve.plugin('tsconfig-paths').use(TsconfigPathsPlugin);
|
||||
},
|
||||
},
|
||||
rn: {
|
||||
appName: 'taroDemo',
|
||||
postcss: {
|
||||
cssModules: {
|
||||
enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// 本地开发构建配置(不混淆压缩)
|
||||
return merge({}, baseConfig, devConfig)
|
||||
return merge({}, baseConfig, devConfig);
|
||||
}
|
||||
// 生产构建配置(默认开启压缩混淆等)
|
||||
return merge({}, baseConfig, prodConfig)
|
||||
})
|
||||
return merge({}, baseConfig, prodConfig);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { UserConfigExport } from "@tarojs/cli";
|
||||
import type { UserConfigExport } from '@tarojs/cli';
|
||||
|
||||
export default {
|
||||
mini: {},
|
||||
h5: {
|
||||
@@ -28,5 +29,5 @@ export default {
|
||||
// postProcess: (context) => ({ ...context, outputPath: path.join(staticDir, 'index.html') })
|
||||
// }))
|
||||
// }
|
||||
}
|
||||
} satisfies UserConfigExport
|
||||
},
|
||||
} satisfies UserConfigExport;
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
# 接口文档
|
||||
|
||||
## 基本格式
|
||||
|
||||
### 成功响应格式
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**NOTE:** 若无特殊说明,`POST`请求的响应`data`字段为空(`{}`),可以不用管。
|
||||
|
||||
### 失败响应格式
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"err": "some error"
|
||||
}
|
||||
```
|
||||
|
||||
### `GET`请求默认格式(若无特殊说明)
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "token_test"
|
||||
}
|
||||
```
|
||||
|
||||
## 主页面
|
||||
|
||||
### 值班信息 `GET /dutyinfo`
|
||||
|
||||
#### 当前在值班
|
||||
|
||||
data:
|
||||
|
||||
```json
|
||||
{
|
||||
"isInDuty": true,
|
||||
"inDutyCnt": 3,
|
||||
"currentDuty": "2"
|
||||
}
|
||||
```
|
||||
|
||||
#### 当前未值班
|
||||
|
||||
data:
|
||||
|
||||
```json
|
||||
{
|
||||
"isInDuty": false,
|
||||
"offDutyReason": "学园维修",
|
||||
"dutyRecoverTime": "下周一"
|
||||
}
|
||||
```
|
||||
|
||||
## 用户页面
|
||||
|
||||
### 个人信息 `GET /user/info`
|
||||
|
||||
data:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "马保国",
|
||||
"phone": "13333333333"
|
||||
}
|
||||
```
|
||||
|
||||
### 修改个人信息 `POST /user/update`
|
||||
|
||||
Request body:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "宇航员",
|
||||
"phone": "1233333210"
|
||||
}
|
||||
```
|
||||
|
||||
### 本地化设置
|
||||
|
||||
#### 获取本地化设置 `GET /user/locale/get`
|
||||
|
||||
data:
|
||||
|
||||
```json
|
||||
{
|
||||
"lang": "zh_CN"
|
||||
}
|
||||
```
|
||||
|
||||
#### 更新本地化设置 `POST /user/locale/update`
|
||||
|
||||
Request body:
|
||||
|
||||
```json
|
||||
{
|
||||
"lang": "en_US"
|
||||
}
|
||||
```
|
||||
|
||||
### 意见反馈 `POST /report`
|
||||
|
||||
Request body:
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "token_test",
|
||||
"content": "aaa bbbb ccccc"
|
||||
}
|
||||
```
|
||||
|
||||
### 我的工单(查询)`GET /user/mytickets`
|
||||
|
||||
data (same as oreo):
|
||||
|
||||
```json
|
||||
{
|
||||
"list": [
|
||||
{
|
||||
"id": 6830,
|
||||
"type": 1,
|
||||
"status": 5,
|
||||
"device": "主机",
|
||||
"deviceModel": "技嘉",
|
||||
"owner": "武技栏",
|
||||
"phone": "18888888888",
|
||||
"createdTime": "2024-03-06T19:49:27.043865",
|
||||
"isConfirmed": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 工单详情
|
||||
|
||||
### 创建评论 `POST /tickets/newcomment/{id}`
|
||||
|
||||
Request
|
||||
|
||||
```json
|
||||
{
|
||||
"content": "这是一条评论",
|
||||
"token": "token_test"
|
||||
}
|
||||
```
|
||||
|
||||
### 创建工单 `POST /tickets/create`
|
||||
|
||||
Request
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "token_test",
|
||||
"type": 1, // 电器是0,电脑是1(bushi)
|
||||
"device": "华硕",
|
||||
"deviceModel": "天选3",
|
||||
"owner": "西西弗",
|
||||
"phone": "12333333333",
|
||||
"description": "没法用pd充电",
|
||||
"accessories": [0]
|
||||
}
|
||||
```
|
||||
|
||||
### 工单信息 `GET /tickets/info/{id}`
|
||||
|
||||
data (same as oreo):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 6847,
|
||||
"type": 1,
|
||||
"device": "华硕",
|
||||
"deviceModel": "灵耀X14",
|
||||
"owner": "唐姐姐",
|
||||
"phone": "15555555555",
|
||||
"description": "清灰",
|
||||
"workers": [],
|
||||
"createdTime": "2024-03-07T19:52:48.523303",
|
||||
"status": 5,
|
||||
"isConfirmed": false,
|
||||
"notes": [
|
||||
{
|
||||
"avatar": "https://....jpg",
|
||||
"id": 21368,
|
||||
"op": "宇航员",
|
||||
"type": 0,
|
||||
"content": "",
|
||||
"createdTime": "2024-03-07T19:52:48.523305"
|
||||
},
|
||||
{
|
||||
"avatar": "https://....jpg",
|
||||
"id": 21370,
|
||||
"op": "宇航员",
|
||||
"type": 2,
|
||||
"content": "1",
|
||||
"createdTime": "2024-03-07T19:58:27.838816"
|
||||
},
|
||||
{
|
||||
"avatar": "https://....jpg",
|
||||
"id": 21373,
|
||||
"op": "宇航员",
|
||||
"type": 2,
|
||||
"content": "4",
|
||||
"createdTime": "2024-03-07T20:28:12.070707"
|
||||
},
|
||||
{
|
||||
"avatar": "https://....jpg",
|
||||
"id": 21374,
|
||||
"op": "宇航员",
|
||||
"type": 2,
|
||||
"content": "5",
|
||||
"createdTime": "2024-03-07T20:30:15.770486"
|
||||
}
|
||||
],
|
||||
"accessories": [2],
|
||||
"picked": false
|
||||
}
|
||||
```
|
||||
@@ -1,6 +0,0 @@
|
||||
const defineJestConfig = require('@tarojs/test-utils-react/dist/jest.js').default
|
||||
|
||||
module.exports = defineJestConfig({
|
||||
testEnvironment: 'jsdom',
|
||||
testMatch: ['<rootDir>/__tests__/**/*.(spec|test).[jt]s?(x)']
|
||||
})
|
||||
@@ -0,0 +1,59 @@
|
||||
import mytickets from './mytickets.json';
|
||||
import ticketInfo from './ticketInfo.json';
|
||||
import uncompleted from './uncompleted.json';
|
||||
|
||||
export default {
|
||||
'GET /dutyinfo': {
|
||||
success: true,
|
||||
data: {
|
||||
token: 'token_test',
|
||||
isInDuty: true,
|
||||
inDutyCnt: 3,
|
||||
currentDuty: '2',
|
||||
},
|
||||
},
|
||||
'GET /user/info': {
|
||||
success: true,
|
||||
data: {
|
||||
token: 'token_test',
|
||||
name: '马保国',
|
||||
phone: 13333333333,
|
||||
},
|
||||
},
|
||||
'POST /user/update': {
|
||||
data: {},
|
||||
},
|
||||
'GET /user/locale/get': {
|
||||
success: true,
|
||||
data: {
|
||||
lang: 'en_US',
|
||||
},
|
||||
},
|
||||
'POST /user/locale/update': {
|
||||
data: {},
|
||||
},
|
||||
'POST /report': {
|
||||
data: {},
|
||||
},
|
||||
'GET /user/mytickets': {
|
||||
success: true,
|
||||
data: mytickets,
|
||||
},
|
||||
'GET /tickets/info': {
|
||||
success: true,
|
||||
data: ticketInfo,
|
||||
},
|
||||
'POST /tickets/newcomment': {
|
||||
data: {},
|
||||
},
|
||||
'POST /tickets/create': {
|
||||
data: {},
|
||||
},
|
||||
'POST /member/login': {
|
||||
data: {},
|
||||
},
|
||||
'GET /member/tickets/uncompleted': {
|
||||
success: true,
|
||||
data: uncompleted,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"list": [
|
||||
{
|
||||
"id": 6830,
|
||||
"type": 1,
|
||||
"status": 2,
|
||||
"device": "主机",
|
||||
"deviceModel": "技嘉",
|
||||
"owner": "武技栏",
|
||||
"phone": "18888888888",
|
||||
"createdTime": "2024-03-06T19:49:27.043865",
|
||||
"isConfirmed": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"id": 6830,
|
||||
"type": 1,
|
||||
"device": "华硕",
|
||||
"deviceModel": "灵耀X14",
|
||||
"owner": "唐姐姐",
|
||||
"phone": "15555555555",
|
||||
"description": "清灰",
|
||||
"workers": [],
|
||||
"createdTime": "2024-03-07T19:52:48.523303",
|
||||
"status": 2,
|
||||
"isConfirmed": false,
|
||||
"notes": [
|
||||
{
|
||||
"avatar": "https://....jpg",
|
||||
"id": 21368,
|
||||
"op": "宇航员",
|
||||
"type": 0,
|
||||
"content": "",
|
||||
"createdTime": "2024-03-07T19:52:48.523305"
|
||||
},
|
||||
{
|
||||
"avatar": "https://....jpg",
|
||||
"id": 21370,
|
||||
"op": "宇航员",
|
||||
"type": 2,
|
||||
"content": "1",
|
||||
"createdTime": "2024-03-07T19:58:27.838816"
|
||||
},
|
||||
{
|
||||
"avatar": "https://....jpg",
|
||||
"id": 21373,
|
||||
"op": "宇航员",
|
||||
"type": 2,
|
||||
"content": "4",
|
||||
"createdTime": "2024-03-07T20:28:12.070707"
|
||||
},
|
||||
{
|
||||
"avatar": "https://....jpg",
|
||||
"id": 21374,
|
||||
"op": "宇航员",
|
||||
"type": 2,
|
||||
"content": "5",
|
||||
"createdTime": "2024-03-07T20:30:15.770486"
|
||||
}
|
||||
],
|
||||
"accessories": [2],
|
||||
"picked": false
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"list": [
|
||||
{
|
||||
"id": 6832,
|
||||
"type": 1,
|
||||
"status": 2,
|
||||
"device": "ROG",
|
||||
"deviceModel": "幻 14 2022",
|
||||
"owner": "晓洋",
|
||||
"phone": "18888888887",
|
||||
"createdTime": "2024-03-07T11:45:14.191981",
|
||||
"isConfirmed": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
"build:jd": "taro build --type jd",
|
||||
"build:quickapp": "taro build --type quickapp",
|
||||
"build:harmony-hybrid": "taro build --type harmony-hybrid",
|
||||
"dev:weapp": "npm run build:weapp -- --watch",
|
||||
"dev:weapp": "npm run build:weapp -- --watch --mode dev",
|
||||
"dev:swan": "npm run build:swan -- --watch",
|
||||
"dev:alipay": "npm run build:alipay -- --watch",
|
||||
"dev:tt": "npm run build:tt -- --watch",
|
||||
@@ -30,7 +30,8 @@
|
||||
"dev:jd": "npm run build:jd -- --watch",
|
||||
"dev:quickapp": "npm run build:quickapp -- --watch",
|
||||
"dev:harmony-hybrid": "npm run build:harmony-hybrid -- --watch",
|
||||
"test": "jest"
|
||||
"test": "jest",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 3 versions",
|
||||
@@ -54,14 +55,18 @@
|
||||
"@tarojs/runtime": "3.6.24",
|
||||
"@tarojs/shared": "3.6.24",
|
||||
"@tarojs/taro": "3.6.24",
|
||||
"moment": "^2.30.1",
|
||||
"process": "^0.11.10",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
"react-dom": "^18.0.0",
|
||||
"taro-ui": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.8.0",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
|
||||
"@tarojs/cli": "3.6.24",
|
||||
"@tarojs/plugin-platform-h5": "^3.6.24",
|
||||
"@tarojs/plugin-mock": "^0.0.9",
|
||||
"@tarojs/plugin-platform-h5": "3.6.24",
|
||||
"@tarojs/taro-loader": "3.6.24",
|
||||
"@tarojs/test-utils-react": "^0.1.1",
|
||||
"@tarojs/webpack5-runner": "3.6.24",
|
||||
@@ -76,10 +81,14 @@
|
||||
"eslint": "^8.12.0",
|
||||
"eslint-config-taro": "3.6.24",
|
||||
"eslint-plugin-import": "^2.12.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-react": "^7.8.2",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"husky": "^9.0.11",
|
||||
"jest": "^29.3.1",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"lint-staged": "^15.2.2",
|
||||
"mockjs": "^1.1.0",
|
||||
"postcss": "^8.4.18",
|
||||
"react-refresh": "^0.11.0",
|
||||
"stylelint": "^14.4.0",
|
||||
@@ -87,5 +96,9 @@
|
||||
"tsconfig-paths-webpack-plugin": "^4.1.0",
|
||||
"typescript": "^5.1.0",
|
||||
"webpack": "5.78.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.ts": "prettier --write",
|
||||
"*.tsx": "prettier --write"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"ignore": [],
|
||||
"disablePlugins": [],
|
||||
"outputPath": ""
|
||||
}
|
||||
},
|
||||
"packNpmRelationList": []
|
||||
},
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "3.3.4",
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
|
||||
"projectname": "EVA-Notify",
|
||||
"setting": {
|
||||
"compileHotReLoad": true
|
||||
"compileHotReLoad": true,
|
||||
"urlCheck": false,
|
||||
"bigPackageSizeSupport": true
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,41 @@
|
||||
export default defineAppConfig({
|
||||
pages: [
|
||||
'pages/index/index'
|
||||
'pages/index/index',
|
||||
'pages/repair/repair',
|
||||
'pages/member/member',
|
||||
'pages/user/user',
|
||||
'pages/user/myTicket/myTicket',
|
||||
'pages/user/inform/inform',
|
||||
'pages/user/about/about',
|
||||
'pages/user/report/report',
|
||||
'pages/user/member/member',
|
||||
'pages/TicketDetail/TicketDetail',
|
||||
],
|
||||
window: {
|
||||
backgroundTextStyle: 'light',
|
||||
navigationBarBackgroundColor: '#fff',
|
||||
navigationBarTitleText: 'WeChat',
|
||||
navigationBarTextStyle: 'black'
|
||||
}
|
||||
})
|
||||
navigationBarTitleText: 'EVA Notify',
|
||||
navigationBarTextStyle: 'black',
|
||||
},
|
||||
tabBar: {
|
||||
custom: true,
|
||||
list: [
|
||||
{
|
||||
pagePath: 'pages/index/index',
|
||||
text: '主页',
|
||||
},
|
||||
{
|
||||
pagePath: 'pages/repair/repair',
|
||||
text: '维修',
|
||||
},
|
||||
{
|
||||
pagePath: 'pages/member/member',
|
||||
text: '管理',
|
||||
},
|
||||
{
|
||||
pagePath: 'pages/user/user',
|
||||
text: '我的',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import { PropsWithChildren } from 'react'
|
||||
import { useLaunch } from '@tarojs/taro'
|
||||
import './app.scss'
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { useLaunch } from '@tarojs/taro';
|
||||
import 'taro-ui/dist/style/index.scss';
|
||||
import './app.scss';
|
||||
import { getLocaleData } from './service/localeData';
|
||||
|
||||
function App({ children }: PropsWithChildren<any>) {
|
||||
|
||||
useLaunch(() => {
|
||||
console.log('App launched.')
|
||||
})
|
||||
console.log('App launched.');
|
||||
getLocaleData();
|
||||
});
|
||||
|
||||
// children 是将要会渲染的页面
|
||||
return children
|
||||
return children;
|
||||
}
|
||||
|
||||
export default App
|
||||
export default App;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709817911051" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4420" width="24" height="24" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M523.52 965.12a448 448 0 1 1 448-448 448 448 0 0 1-448 448z m0-832a384 384 0 1 0 384 384 384 384 0 0 0-384-384z" p-id="4421" fill="#c89bc7"></path><path d="M523.52 772.16a32 32 0 0 1-32-32V448a32 32 0 0 1 64 0v292.8a32 32 0 0 1-32 31.36z" p-id="4422" fill="#c89bc7"></path><path d="M523.52 293.12m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" p-id="4423" fill="#c89bc7"></path></svg>
|
||||
|
After Width: | Height: | Size: 710 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709729147345" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7587" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M960 170.56L869.44 80 512 437.44 154.56 80 64 170.56 421.44 528 64 885.44l90.56 90.56L512 618.56 869.44 976 960 885.44 602.56 528 960 170.56z" p-id="7588" fill="#d4237a"></path></svg>
|
||||
|
After Width: | Height: | Size: 514 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709729289782" class="icon" viewBox="0 0 1418 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8708" width="44.3125" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M491.191709 1023.803077L0.136305 539.63733l111.888035-110.273886 379.167369 373.89186L1305.549204 0.433064 1417.437238 110.706951 491.191709 1023.803077z" p-id="8709" fill="#12c53d"></path></svg>
|
||||
|
After Width: | Height: | Size: 531 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709907392895" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9700" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M512 32C246.4 32 32 246.4 32 512s214.4 480 480 480 480-214.4 480-480S777.6 32 512 32z m160 566.4c19.2 19.2 19.2 51.2 0 73.6-19.2 19.2-51.2 19.2-73.6 0L512 585.6 425.6 672c-19.2 19.2-51.2 19.2-73.6 0-19.2-19.2-19.2-51.2 0-73.6l86.4-86.4-86.4-86.4c-19.2-19.2-19.2-51.2 0-73.6 19.2-19.2 51.2-19.2 73.6 0l86.4 86.4 86.4-86.4c19.2-19.2 51.2-19.2 73.6 0 19.2 19.2 19.2 51.2 0 73.6L585.6 512l86.4 86.4z" p-id="9701" fill="#d4237a"></path></svg>
|
||||
|
After Width: | Height: | Size: 768 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709907148592" class="icon" viewBox="0 0 1410 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4262" width="66.09375" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M385.420696 906.172765L1004.039509 20.583293a47.214703 47.214703 0 0 1 44.414648-20.276253c18.634842 1.448304 31.766129 10.524341 39.297309 27.035004a49.049221 49.049221 0 0 1-3.76559 49.145774L435.242346 1001.278045a49.531989 49.531989 0 0 1-31.669576 20.276253 44.800863 44.800863 0 0 1-36.207594-8.207055L18.806738 752.362906a48.469899 48.469899 0 0 1-18.05552-31.669576 47.311256 47.311256 0 0 1 9.076037-36.207594 44.028434 44.028434 0 0 1 31.669575-18.924502 49.918203 49.918203 0 0 1 36.207594 9.848465l307.716272 230.763066z m686.495982-461.622685a47.021595 47.021595 0 0 1-34.75929-13.517502 47.021595 47.021595 0 0 1-13.517502-34.75929c0-14.096823 4.441465-25.683253 13.517502-34.75929a47.021595 47.021595 0 0 1 34.75929-13.517502h289.660752c14.096823 0 25.5867 4.441465 34.75929 13.517502 8.979483 9.076037 13.517502 20.662467 13.517502 34.75929a47.021595 47.021595 0 0 1-13.517502 34.75929 47.021595 47.021595 0 0 1-34.75929 13.517502h-289.660752z m-193.107168 289.660752a47.021595 47.021595 0 0 1-34.75929-13.517502 47.021595 47.021595 0 0 1-13.517502-34.75929c0-14.096823 4.441465-25.683253 13.517502-34.75929a47.021595 47.021595 0 0 1 34.75929-13.517502h482.76792c14.096823 0 25.5867 4.441465 34.75929 13.517502 8.979483 9.076037 13.517502 20.662467 13.517502 34.75929a47.021595 47.021595 0 0 1-13.517502 34.75929 47.021595 47.021595 0 0 1-34.75929 13.517502h-482.76792z m-193.107168 289.660752a47.021595 47.021595 0 0 1-34.75929-13.517502 47.021595 47.021595 0 0 1-13.517502-34.75929c0-14.096823 4.441465-25.683253 13.517502-34.75929a47.021595 47.021595 0 0 1 34.75929-13.517502h675.875088c14.096823 0 25.5867 4.441465 34.75929 13.517502 8.979483 9.076037 13.517502 20.662467 13.517502 34.75929a47.021595 47.021595 0 0 1-13.517502 34.75929 47.021595 47.021595 0 0 1-34.75929 13.517502h-675.875088z" p-id="4263" fill="#8a8a8a"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709907302076" class="icon" viewBox="0 0 1026 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7483" width="48.09375" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M123.252 739.482L406.85 455.885l-60.34-60.34-287.64 287.64c-30.893 30.894-31.708 80.946-0.814 111.84l177.279 177.278c30.863 30.864 80.945 30.08 111.84-0.814l287.609-287.61-60.34-60.34-283.597 283.597-167.654-167.654z" p-id="7484" fill="#8a8a8a"></path><path d="M717.75 223.245l65.107-65.348 122.58 121.374-62.331 62.572-109.064 44.56a81.444 81.444 0 0 0-27.274 18.404L562.013 553.183l61.064 59.616 144.122-147.742 109.034-44.531a80.337 80.337 0 0 0 26.67-17.8l123.364-123.848-243.863-241.45L656.686 163.69c-7.452 7.452-13.365 16.382-17.408 26.097l-44.56 107.616-136.972 137.574 60.46 60.22 137.605-138.209c7.482-7.482 13.366-16.382 17.438-26.127l44.47-107.646z" p-id="7485" fill="#8a8a8a"></path><path d="M351.156 295.623L746.713 691.18q30.17 30.17 0 60.34t-60.34 0L290.816 355.962q-30.17-30.17 0-60.34t60.34 0zM222.24 728.35a42.667 42.667 0 0 1 60.31 1.055l24.739 25.584a42.667 42.667 0 0 1-61.366 59.254l-24.74-25.644a42.624 42.624 0 0 1 1.027-60.28z" p-id="7486" fill="#8a8a8a"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709907338992" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8608" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M832 0H192C85.952 0 0 86.016 0 192v640a192 192 0 0 0 192 192h640a192 192 0 0 0 192-192V192c0-105.984-85.952-192-192-192z m64 832c0 35.392-28.608 64-64 64H192a64 64 0 0 1-64-64V192c0-35.328 28.672-64 64-64h640a64 64 0 0 1 64 64v640zM669.376 330.88L443.136 557.12l-90.56-90.496c-24.96-25.024-65.472-25.024-90.496 0s-25.024 65.536 0 90.496l135.808 135.744a63.936 63.936 0 0 0 90.496 0l271.488-271.488c25.024-25.024 25.024-65.472 0-90.496s-65.472-25.024-90.496 0z" p-id="8609" fill="#12c53d"></path></svg>
|
||||
|
After Width: | Height: | Size: 832 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1710232513408" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4296" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24"><path d="M816.672 937.344c-8.192 0-16.384-3.136-22.624-9.376l-213.952-213.952c-12.512-12.512-12.512-32.736 0-45.248s32.736-12.512 45.248 0l191.328 191.328 33.408-33.376-190.848-190.848c-12.512-12.512-12.512-32.736 0-45.248s32.736-12.512 45.248 0l213.472 213.472c6.016 6.016 9.376 14.112 9.376 22.624s-3.36 16.64-9.376 22.624l-78.656 78.624C833.024 934.208 824.832 937.344 816.672 937.344z" fill="#5C636E" p-id="4297"></path><path d="M590.752 128c0-0.032 0-0.064 0-0.064 1.472-4.16 2.048-8.352 1.792-12.512 0 0 0 0 0 0 0 0-0.032-0.064-0.032-0.096-0.256-4.128-1.312-8.096-3.104-11.776-0.352-0.704-0.896-1.248-1.28-1.92-1.632-2.848-3.456-5.472-5.952-7.712-0.928-0.864-2.08-1.376-3.136-2.112-1.92-1.376-3.616-3.008-5.888-3.968-0.608-0.256-1.248-0.384-1.888-0.608-0.032 0-0.064-0.032-0.096-0.032-114.144-46.624-243.808-20.704-331.072 66.592C239.328 154.528 239.04 155.584 238.336 156.416 237.472 157.12 236.448 157.408 235.648 158.208L73.664 319.552c-6.016 6.016-9.408 14.144-9.408 22.656s3.36 16.64 9.376 22.656l98.304 98.304c6.016 6.016 14.144 9.376 22.624 9.376s16.64-3.36 22.624-9.376l56.032-56.032 68.192 68.224c6.24 6.24 14.432 9.376 22.624 9.376s16.384-3.136 22.624-9.376c12.512-12.48 12.512-32.736 0-45.248l-90.816-90.848c-12.512-12.512-32.736-12.512-45.248 0L194.56 395.296l-52.992-53.024 139.264-138.72c0.832-0.8 1.12-1.888 1.824-2.752 0.864-0.704 1.92-0.992 2.72-1.824 40-39.936 91.296-63.072 144.864-68.768-2.208 1.664-4.384 3.392-6.56 5.12-8.96 6.784-17.632 14.016-25.664 22.048-0.544 0.544-0.736 1.248-1.216 1.824-19.232 19.36-35.936 41.024-49.568 64.512-2.464 4.224-4.768 8.448-7.008 12.736l0.416 0.224c-12.288 24.64-12.288 53.664 0.48 78.144 1.536 2.944 3.52 5.504 5.76 7.744 0.768 0.96 1.088 2.112 1.984 2.976l70.432 70.464c6.24 6.24 14.432 9.376 22.624 9.376s16.384-3.136 22.624-9.376c12.512-12.48 12.512-32.736 0-45.248l-67.072-67.072c-2.624-6.112-2.688-13.024 0.448-18.976 0.16-0.288 0.128-0.608 0.256-0.896 1.44-2.656 2.848-5.344 4.384-7.968 11.008-18.944 24.48-36.448 40.064-52.032 4.096-4.096 8.608-7.648 12.96-11.456 30.144-25.28 67.232-40.864 106.816-43.136 0.576-0.032 1.056-0.352 1.632-0.416 3.616-0.384 7.104-1.184 10.368-2.72 0.512-0.256 0.896-0.64 1.376-0.896 3.168-1.696 6.048-3.776 8.512-6.496 0.256-0.288 0.384-0.64 0.608-0.928 2.08-2.464 4.128-4.928 5.44-8.064C590.624 129.12 590.528 128.544 590.752 128z" fill="#5C636E" p-id="4298"></path><path d="M289.536 960.032c-28.384 0-56.928-6.368-82.624-18.432-9.408-4.448-16.096-13.184-17.888-23.456-1.792-10.24 1.504-20.736 8.896-28.128l88.064-88.096-33.056-33.024-87.52 87.488c-7.424 7.424-18.048 10.848-28.384 8.832-10.336-1.888-19.104-8.704-23.392-18.304-32.736-72.64-17.088-159.072 38.944-215.104 50.048-50.08 126.048-68.384 193.952-47.04l238.688-238.72c-21.28-67.712-3.648-143.264 47.04-193.952 36.128-36.16 84.256-56.064 135.456-56.064 27.264 0 54.816 5.92 79.648 17.12 9.568 4.32 16.448 13.056 18.304 23.392 1.92 10.336-1.408 20.96-8.832 28.384l-88.8 88.8 33.024 33.056 89.376-89.344c7.392-7.392 17.92-10.72 28.128-8.896 10.272 1.792 19.04 8.48 23.456 17.888 34.496 73.376 19.424 160.96-37.536 217.92-36.096 36.096-84.128 56-135.296 56-20.704 0-41.536-3.392-61.216-9.952l-237.12 237.12c22.688 68.48 5.44 145.024-46.048 196.544C388.736 940.16 340.672 960.032 289.536 960.032zM282.592 895.84c36.352 2.112 71.36-11.392 96.992-37.024 37.952-37.952 47.936-96.384 24.864-145.408-5.76-12.224-3.232-26.72 6.336-36.256l266.816-266.848c9.536-9.536 24.032-12.032 36.256-6.336 47.936 22.56 108 12.544 145.408-24.864 25.952-25.92 38.784-61.408 36.992-96.96l-72.576 72.544c-6.016 6.016-14.112 9.376-22.624 9.376l0 0c-8.512 0-16.64-3.36-22.624-9.376L700.16 276.416c-12.512-12.512-12.512-32.736 0-45.248l71.04-71.04c-35.072-0.896-68.8 12.384-93.696 37.28-37.92 37.92-48.064 94.272-25.856 143.552 5.44 12.128 2.848 26.368-6.56 35.776l-267.936 267.968c-9.376 9.376-23.648 11.936-35.776 6.56-47.68-21.504-106.624-11.104-143.584 25.856-25.504 25.536-38.464 59.392-37.408 93.856l69.92-69.92c12.512-12.512 32.736-12.512 45.248 0l78.304 78.272c6.016 6.016 9.376 14.112 9.376 22.624 0 8.48-3.36 16.64-9.376 22.624L282.592 895.84z" fill="#5C636E" p-id="4299"></path></svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 50 KiB |
@@ -0,0 +1 @@
|
||||
export type FixStatus = 1 | 2 | 3 | 4 | 5;
|
||||
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
component: true,
|
||||
};
|
||||
@@ -0,0 +1,155 @@
|
||||
import { View } from '@tarojs/components';
|
||||
import { Component, ReactNode } from 'react';
|
||||
import Taro from '@tarojs/taro';
|
||||
import {
|
||||
ShowElements,
|
||||
TicketInfo,
|
||||
TicketNote,
|
||||
} from '@/pages/TicketDetail/TicketNote';
|
||||
import pt from '@/plain-text';
|
||||
import { RequestState } from '@/service';
|
||||
import { getTicketInfo } from '@/service/ticketsInfo';
|
||||
import { FixStatus } from '@/common';
|
||||
import { AtCard, AtSteps } from 'taro-ui';
|
||||
import NoteList from '../NoteList/NoteList';
|
||||
|
||||
interface StepItemData {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const mapStatusStep: Map<FixStatus, 0 | 1 | 2 | 3> = new Map([
|
||||
[1, 0],
|
||||
[2, 1],
|
||||
[3, 2],
|
||||
[4, 2],
|
||||
[5, 3],
|
||||
]);
|
||||
|
||||
interface DetailFrameworkState {
|
||||
current: number;
|
||||
items: Array<StepItemData>;
|
||||
ticketInfo: TicketInfo;
|
||||
notes: Array<TicketNote>;
|
||||
rs: RequestState;
|
||||
}
|
||||
|
||||
interface DetailFrameworkProps {
|
||||
middleButton: JSX.Element;
|
||||
id: number;
|
||||
isInfoShow: { [key: string]: boolean };
|
||||
}
|
||||
|
||||
export default class DetailFramework extends Component<
|
||||
DetailFrameworkProps,
|
||||
DetailFrameworkState
|
||||
> {
|
||||
state = {
|
||||
current: 0,
|
||||
items: [],
|
||||
ticketInfo: new TicketInfo(),
|
||||
notes: [new TicketNote()],
|
||||
rs: new RequestState(),
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
const navBar = pt.get().navBar;
|
||||
Taro.setNavigationBarTitle({
|
||||
title: navBar.ticketDetail,
|
||||
});
|
||||
getTicketInfo(this, this.props.id);
|
||||
}
|
||||
|
||||
props: Readonly<DetailFrameworkProps> = {
|
||||
middleButton: <View></View>,
|
||||
id: 0,
|
||||
isInfoShow: {
|
||||
device: true,
|
||||
createdTime: true,
|
||||
description: true,
|
||||
current: true,
|
||||
notelist: true,
|
||||
showAllNotes: true,
|
||||
},
|
||||
};
|
||||
|
||||
render(): ReactNode {
|
||||
if (this.state.rs.loading) {
|
||||
return <View>Loading</View>;
|
||||
} else if (!this.state.rs.success) {
|
||||
return <View>Request failed</View>;
|
||||
}
|
||||
|
||||
const status = this.state.ticketInfo.status;
|
||||
this.setState({
|
||||
current: mapStatusStep.get(status) || 0,
|
||||
items: pt.get().ticketDetail.stepItems,
|
||||
});
|
||||
|
||||
const elements: ShowElements = {
|
||||
device: this.props.isInfoShow['device'] ? (
|
||||
<View className='at-article__h1'>
|
||||
{this.state.ticketInfo.device +
|
||||
' ' +
|
||||
this.state.ticketInfo.deviceModel}
|
||||
</View>
|
||||
) : (
|
||||
<View></View>
|
||||
),
|
||||
createdTime: this.props.isInfoShow['createdTime'] ? (
|
||||
<View className='at-article__info'>
|
||||
{pt.get().common.createdAtText(this.state.ticketInfo.createdTime)}
|
||||
</View>
|
||||
) : (
|
||||
<View></View>
|
||||
),
|
||||
description: this.props.isInfoShow['description'] ? (
|
||||
<View style={{ marginTop: 10, marginBottom: 10 }}>
|
||||
<AtCard title={pt.get().ticketDetail.descTitle}>
|
||||
<View className='at-article__h3'>
|
||||
{this.state.ticketInfo.description}
|
||||
</View>
|
||||
</AtCard>
|
||||
</View>
|
||||
) : (
|
||||
<View></View>
|
||||
),
|
||||
current: this.props.isInfoShow['current'] ? (
|
||||
<View style={{ padding: 10 }}>
|
||||
<AtSteps
|
||||
items={this.state.items}
|
||||
current={this.state.current}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<View></View>
|
||||
),
|
||||
notelist: this.props.isInfoShow['notelist'] ? (
|
||||
this.props.isInfoShow['showAllNotes'] ? (
|
||||
<View style={{ padding: 10 }}>
|
||||
<NoteList noteList={this.state.notes} />
|
||||
</View>
|
||||
) : (
|
||||
<View style={{ padding: 10 }}>
|
||||
<NoteList
|
||||
noteList={[this.state.notes[this.state.notes.length - 1]]}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
) : (
|
||||
<View></View>
|
||||
),
|
||||
};
|
||||
|
||||
return (
|
||||
<View>
|
||||
{elements.device}
|
||||
{elements.createdTime}
|
||||
{elements.description}
|
||||
{elements.current}
|
||||
{this.props.middleButton}
|
||||
{elements.notelist}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
component: true,
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
import { View } from '@tarojs/components';
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { TicketNote, StatusStr } from '@/pages/TicketDetail/TicketNote';
|
||||
import pt from '@/plain-text';
|
||||
import { timeFormat } from '@/utils';
|
||||
import { AtDivider } from 'taro-ui';
|
||||
import './NoteCard.scss';
|
||||
|
||||
interface NoteCardProps {
|
||||
note: TicketNote;
|
||||
}
|
||||
|
||||
export default class NoteCard extends Component<NoteCardProps, {}> {
|
||||
props: Readonly<NoteCardProps> = {
|
||||
note: new TicketNote(),
|
||||
};
|
||||
|
||||
render(): ReactNode {
|
||||
var message = '';
|
||||
const note = this.props.note;
|
||||
const td = pt.get().ticketDetail;
|
||||
const createMessage = td.createTicketMessage;
|
||||
const modifyMessage = td.statusModifyMessage;
|
||||
const prefix = td.statusModifyPrefix;
|
||||
|
||||
switch (note.type) {
|
||||
case 0:
|
||||
message = createMessage;
|
||||
break;
|
||||
case 1:
|
||||
message = note.content;
|
||||
break;
|
||||
case 2:
|
||||
message = prefix + modifyMessage.get(note.content as StatusStr) || '';
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View className='at-article__h2'>{note.op}</View>
|
||||
<View className='at-article__info'>
|
||||
{note.createdTime.format(timeFormat)}
|
||||
</View>
|
||||
<View className='at-article__p'>{message}</View>
|
||||
<AtDivider />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
component: true,
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Component, ReactNode } from 'react';
|
||||
import NoteCard from '@/components/NoteCard/NoteCard';
|
||||
import { TicketNote } from '@/pages/TicketDetail/TicketNote';
|
||||
import { View } from '@tarojs/components';
|
||||
|
||||
interface NoteListProps {
|
||||
noteList: Array<TicketNote>;
|
||||
}
|
||||
|
||||
export default class NoteList extends Component<NoteListProps, {}> {
|
||||
props: Readonly<NoteListProps> = {
|
||||
noteList: [],
|
||||
};
|
||||
render(): ReactNode {
|
||||
return (
|
||||
<View>
|
||||
{this.props.noteList.map((note, idx) => (
|
||||
<View key={idx}>
|
||||
<NoteCard note={note} />
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
component: true,
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import { AtDivider } from 'taro-ui';
|
||||
import pt from '@/plain-text';
|
||||
|
||||
export default () => {
|
||||
const blankHeightUpper = 15;
|
||||
const blankHeightLower = 110;
|
||||
return (
|
||||
<View>
|
||||
<View style={{ height: blankHeightUpper }}></View>
|
||||
<View>
|
||||
<AtDivider
|
||||
content={pt.get().pageFooter.dividerText}
|
||||
fontColor='#dddddd'
|
||||
lineColor='#dddddd'
|
||||
/>
|
||||
</View>
|
||||
<View className='at-row at-row__justify--center'>
|
||||
<Text style='color:#dddddd;'>© 2024 EVA Tech</Text>
|
||||
</View>
|
||||
<View style={{ height: blankHeightLower }}></View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
component: true,
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
import { AtListItem } from 'taro-ui';
|
||||
import repair from '@/assets/icons/MyTickets/repair.svg';
|
||||
import finished from '@/assets/icons/MyTickets/finished.svg';
|
||||
import tick from '@/assets/icons/MyTickets/tick.svg';
|
||||
import fail from '@/assets/icons/MyTickets/fail.svg';
|
||||
import pt from '@/plain-text';
|
||||
import Taro from '@tarojs/taro';
|
||||
|
||||
type FixStatus = 1 | 2 | 3 | 4 | 5;
|
||||
|
||||
export class TicketListItem {
|
||||
id: number;
|
||||
brand: string;
|
||||
model: string;
|
||||
status: FixStatus;
|
||||
createAt: moment.Moment;
|
||||
iconMap: Map<FixStatus, string>;
|
||||
|
||||
constructor(
|
||||
id: number,
|
||||
brand: string,
|
||||
model: string,
|
||||
status: FixStatus,
|
||||
createAt: moment.Moment,
|
||||
) {
|
||||
this.id = id;
|
||||
this.brand = brand;
|
||||
this.model = model;
|
||||
this.status = status;
|
||||
this.createAt = createAt;
|
||||
this.iconMap = new Map<FixStatus, string>([
|
||||
[1, repair],
|
||||
[2, repair],
|
||||
[3, finished],
|
||||
[4, tick],
|
||||
[5, fail],
|
||||
]);
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
const tl = pt.get().ticketList;
|
||||
return (
|
||||
<AtListItem
|
||||
title={this.brand + ' ' + this.model}
|
||||
note={tl.createdAt(this.createAt.format('YYYY-MM-DD HH:mm'))}
|
||||
extraText={tl.statusMap.get(this.status)}
|
||||
arrow='right'
|
||||
thumb={this.iconMap.get(this.status)}
|
||||
onClick={() => {
|
||||
Taro.navigateTo({
|
||||
url: '/pages/TicketDetail/TicketDetail?id=' + this.id,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
component: true,
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
@import '~taro-ui/dist/style/components/tab-bar.scss';
|
||||
@import '~taro-ui/dist/style/components/badge.scss';
|
||||
@import '~taro-ui/dist/style/components/icon.scss';
|
||||
@@ -0,0 +1,91 @@
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { AtTabBar } from 'taro-ui';
|
||||
import Taro from '@tarojs/taro';
|
||||
import pt from '@/plain-text';
|
||||
import wechatUser from '@/wechat';
|
||||
import 'taro-ui/dist/style/index.scss';
|
||||
import './index.scss';
|
||||
|
||||
const navList: Array<Taro.TabBarItem> = [
|
||||
{
|
||||
pagePath: '/pages/index/index',
|
||||
text: pt.get().tabBar.indexText,
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/repair/repair',
|
||||
text: pt.get().tabBar.repairText,
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/member/member',
|
||||
text: pt.get().tabBar.memberText,
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/user/user',
|
||||
text: pt.get().tabBar.userText,
|
||||
},
|
||||
];
|
||||
|
||||
export default class Index extends Component {
|
||||
state = {
|
||||
selected: 0,
|
||||
tabList: wechatUser.getAccess()
|
||||
? [
|
||||
{
|
||||
title: pt.get().tabBar.indexText,
|
||||
iconType: 'home',
|
||||
},
|
||||
{
|
||||
title: pt.get().tabBar.repairText,
|
||||
iconType: 'settings',
|
||||
},
|
||||
{
|
||||
title: pt.get().tabBar.memberText,
|
||||
iconType: 'sketch',
|
||||
},
|
||||
{
|
||||
title: pt.get().tabBar.userText,
|
||||
iconType: 'user',
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: pt.get().tabBar.indexText,
|
||||
iconType: 'home',
|
||||
},
|
||||
{
|
||||
title: pt.get().tabBar.repairText,
|
||||
iconType: 'settings',
|
||||
},
|
||||
{
|
||||
title: pt.get().tabBar.userText,
|
||||
iconType: 'user',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
handleClick(idx: number) {
|
||||
this.switchTab(idx, navList[idx].pagePath);
|
||||
}
|
||||
|
||||
switchTab(idx: number, url: string) {
|
||||
this.setSelected(idx);
|
||||
Taro.switchTab({ url });
|
||||
}
|
||||
|
||||
setSelected(idx: number) {
|
||||
this.setState({
|
||||
selected: idx,
|
||||
});
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
return (
|
||||
<AtTabBar
|
||||
fixed
|
||||
tabList={this.state.tabList}
|
||||
onClick={this.handleClick.bind(this)}
|
||||
current={this.state.selected}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-touch-fullscreen" content="yes">
|
||||
<meta name="format-detection" content="telephone=no,address=no">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="white">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" >
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
||||
<meta
|
||||
content="width=device-width,initial-scale=1,user-scalable=no"
|
||||
name="viewport"
|
||||
/>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-touch-fullscreen" content="yes" />
|
||||
<meta name="format-detection" content="telephone=no,address=no" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="white" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<title>EVA-Notify</title>
|
||||
<script><%= htmlWebpackPlugin.options.script %></script>
|
||||
<script>
|
||||
<%= htmlWebpackPlugin.options.script %>
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
usingComponents: {},
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { View } from '@tarojs/components';
|
||||
import { getCurrentInstance } from '@tarojs/runtime';
|
||||
import pt from '@/plain-text';
|
||||
import { AtButton } from 'taro-ui';
|
||||
import DetailFramework from '@/components/DetailFramework/DetailFramework';
|
||||
import PageFooter from '@/components/PageFooter/PageFooter';
|
||||
|
||||
interface TicketDetailState {
|
||||
id: number;
|
||||
}
|
||||
|
||||
export default class TicketDetail extends Component<{}, TicketDetailState> {
|
||||
state: Readonly<TicketDetailState> = {
|
||||
id: 0,
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
const { router } = getCurrentInstance();
|
||||
const id = router?.params.id as number;
|
||||
this.setState({
|
||||
id: id,
|
||||
});
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
const middleButton = (
|
||||
<View
|
||||
className='at-row'
|
||||
style={{ paddingTop: 10, paddingBottom: 10, width: '100%' }}
|
||||
>
|
||||
<View
|
||||
className='at-col'
|
||||
style={{ marginLeft: 10, paddingRight: 5, width: '50%' }}
|
||||
>
|
||||
<AtButton type='primary'>{pt.get().ticketDetail.tookAway}</AtButton>
|
||||
</View>
|
||||
<View
|
||||
className='at-col'
|
||||
style={{ marginRight: 10, paddingLeft: 5, width: '50%' }}
|
||||
>
|
||||
<AtButton type='secondary'>{pt.get().ticketDetail.addNote}</AtButton>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
const isInfoShow = {
|
||||
device: true,
|
||||
createdTime: true,
|
||||
description: true,
|
||||
current: true,
|
||||
notelist: true,
|
||||
showAllNotes: true,
|
||||
};
|
||||
|
||||
return (
|
||||
<View>
|
||||
<DetailFramework
|
||||
middleButton={middleButton}
|
||||
id={this.state.id}
|
||||
isInfoShow={isInfoShow}
|
||||
/>
|
||||
<PageFooter />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { FixStatus } from '@/common';
|
||||
|
||||
export class TicketInfo {
|
||||
id: number;
|
||||
type: 0 | 1;
|
||||
device: string;
|
||||
deviceModel: string;
|
||||
description: string;
|
||||
createdTime: moment.Moment;
|
||||
status: FixStatus;
|
||||
}
|
||||
|
||||
export class TicketNote {
|
||||
id: number;
|
||||
op: string;
|
||||
type: 0 | 1 | 2;
|
||||
content: string;
|
||||
createdTime: moment.Moment;
|
||||
}
|
||||
|
||||
export class ShowElements {
|
||||
device: JSX.Element;
|
||||
createdTime: JSX.Element;
|
||||
description: JSX.Element;
|
||||
current: JSX.Element;
|
||||
notelist: JSX.Element;
|
||||
}
|
||||
|
||||
export type StatusStr = '1' | '2' | '3' | '4' | '5';
|
||||
@@ -0,0 +1,108 @@
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { View, Image } from '@tarojs/components';
|
||||
import { AtTimeline } from 'taro-ui';
|
||||
import pt from '@/plain-text';
|
||||
import tick from '@/assets/icons/MainPage/tick.svg';
|
||||
import cross from '@/assets/icons/MainPage/cross.svg';
|
||||
|
||||
export class DutyData {
|
||||
constructor() {
|
||||
this.isInDuty = false;
|
||||
this.inDutyCnt = 3;
|
||||
this.currentDuty = '2';
|
||||
this.offDutyReason = '学园维修';
|
||||
this.dutyRecoverTime = '下周一';
|
||||
}
|
||||
|
||||
isInDuty: boolean;
|
||||
inDutyCnt?: number;
|
||||
currentDuty?: 'off' | '1' | '2' | '3';
|
||||
offDutyReason?: string;
|
||||
dutyRecoverTime?: string;
|
||||
}
|
||||
|
||||
class Card extends Component {
|
||||
props = {
|
||||
isInDuty: false,
|
||||
};
|
||||
render(): ReactNode {
|
||||
const inDuty = this.props.isInDuty;
|
||||
const dc = pt.get().mainPage.dutyCard;
|
||||
const title = inDuty ? dc.inDuty.title : dc.offDuty.title;
|
||||
const iconsrc = inDuty ? tick : cross;
|
||||
return (
|
||||
<View>
|
||||
<View
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginBottom: 20,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={iconsrc}
|
||||
style={{
|
||||
width: 24,
|
||||
height: 24,
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
fontSize: 30,
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class DutyInfo extends Component {
|
||||
props = {
|
||||
data: new DutyData(),
|
||||
};
|
||||
|
||||
offDutyContent(): ReactNode {
|
||||
const data = this.props.data;
|
||||
const od = pt.get().mainPage.dutyCard.offDuty;
|
||||
return (
|
||||
<View>
|
||||
<Card isInDuty={data.isInDuty} />
|
||||
<AtTimeline
|
||||
items={[
|
||||
{ title: od.reason(data.offDutyReason as string) },
|
||||
{ title: od.recoverTime(data.dutyRecoverTime as string) },
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
inDutyContent(): ReactNode {
|
||||
const data = this.props.data;
|
||||
const id = pt.get().mainPage.dutyCard.inDuty;
|
||||
return (
|
||||
<View>
|
||||
<Card isInDuty={data.isInDuty} />
|
||||
<AtTimeline
|
||||
items={[
|
||||
{ title: id.currentDutyText(data.currentDuty || 'off') },
|
||||
{ title: id.inDutyCnt(data.inDutyCnt as number) },
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
if (this.props.data.isInDuty) {
|
||||
return this.inDutyContent();
|
||||
} else {
|
||||
return this.offDutyContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { View } from '@tarojs/components';
|
||||
import { AtTimeline } from 'taro-ui';
|
||||
import pt from '@/plain-text';
|
||||
|
||||
export class StepInfo extends Component {
|
||||
render(): ReactNode {
|
||||
return (
|
||||
<View>
|
||||
<AtTimeline items={pt.get().mainPage.stepList}></AtTimeline>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class TipsInfo extends Component {
|
||||
render(): ReactNode {
|
||||
return (
|
||||
<View>
|
||||
<AtTimeline items={pt.get().mainPage.tipsList}></AtTimeline>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { View, Image } from '@tarojs/components';
|
||||
import pt from '@/plain-text';
|
||||
import logo from '@/assets/images/UserPage/logo.png';
|
||||
|
||||
export default class TitleCard extends React.Component {
|
||||
render(): React.ReactNode {
|
||||
const mainPage = pt.get().mainPage;
|
||||
return (
|
||||
<View className='at-row at-row__align--center'>
|
||||
<View className='at-col at-col-1 at-col--auto'>
|
||||
<Image
|
||||
style='width: 50px; height: 50px; margin-left: 15px;'
|
||||
src={logo}
|
||||
mode='aspectFit'
|
||||
/>
|
||||
</View>
|
||||
<View className='page-title'>
|
||||
<View className='at-article__h1' style={{ fontWeight: 'bold' }}>
|
||||
{mainPage.mainTitleLine}
|
||||
</View>
|
||||
<View className='at-article__h2'>{mainPage.subTitleLine}</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '首页'
|
||||
})
|
||||
usingComponents: {},
|
||||
});
|
||||
|
||||
@@ -1,16 +1,120 @@
|
||||
import { View, Text } from '@tarojs/components'
|
||||
import { useLoad } from '@tarojs/taro'
|
||||
import './index.scss'
|
||||
import { View } from '@tarojs/components';
|
||||
import { Component, ReactNode } from 'react';
|
||||
import Taro from '@tarojs/taro';
|
||||
import { AtCard, AtAccordion } from 'taro-ui';
|
||||
import type CustomTabBar from '@/custom-tab-bar';
|
||||
import PageFooter from '@/components/PageFooter/PageFooter';
|
||||
import pt from '@/plain-text';
|
||||
import { getDutyInfo } from '@/service/dutyInfo';
|
||||
import './index.scss';
|
||||
import TitleCard from './TitleCard';
|
||||
import { DutyInfo, DutyData } from './DutyInfo';
|
||||
import { StepInfo, TipsInfo } from './StepTipsInfo';
|
||||
|
||||
export default function Index() {
|
||||
class CardContent {
|
||||
title: string;
|
||||
note: string;
|
||||
extra: JSX.Element | string;
|
||||
content: () => JSX.Element;
|
||||
}
|
||||
|
||||
useLoad(() => {
|
||||
console.log('Page loaded.')
|
||||
})
|
||||
function mainPageCard(c: CardContent): JSX.Element {
|
||||
return (
|
||||
<View style={{ marginTop: 10 }}>
|
||||
<AtCard note={c.note} extra={c.extra} title={c.title}>
|
||||
{c.content()}
|
||||
</AtCard>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
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 {
|
||||
dutyData: DutyData;
|
||||
dutyInfoCard: CardContent;
|
||||
stepInfoCard: CardContent;
|
||||
tipsInfoCard: CardContent;
|
||||
//rs: RequestState;
|
||||
}
|
||||
|
||||
export default class MainPage extends Component<{}, MainPageState> {
|
||||
state = {
|
||||
dutyData: new DutyData(),
|
||||
dutyInfoCard: {
|
||||
title: pt.get().mainPage.cardTitle.dutyInfo,
|
||||
note: pt.get().mainPage.cardTips.dutyInfo,
|
||||
extra: pt.get().mainPage.extraInfo.dutyInfo,
|
||||
content: () => <DutyInfo data={this.state.dutyData} />,
|
||||
},
|
||||
stepInfoCard: {
|
||||
title: pt.get().mainPage.cardTitle.stepInfo,
|
||||
note: pt.get().mainPage.cardTips.stepInfo,
|
||||
extra: pt.get().mainPage.extraInfo.dutyInfo,
|
||||
content: () => <StepInfo />,
|
||||
},
|
||||
tipsInfoCard: {
|
||||
title: pt.get().mainPage.cardTitle.tipsInfo,
|
||||
note: pt.get().mainPage.cardTips.tipsInfo,
|
||||
extra: pt.get().mainPage.extraInfo.dutyInfo,
|
||||
content: () => <TipsInfo />,
|
||||
},
|
||||
// rs: new RequestState(),
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
getDutyInfo(this);
|
||||
}
|
||||
|
||||
// 以下是TabBar相关
|
||||
pageCtx = Taro.getCurrentInstance().page;
|
||||
componentDidShow() {
|
||||
const tabbar = Taro.getTabBar<CustomTabBar>(this.pageCtx);
|
||||
tabbar?.setSelected(0);
|
||||
}
|
||||
// 以上是TabBar相关
|
||||
|
||||
render(): ReactNode {
|
||||
const mainPage = pt.get().mainPage;
|
||||
return (
|
||||
<View className='index'>
|
||||
<Text>Hello world!</Text>
|
||||
<View>
|
||||
<TitleCard />
|
||||
<View style={{ marginTop: 30 }}>
|
||||
{mainPageCard(this.state.dutyInfoCard)}
|
||||
{mainPageCard(this.state.tipsInfoCard)}
|
||||
<ExpandItem
|
||||
title={mainPage.expandTitle.stepInfo}
|
||||
content={mainPageCard(this.state.stepInfoCard)}
|
||||
/>
|
||||
</View>
|
||||
<PageFooter />
|
||||
</View>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
usingComponents: {},
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import { Component, ReactNode } from 'react';
|
||||
import Taro from '@tarojs/taro';
|
||||
import type CustomTabBar from '../../custom-tab-bar';
|
||||
import './member.scss';
|
||||
|
||||
export default class MemberPage extends Component {
|
||||
// 以下是TabBar相关
|
||||
pageCtx = Taro.getCurrentInstance().page;
|
||||
componentDidShow() {
|
||||
const tabbar = Taro.getTabBar<CustomTabBar>(this.pageCtx);
|
||||
tabbar?.setSelected(2);
|
||||
}
|
||||
// 以上是TabBar相关
|
||||
|
||||
render(): ReactNode {
|
||||
return (
|
||||
<View>
|
||||
<Text>Member Page</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
usingComponents: {},
|
||||
});
|
||||
@@ -0,0 +1,262 @@
|
||||
import { View } from '@tarojs/components';
|
||||
import { Component, ReactNode } from 'react';
|
||||
import Taro from '@tarojs/taro';
|
||||
import {
|
||||
AtForm,
|
||||
AtInput,
|
||||
AtButton,
|
||||
AtCheckbox,
|
||||
AtCard,
|
||||
AtSegmentedControl,
|
||||
AtMessage,
|
||||
} from 'taro-ui';
|
||||
import pt from '@/plain-text';
|
||||
import PageFooter from '@/components/PageFooter/PageFooter';
|
||||
import { submitTicket } from '@/service/submitTicket';
|
||||
import type CustomTabBar from '@/custom-tab-bar';
|
||||
import repairLogo from '@/assets/icons/RepairPage/repair.svg';
|
||||
import DetailFramework from '@/components/DetailFramework/DetailFramework';
|
||||
import { getCurrentTicket } from '@/service/currentTicket';
|
||||
import './repair.scss';
|
||||
|
||||
interface RepairPageState {
|
||||
type: 0 | 1;
|
||||
device: string;
|
||||
deviceModel: string;
|
||||
owner: string;
|
||||
phone: string;
|
||||
description: string;
|
||||
isLoading: boolean;
|
||||
isDisable: boolean;
|
||||
checkedList: Array<number>;
|
||||
currentTicketsId: Array<number>;
|
||||
}
|
||||
|
||||
const submitInterval = 5000;
|
||||
|
||||
const middleButton = <View></View>;
|
||||
|
||||
const isInfoShow = {
|
||||
device: true,
|
||||
createdTime: true,
|
||||
description: false,
|
||||
current: true,
|
||||
notelist: true,
|
||||
showAllNotes: false,
|
||||
};
|
||||
|
||||
export default class RepairPage extends Component<{}, RepairPageState> {
|
||||
state = {
|
||||
type: 1 as 0 | 1,
|
||||
device: '',
|
||||
deviceModel: '',
|
||||
owner: '',
|
||||
phone: '',
|
||||
description: '',
|
||||
isLoading: false,
|
||||
isDisable: true,
|
||||
checkedList: [0],
|
||||
currentTicketsId: [] as Array<number>,
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
getCurrentTicket(this, middleButton, isInfoShow);
|
||||
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
isDisable: false,
|
||||
});
|
||||
}, submitInterval);
|
||||
}
|
||||
|
||||
// 以下是TabBar相关
|
||||
pageCtx = Taro.getCurrentInstance().page;
|
||||
componentDidShow() {
|
||||
const tabbar = Taro.getTabBar<CustomTabBar>(this.pageCtx);
|
||||
tabbar?.setSelected(1);
|
||||
}
|
||||
// 以上是TabBar相关
|
||||
|
||||
handleTypeChange(type: 0 | 1) {
|
||||
this.setState({
|
||||
type: type,
|
||||
});
|
||||
return type;
|
||||
}
|
||||
|
||||
handleDeviceChange(device: string) {
|
||||
this.setState({
|
||||
device: device,
|
||||
});
|
||||
return device;
|
||||
}
|
||||
|
||||
handleDeviceModelChange(deviceModel: string) {
|
||||
this.setState({
|
||||
deviceModel: deviceModel,
|
||||
});
|
||||
return deviceModel;
|
||||
}
|
||||
|
||||
handleOwnerChange(owner: string) {
|
||||
this.setState({
|
||||
owner: owner,
|
||||
});
|
||||
return owner;
|
||||
}
|
||||
|
||||
handlePhoneChange(phone: string) {
|
||||
this.setState({
|
||||
phone: phone,
|
||||
});
|
||||
return phone;
|
||||
}
|
||||
|
||||
handleDescriptionChange(description: string) {
|
||||
this.setState({
|
||||
description: description,
|
||||
});
|
||||
return description;
|
||||
}
|
||||
|
||||
checkboxOption = [
|
||||
{
|
||||
value: 0,
|
||||
label: pt.get().repairPage.checkboxText.none,
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: pt.get().repairPage.checkboxText.usbDisk,
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: pt.get().repairPage.checkboxText.mouseOrReceiver,
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: pt.get().repairPage.checkboxText.powerAdapter,
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: pt.get().repairPage.checkboxText.others.label,
|
||||
desc: pt.get().repairPage.checkboxText.others.desc,
|
||||
},
|
||||
];
|
||||
|
||||
handleCheckboxChange(checkedList: Array<number>) {
|
||||
this.setState({
|
||||
checkedList: checkedList,
|
||||
});
|
||||
return checkedList;
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
isDisable: true,
|
||||
});
|
||||
submitTicket(this);
|
||||
Taro.reLaunch({
|
||||
url: '/pages/repair/repair',
|
||||
});
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
const ticketsRenderer = this.state.currentTicketsId.map((id, idx) => (
|
||||
<AtCard key={idx}>
|
||||
<DetailFramework
|
||||
id={id}
|
||||
isInfoShow={isInfoShow}
|
||||
middleButton={middleButton}
|
||||
/>
|
||||
</AtCard>
|
||||
));
|
||||
console.log(ticketsRenderer);
|
||||
return (
|
||||
<View>
|
||||
<AtMessage />
|
||||
{ticketsRenderer}
|
||||
<AtCard
|
||||
note={pt.get().repairPage.cardText.note}
|
||||
title={pt.get().repairPage.cardText.title}
|
||||
thumb={repairLogo}
|
||||
>
|
||||
<AtForm onSubmit={this.onSubmit.bind(this)}>
|
||||
<AtSegmentedControl
|
||||
values={[
|
||||
pt.get().repairPage.typeText.appliance,
|
||||
pt.get().repairPage.typeText.computer,
|
||||
]}
|
||||
onClick={this.handleTypeChange.bind(this)}
|
||||
current={this.state.type}
|
||||
/>
|
||||
<AtInput
|
||||
clear
|
||||
required
|
||||
name='device'
|
||||
title={pt.get().repairPage.deviceText.title}
|
||||
type='text'
|
||||
placeholder={pt.get().repairPage.deviceText.placeholder}
|
||||
value={this.state.device}
|
||||
onChange={this.handleDeviceChange.bind(this)}
|
||||
/>
|
||||
<AtInput
|
||||
clear
|
||||
required
|
||||
name='deviceModel'
|
||||
title={pt.get().repairPage.deviceModelText.title}
|
||||
type='text'
|
||||
placeholder={pt.get().repairPage.deviceModelText.placeholder}
|
||||
value={this.state.deviceModel}
|
||||
onChange={this.handleDeviceModelChange.bind(this)}
|
||||
/>
|
||||
<AtInput
|
||||
clear
|
||||
required
|
||||
name='owner'
|
||||
title={pt.get().repairPage.ownerText.title}
|
||||
type='text'
|
||||
placeholder={pt.get().repairPage.ownerText.placeholder}
|
||||
value={this.state.owner}
|
||||
onChange={this.handleOwnerChange.bind(this)}
|
||||
/>
|
||||
<AtInput
|
||||
clear
|
||||
required
|
||||
name='phone'
|
||||
title={pt.get().repairPage.phoneText.title}
|
||||
type='number'
|
||||
placeholder={pt.get().repairPage.phoneText.placeholder}
|
||||
value={this.state.phone}
|
||||
onChange={this.handlePhoneChange.bind(this)}
|
||||
/>
|
||||
<AtInput
|
||||
clear
|
||||
required
|
||||
name='description'
|
||||
title={pt.get().repairPage.descriptionText.title}
|
||||
type='text'
|
||||
placeholder={pt.get().repairPage.descriptionText.placeholder}
|
||||
value={this.state.description}
|
||||
onChange={this.handleDescriptionChange.bind(this)}
|
||||
/>
|
||||
<AtCheckbox
|
||||
options={this.checkboxOption}
|
||||
selectedList={this.state.checkedList}
|
||||
onChange={this.handleCheckboxChange.bind(this)}
|
||||
/>
|
||||
<AtButton
|
||||
loading={this.state.isLoading}
|
||||
formType='submit'
|
||||
type='primary'
|
||||
disabled={this.state.isDisable}
|
||||
>
|
||||
{pt.get().button.buttonText.submit}
|
||||
</AtButton>
|
||||
</AtForm>
|
||||
</AtCard>
|
||||
<PageFooter />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
usingComponents: {},
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { View } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import pt from '@/plain-text';
|
||||
import './about.scss';
|
||||
|
||||
export default class AboutPage extends Component {
|
||||
componentDidMount(): void {
|
||||
Taro.setNavigationBarTitle({
|
||||
title: pt.get().navBar.user.about,
|
||||
});
|
||||
}
|
||||
render(): ReactNode {
|
||||
return <View></View>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
usingComponents: {},
|
||||
});
|
||||
@@ -0,0 +1,88 @@
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { AtForm, AtInput, AtButton, AtMessage } from 'taro-ui';
|
||||
import { View } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import pt from '@/plain-text';
|
||||
import { updateUserInfo } from '@/service/userData';
|
||||
import './inform.scss';
|
||||
|
||||
const submitInterval = 5000;
|
||||
|
||||
export default class InformPage extends Component {
|
||||
state = {
|
||||
phone: '',
|
||||
name: '',
|
||||
isLoading: false,
|
||||
isDisable: false,
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
Taro.setNavigationBarTitle({
|
||||
title: pt.get().navBar.user.inform,
|
||||
});
|
||||
}
|
||||
|
||||
handleChangePhone(phone: string) {
|
||||
this.setState({
|
||||
phone: phone,
|
||||
});
|
||||
return phone;
|
||||
}
|
||||
handleChangeName(name: string) {
|
||||
this.setState({
|
||||
name: name,
|
||||
});
|
||||
return name;
|
||||
}
|
||||
onSubmit() {
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
isDisable: true,
|
||||
});
|
||||
console.log(this.state.name, this.state.phone);
|
||||
updateUserInfo(this);
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
isDisable: false,
|
||||
});
|
||||
}, submitInterval);
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
return (
|
||||
<View>
|
||||
<AtForm onSubmit={this.onSubmit.bind(this)}>
|
||||
<AtMessage />
|
||||
<AtInput
|
||||
clear
|
||||
required
|
||||
name='phone'
|
||||
title={pt.get().informPage.phoneText.title}
|
||||
type='number'
|
||||
placeholder={pt.get().informPage.phoneText.placeholder}
|
||||
value={this.state.phone}
|
||||
onChange={this.handleChangePhone.bind(this)}
|
||||
/>
|
||||
<AtInput
|
||||
required
|
||||
clear
|
||||
name='name'
|
||||
title={pt.get().informPage.nameText.title}
|
||||
type='text'
|
||||
placeholder={pt.get().informPage.nameText.placeholder}
|
||||
value={this.state.name}
|
||||
onChange={this.handleChangeName.bind(this)}
|
||||
/>
|
||||
<AtButton
|
||||
loading={this.state.isLoading}
|
||||
formType='submit'
|
||||
type='primary'
|
||||
disabled={this.state.isDisable}
|
||||
>
|
||||
{pt.get().button.buttonText.submit}
|
||||
</AtButton>
|
||||
</AtForm>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
usingComponents: {},
|
||||
});
|
||||
@@ -0,0 +1,108 @@
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { AtForm, AtInput, AtButton, AtMessage } from 'taro-ui';
|
||||
import { getUrl } from '@/service';
|
||||
import Taro from '@tarojs/taro';
|
||||
import pt from '@/plain-text';
|
||||
import './member.scss';
|
||||
|
||||
const loginInterval = 5000;
|
||||
|
||||
export default class MemberPage extends Component {
|
||||
state = {
|
||||
stuid: '',
|
||||
passwd: '',
|
||||
isLoading: false,
|
||||
isDisable: false,
|
||||
};
|
||||
componentDidMount(): void {
|
||||
Taro.setNavigationBarTitle({
|
||||
title: pt.get().navBar.user.member,
|
||||
});
|
||||
}
|
||||
handleChangeStuid(stuid: string) {
|
||||
this.setState({
|
||||
stuid: stuid,
|
||||
});
|
||||
return stuid;
|
||||
}
|
||||
handleChangePasswd(passwd: string) {
|
||||
this.setState({
|
||||
passwd: passwd,
|
||||
});
|
||||
return passwd;
|
||||
}
|
||||
onSubmit() {
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
isDisable: true,
|
||||
});
|
||||
console.log([this.state.stuid, this.state.passwd]);
|
||||
Taro.request({
|
||||
url: getUrl('/member/login'),
|
||||
method: 'POST',
|
||||
data: {
|
||||
token: 'token_test',
|
||||
name: this.state.stuid,
|
||||
passwd: this.state.passwd,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res.data);
|
||||
Taro.atMessage({
|
||||
message: pt.get().button.loginText.success,
|
||||
type: 'success',
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
Taro.atMessage({
|
||||
message: pt.get().button.loginText.error + err.toString(),
|
||||
type: 'error',
|
||||
});
|
||||
});
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
isDisable: false,
|
||||
});
|
||||
}, loginInterval);
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
return (
|
||||
<AtForm onSubmit={this.onSubmit.bind(this)}>
|
||||
<AtMessage />
|
||||
<AtInput
|
||||
required
|
||||
name='stuid'
|
||||
title={pt.get().memberPage.stuidText.title}
|
||||
type='number'
|
||||
clear
|
||||
placeholder={pt.get().memberPage.stuidText.placeholder}
|
||||
value={this.state.stuid}
|
||||
onChange={this.handleChangeStuid.bind(this)}
|
||||
/>
|
||||
<AtInput
|
||||
clear
|
||||
required
|
||||
name='name'
|
||||
title={pt.get().memberPage.passwdText.title}
|
||||
type='password'
|
||||
placeholder={pt.get().memberPage.passwdText.placeholder}
|
||||
value={this.state.passwd}
|
||||
onChange={this.handleChangePasswd.bind(this)}
|
||||
/>
|
||||
<AtButton
|
||||
loading={this.state.isLoading}
|
||||
formType='submit'
|
||||
type='primary'
|
||||
disabled={this.state.isDisable}
|
||||
>
|
||||
{pt.get().button.buttonText.login}
|
||||
</AtButton>
|
||||
</AtForm>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
usingComponents: {},
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { View } from '@tarojs/components';
|
||||
import { AtList } from 'taro-ui';
|
||||
import Taro from '@tarojs/taro';
|
||||
import moment from 'moment';
|
||||
import pt from '@/plain-text';
|
||||
import { RequestState } from '@/service';
|
||||
import { getMyTicketList } from '@/service/myTicket';
|
||||
import { TicketListItem } from '@/components/TicketListItem/TicketListItem';
|
||||
import './myTicket.scss';
|
||||
|
||||
interface MyTicketState {
|
||||
fixList: Array<TicketListItem>;
|
||||
rs: RequestState;
|
||||
}
|
||||
|
||||
export default class MyTicketPage extends Component<{}, MyTicketState> {
|
||||
state = {
|
||||
fixList: [new TicketListItem(0, '', '', 1, moment())],
|
||||
rs: new RequestState(),
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
Taro.setNavigationBarTitle({
|
||||
title: pt.get().navBar.user.myTicket,
|
||||
});
|
||||
getMyTicketList(this);
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
if (this.state.rs.loading) {
|
||||
return <View>loading</View>;
|
||||
}
|
||||
if (!this.state.rs.success) {
|
||||
return <View>Failed</View>;
|
||||
}
|
||||
const fixListRenderer = this.state.fixList.map((item) => item.render());
|
||||
return (
|
||||
<View>
|
||||
<AtList>{fixListRenderer}</AtList>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
usingComponents: {},
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
import { AtTextarea, AtButton, AtForm, AtMessage } from 'taro-ui';
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { getUrl } from '@/service';
|
||||
import Taro from '@tarojs/taro';
|
||||
import pt from '@/plain-text';
|
||||
import './report.scss';
|
||||
|
||||
const submitInterval = 5000;
|
||||
|
||||
export default class ReportPage extends Component {
|
||||
state = {
|
||||
report: '',
|
||||
isLoading: false,
|
||||
isDisable: false,
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
Taro.setNavigationBarTitle({
|
||||
title: pt.get().navBar.user.report,
|
||||
});
|
||||
}
|
||||
|
||||
handleChange(report: string) {
|
||||
this.setState({
|
||||
report,
|
||||
});
|
||||
}
|
||||
onSubmit() {
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
isDisable: true,
|
||||
});
|
||||
console.log(this.state.report);
|
||||
Taro.request({
|
||||
url: getUrl('/report'),
|
||||
method: 'POST',
|
||||
data: {
|
||||
token: 'token_test',
|
||||
report: this.state.report,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res.data);
|
||||
Taro.atMessage({
|
||||
message: pt.get().button.submitText.success,
|
||||
type: 'success',
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
Taro.atMessage({
|
||||
message: pt.get().button.submitText.error + err.toString(),
|
||||
type: 'error',
|
||||
});
|
||||
});
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
isDisable: false,
|
||||
});
|
||||
}, submitInterval);
|
||||
}
|
||||
onReset() {
|
||||
this.setState({
|
||||
report: '',
|
||||
});
|
||||
}
|
||||
render(): ReactNode {
|
||||
return (
|
||||
<AtForm
|
||||
onSubmit={this.onSubmit.bind(this)}
|
||||
onReset={this.onReset.bind(this)}
|
||||
>
|
||||
<AtMessage />
|
||||
<AtTextarea
|
||||
value={this.state.report}
|
||||
onChange={this.handleChange.bind(this)}
|
||||
maxLength={200}
|
||||
placeholder={pt.get().reportPage.placeHolderText}
|
||||
/>
|
||||
<AtButton
|
||||
loading={this.state.isLoading}
|
||||
formType='submit'
|
||||
type='primary'
|
||||
disabled={this.state.isDisable}
|
||||
>
|
||||
{pt.get().button.buttonText.submit}
|
||||
</AtButton>
|
||||
<AtButton formType='reset' type='secondary'>
|
||||
{pt.get().button.buttonText.reset}
|
||||
</AtButton>
|
||||
</AtForm>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
usingComponents: {},
|
||||
});
|
||||
@@ -0,0 +1,176 @@
|
||||
import { AtList, AtListItem, AtToast } from 'taro-ui';
|
||||
import { Component, ReactNode } from 'react';
|
||||
import { View, Picker, Image, Text } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import type CustomTabBar from '@/custom-tab-bar';
|
||||
import PageFooter from '@/components/PageFooter/PageFooter';
|
||||
import aboutIcon from '@/assets/icons/AboutPage/about.svg';
|
||||
import pt, { Lang } from '@/plain-text';
|
||||
import wechatUser from '@/wechat';
|
||||
import logo from '@/assets/images/UserPage/logo.png';
|
||||
import { setLocaleData } from '@/service/localeData';
|
||||
import './user.scss';
|
||||
|
||||
const listLangInterval = 20;
|
||||
const memberClickTimes = 7;
|
||||
|
||||
export default class UserPage extends Component {
|
||||
state = {
|
||||
selector: ['简体中文', 'English'],
|
||||
selectorChecked: {
|
||||
zh_CN: '简体中文',
|
||||
en_US: 'English',
|
||||
}[pt.getCurLang()],
|
||||
clicks: memberClickTimes,
|
||||
isToastOpen: false,
|
||||
toastText: '',
|
||||
haveAccess: wechatUser.getAccess(),
|
||||
};
|
||||
|
||||
// 以下是TabBar相关
|
||||
pageCtx = Taro.getCurrentInstance().page;
|
||||
componentDidShow() {
|
||||
const tabbar = Taro.getTabBar<CustomTabBar>(this.pageCtx);
|
||||
tabbar?.setSelected(this.state.haveAccess ? 3 : 2);
|
||||
}
|
||||
// 以上是TabBar相关
|
||||
|
||||
onTapImage = () => {
|
||||
this.setState({
|
||||
clicks: this.state.clicks - 1,
|
||||
});
|
||||
if (this.state.clicks < 3) {
|
||||
this.setState({
|
||||
toastText:
|
||||
pt.get().userPage.memberEntry.front +
|
||||
(this.state.clicks + 1).toString() + // React State's feature
|
||||
pt.get().userPage.memberEntry.behind,
|
||||
isToastOpen: true,
|
||||
});
|
||||
if (this.state.clicks == 0) {
|
||||
this.setState({
|
||||
isToastOpen: false,
|
||||
clicks: memberClickTimes,
|
||||
});
|
||||
Taro.navigateTo({
|
||||
url: '/pages/user/member/member',
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
showLangDict: Record<string, Lang> = {
|
||||
简体中文: 'zh_CN',
|
||||
English: 'en_US',
|
||||
};
|
||||
|
||||
onSelect = (e: { detail: { value: string | number } }) => {
|
||||
this.setState({
|
||||
selectorChecked: this.state.selector[e.detail.value],
|
||||
});
|
||||
let currentLang = this.showLangDict[this.state.selector[e.detail.value]];
|
||||
pt.setLang(currentLang);
|
||||
setLocaleData(currentLang);
|
||||
Taro.reLaunch({
|
||||
url: '/pages/user/user',
|
||||
});
|
||||
};
|
||||
|
||||
myTicketPage() {
|
||||
Taro.navigateTo({
|
||||
url: '/pages/user/myTicket/myTicket',
|
||||
});
|
||||
}
|
||||
|
||||
informPage() {
|
||||
Taro.navigateTo({
|
||||
url: '/pages/user/inform/inform',
|
||||
});
|
||||
}
|
||||
|
||||
reportPage() {
|
||||
Taro.navigateTo({
|
||||
url: '/pages/user/report/report',
|
||||
});
|
||||
}
|
||||
|
||||
aboutPage() {
|
||||
Taro.navigateTo({
|
||||
url: '/pages/user/about/about',
|
||||
});
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
return (
|
||||
<View>
|
||||
<View
|
||||
className='at-row at-row__justify--center at-row__align--end'
|
||||
style='height:110px;'
|
||||
>
|
||||
<Image
|
||||
onTap={this.onTapImage}
|
||||
style='width: 100px;height: 100px;'
|
||||
src={logo}
|
||||
mode='aspectFit'
|
||||
/>
|
||||
</View>
|
||||
<AtToast
|
||||
isOpened={this.state.isToastOpen}
|
||||
text={this.state.toastText}
|
||||
></AtToast>
|
||||
<View
|
||||
className='at-row at-row__justify--center at-row__align--center'
|
||||
style='height:60px;color:#696969;'
|
||||
>
|
||||
<Text> EVA Notify v1.0.0</Text>
|
||||
</View>
|
||||
<AtList>
|
||||
<AtListItem
|
||||
title={pt.get().userPage.ticketColumn.title}
|
||||
note={pt.get().userPage.ticketColumn.note}
|
||||
arrow='right'
|
||||
iconInfo={{ color: '#E69966', value: 'clock' }}
|
||||
onClick={this.myTicketPage}
|
||||
/>
|
||||
<AtListItem
|
||||
title={pt.get().userPage.infoColumn.title}
|
||||
note={pt.get().userPage.infoColumn.note}
|
||||
arrow='right'
|
||||
iconInfo={{ color: '#78A4FA', value: 'user' }}
|
||||
onClick={this.informPage}
|
||||
/>
|
||||
<AtListItem
|
||||
title={pt.get().userPage.reportColumn.title}
|
||||
note={pt.get().userPage.reportColumn.note}
|
||||
extraText=''
|
||||
arrow='right'
|
||||
iconInfo={{ color: '#9ACD32', value: 'message' }}
|
||||
onClick={this.reportPage}
|
||||
/>
|
||||
<AtListItem
|
||||
title={pt.get().userPage.aboutColumn.title}
|
||||
note={pt.get().userPage.aboutColumn.note}
|
||||
extraText=''
|
||||
arrow='right'
|
||||
thumb={aboutIcon}
|
||||
onClick={this.aboutPage}
|
||||
/>
|
||||
<View style={{ height: listLangInterval }}></View>
|
||||
<Picker
|
||||
mode='selector'
|
||||
range={this.state.selector}
|
||||
onChange={this.onSelect}
|
||||
>
|
||||
<AtList>
|
||||
<AtListItem
|
||||
title='语言 / Language'
|
||||
extraText={this.state.selectorChecked}
|
||||
/>
|
||||
</AtList>
|
||||
</Picker>
|
||||
</AtList>
|
||||
<PageFooter />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface AboutPageText {}
|
||||
|
||||
export const aboutPageZhCn: AboutPageText = {};
|
||||
|
||||
export const aboutPageEnUs: AboutPageText = {};
|
||||
@@ -0,0 +1,47 @@
|
||||
export interface ButtonText {
|
||||
buttonText: {
|
||||
submit: string;
|
||||
reset: string;
|
||||
login: string;
|
||||
};
|
||||
submitText: {
|
||||
success: string;
|
||||
error: string;
|
||||
};
|
||||
loginText: {
|
||||
success: string;
|
||||
error: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const buttonZhCn: ButtonText = {
|
||||
buttonText: {
|
||||
submit: '提交',
|
||||
reset: '清空',
|
||||
login: '登录',
|
||||
},
|
||||
submitText: {
|
||||
success: '提交成功',
|
||||
error: '提交失败:',
|
||||
},
|
||||
loginText: {
|
||||
success: '登录成功',
|
||||
error: '登录失败',
|
||||
},
|
||||
};
|
||||
|
||||
export const buttonEnUs: ButtonText = {
|
||||
buttonText: {
|
||||
submit: 'Submit',
|
||||
reset: 'Reset',
|
||||
login: 'Login',
|
||||
},
|
||||
submitText: {
|
||||
success: 'Success',
|
||||
error: 'Error: ',
|
||||
},
|
||||
loginText: {
|
||||
success: 'Login Success',
|
||||
error: 'Login Failed',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
export interface InformPageText {
|
||||
phoneText: {
|
||||
title: string;
|
||||
placeholder: string;
|
||||
};
|
||||
nameText: {
|
||||
title: string;
|
||||
placeholder: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const informPageZhCn: InformPageText = {
|
||||
phoneText: {
|
||||
title: '手机号码',
|
||||
placeholder: '便于查询工单',
|
||||
},
|
||||
nameText: {
|
||||
title: '真实姓名',
|
||||
placeholder: '必填,与工单绑定',
|
||||
},
|
||||
};
|
||||
|
||||
export const informPageEnUs: InformPageText = {
|
||||
phoneText: {
|
||||
title: 'Phone',
|
||||
placeholder: 'Used for querying tickets',
|
||||
},
|
||||
nameText: {
|
||||
title: 'Real Name',
|
||||
placeholder: '(Required) Bounded to your ticket',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,156 @@
|
||||
export interface MainPageText {
|
||||
mainTitleLine: string;
|
||||
subTitleLine: string;
|
||||
cardTitle: {
|
||||
dutyInfo: string;
|
||||
stepInfo: string;
|
||||
tipsInfo: string;
|
||||
};
|
||||
cardTips: {
|
||||
dutyInfo: string;
|
||||
stepInfo: string;
|
||||
tipsInfo: string;
|
||||
};
|
||||
extraInfo: {
|
||||
dutyInfo: string;
|
||||
stepInfo: string;
|
||||
tipsInfo: string;
|
||||
};
|
||||
expandTitle: {
|
||||
stepInfo: string;
|
||||
tipsInfo: string;
|
||||
};
|
||||
stepList: Array<{ title: string }>;
|
||||
tipsList: Array<{ title: string }>;
|
||||
|
||||
dutyCard: {
|
||||
offDuty: {
|
||||
title: string;
|
||||
reason: (s: string) => string;
|
||||
recoverTime: (t: string) => string;
|
||||
};
|
||||
inDuty: {
|
||||
title: string;
|
||||
currentDutyText: (c: 'off' | '1' | '2' | '3') => string;
|
||||
inDutyCnt: (n: number) => string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const mainPageZhCn: MainPageText = {
|
||||
mainTitleLine: '您好,这里是E志者协会',
|
||||
subTitleLine: '维修请至【东三-204】实验室',
|
||||
cardTitle: {
|
||||
dutyInfo: '204 值班情况',
|
||||
stepInfo: '维修步骤',
|
||||
tipsInfo: '注意事项',
|
||||
},
|
||||
cardTips: {
|
||||
dutyInfo: '提示:可以先前往【维修】页面在线上预填写工单!',
|
||||
stepInfo: '提示:请在 20:30 之前取走自己的物品哦!',
|
||||
tipsInfo: '',
|
||||
},
|
||||
extraInfo: {
|
||||
dutyInfo: '',
|
||||
stepInfo: '',
|
||||
tipsInfo: '',
|
||||
},
|
||||
expandTitle: {
|
||||
stepInfo: '查看维修步骤',
|
||||
tipsInfo: '查看注意事项',
|
||||
},
|
||||
stepList: [
|
||||
{ title: '线上填写工单' },
|
||||
{ title: '去【东三-204】实验室维修电脑' },
|
||||
{ title: '等待电脑维修' },
|
||||
{ title: '维修结束,取回电脑' },
|
||||
],
|
||||
tipsList: [
|
||||
{ title: '戴尔/外星人、Surface、苹果电脑不能拆机哦~' },
|
||||
{ title: '数据无价,请随时做好数据备份哦~' },
|
||||
{ title: '204 也是实验室,请勿在内饮食~' },
|
||||
{ title: '我们是志愿服务,不收取任何礼物哦~' },
|
||||
],
|
||||
dutyCard: {
|
||||
offDuty: {
|
||||
title: '未值班',
|
||||
reason: (s) => '值班停止原因:' + s,
|
||||
recoverTime: (t) => '恢复值班时间:' + t,
|
||||
},
|
||||
inDuty: {
|
||||
title: '值班中',
|
||||
currentDutyText: (c) => {
|
||||
switch (c) {
|
||||
case 'off':
|
||||
return '当前未值班';
|
||||
case '1':
|
||||
return '第一班 13:30-16:00';
|
||||
case '2':
|
||||
return '第二班 16:00-18:00';
|
||||
case '3':
|
||||
return '第三班 18:00-20:30';
|
||||
}
|
||||
},
|
||||
inDutyCnt: (n) => '当前值班人数:' + n,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const mainPageEnUs: MainPageText = {
|
||||
mainTitleLine: 'Hi! This is EVA.',
|
||||
subTitleLine: 'For maintenance, please go to [204 Lab, E3 building]',
|
||||
cardTitle: {
|
||||
dutyInfo: 'Duty Situation',
|
||||
stepInfo: 'Maintenance Steps',
|
||||
tipsInfo: 'Tips',
|
||||
},
|
||||
cardTips: {
|
||||
dutyInfo: 'Tips: Please go to [Repair] and filling out tickets online.',
|
||||
stepInfo: 'Tips: Please retrieve your devices before 20:30!',
|
||||
tipsInfo: '',
|
||||
},
|
||||
expandTitle: {
|
||||
stepInfo: 'Check for maintenance steps',
|
||||
tipsInfo: 'Check for tips',
|
||||
},
|
||||
extraInfo: {
|
||||
dutyInfo: '',
|
||||
stepInfo: '',
|
||||
tipsInfo: '',
|
||||
},
|
||||
stepList: [
|
||||
{ title: 'Filling out tickets online' },
|
||||
{ title: 'Go to [204 Lab, E3 building] for maintenance' },
|
||||
{ title: 'Waiting for the device maintenance' },
|
||||
{ title: 'The maintenance is over, retrieve the device' },
|
||||
],
|
||||
tipsList: [
|
||||
{ title: 'Dell/Alienware, Surface, Apple cannot be dissassembled.' },
|
||||
{ title: 'Data is priceless, please backup your data at any time!' },
|
||||
{ title: '204 is also a laboratory. Do not eat inside.' },
|
||||
{ title: 'We are volunteers and do not take any gifts.' },
|
||||
],
|
||||
dutyCard: {
|
||||
offDuty: {
|
||||
title: 'Off Duty',
|
||||
reason: (s) => 'Reason for cessation of duty: ' + s,
|
||||
recoverTime: (t) => 'Resumption of duty: ' + t,
|
||||
},
|
||||
inDuty: {
|
||||
title: 'On Duty',
|
||||
currentDutyText: (c) => {
|
||||
switch (c) {
|
||||
case 'off':
|
||||
return 'Currently not on duty';
|
||||
case '1':
|
||||
return '1st Shift 13:30-16:00';
|
||||
case '2':
|
||||
return '2nd Shift 16:00-18:00';
|
||||
case '3':
|
||||
return '3rd Shift 18:00-20:30';
|
||||
}
|
||||
},
|
||||
inDutyCnt: (n) => 'EVA members on duty: ' + n,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
export interface MemberPageText {
|
||||
stuidText: {
|
||||
title: string;
|
||||
placeholder: string;
|
||||
};
|
||||
passwdText: {
|
||||
title: string;
|
||||
placeholder: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const memberPageZhCn: MemberPageText = {
|
||||
stuidText: {
|
||||
title: '学号',
|
||||
placeholder: '与统一身份认证学号一致',
|
||||
},
|
||||
passwdText: {
|
||||
title: '密码',
|
||||
placeholder: '与 EVA 统一身份认证一致',
|
||||
},
|
||||
};
|
||||
|
||||
export const memberPageEnUs: MemberPageText = {
|
||||
stuidText: {
|
||||
title: 'Student ID',
|
||||
placeholder: 'Consistent with EVA Auth',
|
||||
},
|
||||
passwdText: {
|
||||
title: 'Password',
|
||||
placeholder: 'Consistent with EVA Auth',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
export interface NavBarTitle {
|
||||
ticketDetail: string;
|
||||
user: {
|
||||
myTicket: string;
|
||||
report: string;
|
||||
member: string;
|
||||
inform: string;
|
||||
about: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const navBarTitleZhCn: NavBarTitle = {
|
||||
ticketDetail: '工单详情',
|
||||
user: {
|
||||
myTicket: '我的工单',
|
||||
report: '意见反馈',
|
||||
inform: '我的信息',
|
||||
about: '关于我们',
|
||||
member: '协会成员登录',
|
||||
},
|
||||
};
|
||||
|
||||
export const navBarTitleEnUs: NavBarTitle = {
|
||||
ticketDetail: 'Ticket Detail',
|
||||
user: {
|
||||
myTicket: 'My Tickets',
|
||||
report: 'Report',
|
||||
inform: 'Information',
|
||||
about: 'About us',
|
||||
member: 'Member login',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
export interface PageFooterText {
|
||||
dividerText: string;
|
||||
}
|
||||
|
||||
export const pageFooterZhCn: PageFooterText = {
|
||||
dividerText: 'EVA Notify',
|
||||
};
|
||||
|
||||
export const pageFooterEnUs: PageFooterText = {
|
||||
dividerText: 'EVA Notify',
|
||||
};
|
||||
@@ -0,0 +1,140 @@
|
||||
export interface RepairPageText {
|
||||
currentTicket: {
|
||||
errorMessage: string;
|
||||
title: string;
|
||||
note: string;
|
||||
extra: string;
|
||||
};
|
||||
typeText: {
|
||||
computer: string;
|
||||
appliance: string;
|
||||
};
|
||||
deviceText: {
|
||||
title: string;
|
||||
placeholder: string;
|
||||
};
|
||||
deviceModelText: {
|
||||
title: string;
|
||||
placeholder: string;
|
||||
};
|
||||
ownerText: {
|
||||
title: string;
|
||||
placeholder: string;
|
||||
};
|
||||
phoneText: {
|
||||
title: string;
|
||||
placeholder: string;
|
||||
};
|
||||
descriptionText: {
|
||||
title: string;
|
||||
placeholder: string;
|
||||
};
|
||||
checkboxText: {
|
||||
none: string;
|
||||
usbDisk: string;
|
||||
mouseOrReceiver: string;
|
||||
powerAdapter: string;
|
||||
others: {
|
||||
label: string;
|
||||
desc: string;
|
||||
};
|
||||
};
|
||||
cardText: {
|
||||
note: string;
|
||||
title: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const repairPageZhCn: RepairPageText = {
|
||||
currentTicket: {
|
||||
errorMessage: '未获取到工单!',
|
||||
title: '',
|
||||
note: '',
|
||||
extra: '',
|
||||
},
|
||||
typeText: {
|
||||
computer: '电脑',
|
||||
appliance: '电器',
|
||||
},
|
||||
deviceText: {
|
||||
title: '设备品牌',
|
||||
placeholder: '如:ROG',
|
||||
},
|
||||
deviceModelText: {
|
||||
title: '设备型号',
|
||||
placeholder: '如:幻 14 2022',
|
||||
},
|
||||
ownerText: {
|
||||
title: '机主姓名',
|
||||
placeholder: '如:晓洋',
|
||||
},
|
||||
phoneText: {
|
||||
title: '联系方式',
|
||||
placeholder: '如:18888888888',
|
||||
},
|
||||
descriptionText: {
|
||||
title: '问题描述',
|
||||
placeholder: '如:ZJUWLAN 无法登入校内网站',
|
||||
},
|
||||
checkboxText: {
|
||||
none: '无附件',
|
||||
usbDisk: 'U 盘',
|
||||
mouseOrReceiver: '鼠标/接收器',
|
||||
powerAdapter: '电源适配器',
|
||||
others: {
|
||||
label: '其他',
|
||||
desc: '请于评论中详述',
|
||||
},
|
||||
},
|
||||
cardText: {
|
||||
note: '工单描述请尽量简短哦!',
|
||||
title: '预填写工单',
|
||||
},
|
||||
};
|
||||
|
||||
export const repairPageEnUs: RepairPageText = {
|
||||
currentTicket: {
|
||||
errorMessage: '未获取到工单!',
|
||||
title: '',
|
||||
note: '',
|
||||
extra: '',
|
||||
},
|
||||
typeText: {
|
||||
computer: 'Computer',
|
||||
appliance: 'Appliance',
|
||||
},
|
||||
deviceText: {
|
||||
title: 'Brand',
|
||||
placeholder: 'e.g. ROG',
|
||||
},
|
||||
deviceModelText: {
|
||||
title: 'Device Model',
|
||||
placeholder: 'e.g. Zephyrus G14 2022',
|
||||
},
|
||||
ownerText: {
|
||||
title: 'Name',
|
||||
placeholder: 'e.g. Dean Ma',
|
||||
},
|
||||
phoneText: {
|
||||
title: 'Tel',
|
||||
placeholder: 'e.g. 18888888888',
|
||||
},
|
||||
descriptionText: {
|
||||
title: 'Problem Description',
|
||||
placeholder: 'e.g. ZJUWLAN inaccessable',
|
||||
},
|
||||
checkboxText: {
|
||||
none: 'None',
|
||||
usbDisk: 'USB Disk',
|
||||
mouseOrReceiver: 'Mouse/Receiver',
|
||||
powerAdapter: 'Power Adapter',
|
||||
others: {
|
||||
label: 'Others',
|
||||
desc: 'Please elaborate in the comments',
|
||||
},
|
||||
},
|
||||
cardText: {
|
||||
note: 'Please keep the ticket description as short as possible',
|
||||
title: 'Pre-filling working tickets',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface ReportPageText {
|
||||
placeHolderText: string;
|
||||
}
|
||||
|
||||
export const reportPageZhCn: ReportPageText = {
|
||||
placeHolderText:
|
||||
'无论是有关于小程序的建议,还是关于E志者协会的建议,都可以提出来哦!',
|
||||
};
|
||||
|
||||
export const reportPageEnUs: ReportPageText = {
|
||||
placeHolderText:
|
||||
'Feel free to post your suggestions about the weapp or about us!',
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
export interface TabBarText {
|
||||
indexText: string;
|
||||
repairText: string;
|
||||
userText: string;
|
||||
memberText: string;
|
||||
}
|
||||
|
||||
export const tabBarZhCn: TabBarText = {
|
||||
indexText: '主页',
|
||||
repairText: '维修',
|
||||
userText: '我的',
|
||||
memberText: '管理',
|
||||
};
|
||||
|
||||
export const tabBarEnUs: TabBarText = {
|
||||
indexText: 'Home',
|
||||
repairText: 'Repair',
|
||||
userText: 'Account',
|
||||
memberText: 'Member',
|
||||
};
|
||||