100 Commits
Author SHA1 Message Date
Dawn_Ocean 9931b23337 wrap up detailframework in atcard in repair page 2024-03-14 16:51:21 +08:00
Dawn_Ocean 84507f7214 refactor ticketListItem 2024-03-14 12:09:51 +08:00
Dawn_Ocean 802d008767 refactor DetailFramework and service/ticketsInfo; create currentTicket service 2024-03-14 11:40:59 +08:00
Dawn_Ocean c070b356fe refactor DetailFramework and service/ticketsInfo 2024-03-14 10:42:30 +08:00
Dawn_Ocean b1c0e5d8b1 Merge branch 'dev' into mgy 2024-03-14 09:03:00 +08:00
Dawn1Ocean e82225ecbc add english localization 2024-03-13 17:09:22 +08:00
Dawn1Ocean df71ebf219 change logo, README.md 2024-03-13 16:23:09 +08:00
fracher 0dac2ad185 refactor ticket detail 2024-03-12 23:01:24 +08:00
Dawn1Ocean e1c3b464a6 change prettier format 2024-03-12 21:55:53 +08:00
Dawn1Ocean e11a58dbb5 change format option 2024-03-12 21:50:23 +08:00
Dawn1Ocean 5bafff52ad optimize layout of index page 2024-03-12 20:33:29 +08:00
Dawn1Ocean d83136a69c add uncompleted ticket mock; fix logo.png: compressed 2024-03-12 19:48:49 +08:00
Dawn1Ocean b243fc5e4c fix submit logic of repair page 2024-03-12 19:15:49 +08:00
Dawn_Ocean 2f6b98b43f fix AtMessage bug in repair page 2024-03-12 18:34:44 +08:00
Dawn_Ocean 6cd27cce10 add card-viewer to repair page 2024-03-12 17:08:32 +08:00
fracher 7810cbaca1 refactor request state 2024-03-12 15:44:35 +08:00
fracher 0120da0760 add ticket detail button 2024-03-12 14:33:40 +08:00
fracher f17bfa2a9e refactor note card to component 2024-03-12 13:28:20 +08:00
fracher 2e2629fe0a add common text 2024-03-12 12:48:58 +08:00
fracher eea622b657 add ticket detail localization 2024-03-12 12:38:04 +08:00
fracher cd076cd5a4 render basic data in ticket detail 2024-03-12 12:14:45 +08:00
fracher a1aa63635f Merge branch 'yhy' into dev 2024-03-12 02:27:02 +08:00
Dawn1Ocean 946a312c61 add request to repair page 2024-03-12 02:25:58 +08:00
fracher 388814f9d9 add ticket detail data 2024-03-12 02:23:11 +08:00
Dawn1Ocean 9bd6c8f1b4 Merge branch 'dev' into mgy 2024-03-12 01:47:15 +08:00
Dawn1Ocean 551d93c8b5 add repair page 2024-03-12 01:45:25 +08:00
fracher 32ce506764 add steps 2024-03-12 01:12:56 +08:00
fracher eaa22dcaa5 refactor user and app service 2024-03-12 00:34:58 +08:00
fracher 9c6cbd91ff rename files 2024-03-11 23:12:41 +08:00
fracher 6583b51750 refactor mainpage service 2024-03-11 23:08:27 +08:00
fracher dd56725575 refactor main page service 2024-03-11 22:57:12 +08:00
fracher 2fd629d479 start refactor 2024-03-11 22:19:32 +08:00
fracher d5b8af7d7b Merge branch 'yhy' into dev 2024-03-11 21:29:56 +08:00
fracher aa334d3f93 nav bar title localization 2024-03-11 21:28:33 +08:00
Dawn_Ocean 7aaad7563f add request to index page 2024-03-11 21:27:11 +08:00
fracher 4d6a769fea add entrance to ticket detail 2024-03-11 20:48:25 +08:00
Dawn_Ocean afdedea344 add member page & tabbar item 2024-03-11 19:22:51 +08:00
Dawn_Ocean 2920059ffa merging all into dev 2024-03-11 14:17:57 +08:00
Dawn_Ocean d2de74578b Merge branch 'yhy' into dev 2024-03-11 14:13:39 +08:00
Dawn_Ocean ac23f88cdd add member login mock 2024-03-11 14:03:23 +08:00
Dawn_Ocean e1e998628f remove reset button from inform page 2024-03-11 13:55:54 +08:00
Dawn_Ocean 806e7a393c add member login page 2024-03-11 13:52:09 +08:00
Dawn_Ocean fd6a60d1d3 add route for memberlogin page 2024-03-11 11:59:12 +08:00
Dawn_Ocean 36a9a35886 add member login entry in user page 2024-03-11 11:58:12 +08:00
fracher 51106ead5e add request to mytickets 2024-03-11 11:36:51 +08:00
fracher 4e31eb70e2 add ticket list 2024-03-11 11:15:02 +08:00
Dawn_Ocean dd770b8ece add inform page request 2024-03-08 22:45:40 +08:00
Dawn_Ocean b174304d74 fix mock file structure 2024-03-08 22:27:13 +08:00
fracher cc5af58155 import moment.js 2024-03-08 22:10:17 +08:00
Dawn_Ocean 88cdb6cb92 add report request 2024-03-08 21:44:21 +08:00
Dawn_Ocean 00977db512 add locale request 2024-03-08 21:24:08 +08:00
Dawn_Ocean 1907f1e967 optimize userpage layout 2024-03-08 16:41:53 +08:00
Dawn_Ocean 39dd945020 optimize pagefooter layout 2024-03-08 16:32:05 +08:00
Dawn_Ocean b603ad24b3 add logo & version in user page 2024-03-08 15:51:27 +08:00
Dawn_Ocean dd07c1da10 add mock apis 2024-03-08 14:56:48 +08:00
fracher a7fd2b2856 Merge branch 'yhy' into dev
merge api doc into dev
2024-03-08 00:04:20 +08:00
fracher 0baf91fadf add api doc 2024-03-08 00:01:32 +08:00
Dawn_Ocean c756e74778 remove oreo id from service 2024-03-07 23:54:59 +08:00
Dawn_Ocean 133d60375a remove settings page 2024-03-07 23:50:32 +08:00
Dawn_Ocean bea23f4705 move about page to user page 2024-03-07 21:47:16 +08:00
Dawn_Ocean 229dffa9a1 fix eslint warnings & errors; add .eslintignore 2024-03-07 21:16:46 +08:00
Dawn_Ocean 74f644b3ee optimize pt structure 2024-03-07 20:41:46 +08:00
Dawn_Ocean 0a98ea71ac add partial localization for inform page 2024-03-07 14:49:54 +08:00
Dawn_Ocean 1a30ff6def add partial localization support for report page 2024-03-07 14:38:37 +08:00
Dawn_Ocean 3232994fb2 add localization for settings page 2024-03-07 14:30:45 +08:00
Dawn_Ocean d995c6ed43 add localization for tab-bar 2024-03-07 14:21:55 +08:00
Dawn_Ocean 6cbd6685bc add language switch in settings page 2024-03-07 14:07:38 +08:00
Dawn_Ocean c63b7fcca8 add en_US structure for plain-text 2024-03-07 11:45:34 +08:00
Dawn_Ocean 34c3753d2c add plain-text support for user page 2024-03-07 11:32:37 +08:00
Dawn_Ocean a5aa10d6f4 add user page footer 2024-03-07 11:14:33 +08:00
Dawn_Ocean f37af7dacd optimize form submit logic 2024-03-07 01:40:11 +08:00
Dawn_Ocean 21e21f272f add about page 2024-03-07 01:18:13 +08:00
Dawn_Ocean a408ac9e39 add myticket page 2024-03-07 01:07:33 +08:00
Dawn_Ocean 162b7a7d09 add report page; optimize style 2024-03-07 00:52:14 +08:00
Dawn_Ocean 54091bb6b3 merging 2024-03-06 21:49:35 +08:00
Dawn_Ocean 098ddd3c13 Merge branch 'dev' into yhy 2024-03-06 21:45:28 +08:00
Dawn_Ocean 64e4b8d6bd fix unused components 2024-03-06 21:44:45 +08:00
fracher 349f125404 update duty info card 2024-03-06 20:57:52 +08:00
fracher d9d005986e refactor main page 2024-03-06 19:45:30 +08:00
fracher 7cd56d7c79 move card text to PlainText 2024-03-06 15:53:13 +08:00
fracher ff880de466 dutycard add data 2024-03-06 15:13:35 +08:00
fracher 11f16b6b06 remove format for project config
remove format for project config
2024-03-06 14:11:30 +08:00
fracher 5f2e66546c add request support 2024-03-06 14:04:17 +08:00
fracher 20b9016f51 change main page layout 2024-03-06 00:14:23 +08:00
fracher 08401dd64d add global plain text to main page 2024-03-06 00:02:41 +08:00
fracher a9d9415def add global plain text 2024-03-06 00:02:00 +08:00
Dawn_Ocean 0841fc91fc add userinfo page 2024-03-05 21:57:54 +08:00
fracher 83d2e8419e update main page 2024-03-05 19:56:13 +08:00
fracher eb7623917c add PageFooter 2024-03-05 19:50:57 +08:00
fracher f0fe2f6abf add main page items 2024-03-05 17:04:51 +08:00
Dawn_Ocean 7d7d8df7d3 add mock 2024-03-04 22:32:35 +08:00
Dawn_Ocean 419a66fd2b add user page structure 2024-03-04 22:19:54 +08:00
Dawn_Ocean b9c20c1dfd fix prettier 2024-03-04 21:35:36 +08:00
Dawn_Ocean 58ffec6cb6 change weapp id 2024-03-04 21:35:03 +08:00
fracher b88beeb9e7 add pre-commit action 2024-03-04 20:42:10 +08:00
fracher a9d318c6e2 format project 2024-03-04 20:23:07 +08:00
fracher d6671e055a add appid to environment 2024-03-04 20:12:23 +08:00
fracher 01fc78fb12 use strict format 2024-03-04 20:08:21 +08:00
fracher 7f84b72ddc fix prettier 2024-03-04 19:47:35 +08:00
fracher 08fbd58c61 add tab bar 2024-03-04 19:47:18 +08:00
113 changed files with 39365 additions and 35432 deletions
+2 -1
View File
@@ -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"
+2 -1
View File
@@ -1 +1,2 @@
# TARO_APP_ID="生产环境下的小程序appid"
TARO_APP_ID="wx636eb7cf2b84f305"
TARO_APP_API=""
+1 -1
View File
@@ -1 +1 @@
# TARO_APP_ID="测试环境下的小程序appid"
TARO_APP_ID="wx636eb7cf2b84f305"
+19
View File
@@ -0,0 +1,19 @@
config
.husky
**/.gitignore
dist/
deploy_versions/
.temp/
.rn_temp/
node_modules/
.DS_Store
.swc
.husky
.prettierignore
.env.*
**/*.json
**/*.svg
**/*.scss
**/*.md
*.config.js
index.html
+3 -1
View File
@@ -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"
}
}
+1
View File
@@ -0,0 +1 @@
_
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
+14
View File
@@ -0,0 +1,14 @@
.eslintignore
**/.gitignore
dist/
deploy_versions/
.temp/
.rn_temp/
node_modules/
.DS_Store
.swc
.husky
.prettierignore
.env.*
project.*.json
**/*.svg
+4 -3
View File
@@ -1,11 +1,12 @@
{
"printWidth": 120,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"proseWrap": "preserve",
"arrowParens": "avoid",
"arrowParens": "always",
"bracketSpacing": true,
"jsxSingleQuote": true
"jsxSingleQuote": true,
"endOfLine": "auto"
}
+14
View File
@@ -58,6 +58,7 @@
## 主页
1. 信息显示
1. 不显示是哪一班,只显示今日值班时间
2. (协会成员)相关信息
3. 提醒事项
4. 如何联系到协会
@@ -68,8 +69,21 @@
2. 维修进度提示
3. (面向协会成员)维修列表
## 成员
1. 最近七天内未取回的工单列表
2. 值班组长上传本班相关信息
3. 现在自己是否要值班(值班时间显示)
## 我的
1. 更改手机号等个人信息(手机号可以填写多个)
2. (备选)修改用户名、头像
3. 设置真名(可帮助预填写工单)
# 主席团管理页面
1. 值班表导入、更新
2. 成员权限管理
3. 特殊维修时间(如学园维修)、值班信息更新
-12
View File
@@ -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()
})
})
+8 -5
View File
@@ -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,
},
],
],
};
+5 -4
View File
@@ -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;
+35 -40
View File
@@ -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,54 +13,49 @@ 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: {
type: 'webpack5',
prebundle: {
exclude: ['taro-ui']
}
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'],
@@ -68,43 +63,43 @@ export default defineConfig(async (merge, { command, mode }) => {
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);
});
+4 -3
View File
@@ -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;
+226
View File
@@ -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
}
```
-6
View File
@@ -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)']
})
+59
View File
@@ -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,
},
};
+15
View File
@@ -0,0 +1,15 @@
{
"list": [
{
"id": 6830,
"type": 1,
"status": 2,
"device": "主机",
"deviceModel": "技嘉",
"owner": "武技栏",
"phone": "18888888888",
"createdTime": "2024-03-06T19:49:27.043865",
"isConfirmed": false
}
]
}
+49
View File
@@ -0,0 +1,49 @@
{
"id": 6830,
"type": 1,
"device": "华硕",
"deviceModel": "灵耀X14",
"owner": "唐姐姐",
"phone": "15555555555",
"description": "清灰",
"workers": [],
"createdTime": "2024-03-07T19:52:48.523303",
"status": 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
}
+15
View File
@@ -0,0 +1,15 @@
{
"list": [
{
"id": 6832,
"type": 1,
"status": 2,
"device": "ROG",
"deviceModel": "幻 14 2022",
"owner": "晓洋",
"phone": "18888888887",
"createdTime": "2024-03-07T11:45:14.191981",
"isConfirmed": false
}
]
}
+727 -9
View File
@@ -23,6 +23,8 @@
"@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",
"taro-ui": "^3.3.0"
@@ -31,7 +33,8 @@
"@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",
@@ -46,10 +49,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",
@@ -5685,6 +5692,15 @@
"node": ">=14"
}
},
"node_modules/@pkgr/core": {
"version": "0.1.1",
"resolved": "https://registry.npmmirror.com/@pkgr/core/-/core-0.1.1.tgz",
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
}
},
"node_modules/@pmmmwh/react-refresh-webpack-plugin": {
"version": "0.5.11",
"resolved": "https://registry.npmmirror.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz",
@@ -8825,6 +8841,61 @@
}
}
},
"node_modules/@tarojs/plugin-mock": {
"version": "0.0.9",
"resolved": "https://registry.npmmirror.com/@tarojs/plugin-mock/-/plugin-mock-0.0.9.tgz",
"integrity": "sha512-Q4z4lHp2mHVByQJ8gtIq0Rct8vkEqvCmyTmv+EJNf9sJY3F5H1fmDNfgMVn2fyZj7TmxuSMq/FDtgNlEA4eTow==",
"dev": true,
"dependencies": {
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"get-port": "^5.1.1",
"glob": "^7.1.6",
"http-proxy-middleware": "^1.0.3",
"path-to-regexp": "^6.1.0"
}
},
"node_modules/@tarojs/plugin-mock/node_modules/get-port": {
"version": "5.1.1",
"resolved": "https://registry.npmmirror.com/get-port/-/get-port-5.1.1.tgz",
"integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/@tarojs/plugin-mock/node_modules/http-proxy-middleware": {
"version": "1.3.1",
"resolved": "https://registry.npmmirror.com/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz",
"integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==",
"dev": true,
"dependencies": {
"@types/http-proxy": "^1.17.5",
"http-proxy": "^1.18.1",
"is-glob": "^4.0.1",
"is-plain-obj": "^3.0.0",
"micromatch": "^4.0.2"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/@tarojs/plugin-mock/node_modules/is-plain-obj": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz",
"integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/@tarojs/plugin-mock/node_modules/path-to-regexp": {
"version": "6.2.1",
"resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==",
"dev": true
},
"node_modules/@tarojs/plugin-platform-alipay": {
"version": "3.6.24",
"resolved": "https://registry.npmmirror.com/@tarojs/plugin-platform-alipay/-/plugin-platform-alipay-3.6.24.tgz",
@@ -10321,6 +10392,19 @@
"url": "https://opencollective.com/postcss/"
}
},
"node_modules/@vue/component-compiler-utils/node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"optional": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/@vue/component-compiler-utils/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
@@ -12992,6 +13076,91 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/cli-truncate": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/cli-truncate/-/cli-truncate-4.0.0.tgz",
"integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
"dev": true,
"dependencies": {
"slice-ansi": "^5.0.0",
"string-width": "^7.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/cli-truncate/node_modules/ansi-regex": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz",
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/cli-truncate/node_modules/ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/cli-truncate/node_modules/emoji-regex": {
"version": "10.3.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-10.3.0.tgz",
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
"dev": true
},
"node_modules/cli-truncate/node_modules/is-fullwidth-code-point": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
"integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/cli-truncate/node_modules/slice-ansi": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-5.0.0.tgz",
"integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^6.0.0",
"is-fullwidth-code-point": "^4.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/cli-truncate/node_modules/string-width": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-7.1.0.tgz",
"integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
"dev": true,
"dependencies": {
"emoji-regex": "^10.3.0",
"get-east-asian-width": "^1.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/cli-truncate/node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/cli-width": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cli-width/-/cli-width-3.0.0.tgz",
@@ -13692,6 +13861,19 @@
"resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"dev": true,
"dependencies": {
"object-assign": "^4",
"vary": "^1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/cosmiconfig": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
@@ -16118,6 +16300,33 @@
"node": "*"
}
},
"node_modules/eslint-plugin-prettier": {
"version": "5.1.3",
"resolved": "https://registry.npmmirror.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
"integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
"dev": true,
"dependencies": {
"prettier-linter-helpers": "^1.0.0",
"synckit": "^0.8.6"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"peerDependencies": {
"@types/eslint": ">=8.0.0",
"eslint": ">=8.0.0",
"eslint-config-prettier": "*",
"prettier": ">=3.0.0"
},
"peerDependenciesMeta": {
"@types/eslint": {
"optional": true
},
"eslint-config-prettier": {
"optional": true
}
}
},
"node_modules/eslint-plugin-react": {
"version": "7.33.2",
"resolved": "https://registry.npmmirror.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz",
@@ -17424,6 +17633,12 @@
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-diff": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/fast-diff/-/fast-diff-1.3.0.tgz",
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true
},
"node_modules/fast-glob": {
"version": "3.3.2",
"resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz",
@@ -18158,6 +18373,15 @@
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-east-asian-width": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz",
"integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==",
"dev": true,
"engines": {
"node": ">=18"
}
},
"node_modules/get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
@@ -19249,6 +19473,18 @@
"node": ">=10.17.0"
}
},
"node_modules/husky": {
"version": "9.0.11",
"resolved": "https://registry.npmmirror.com/husky/-/husky-9.0.11.tgz",
"integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
"dev": true,
"bin": {
"husky": "bin.mjs"
},
"engines": {
"node": ">=18"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -23348,6 +23584,260 @@
"resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
"node_modules/lint-staged": {
"version": "15.2.2",
"resolved": "https://registry.npmmirror.com/lint-staged/-/lint-staged-15.2.2.tgz",
"integrity": "sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==",
"dev": true,
"dependencies": {
"chalk": "5.3.0",
"commander": "11.1.0",
"debug": "4.3.4",
"execa": "8.0.1",
"lilconfig": "3.0.0",
"listr2": "8.0.1",
"micromatch": "4.0.5",
"pidtree": "0.6.0",
"string-argv": "0.3.2",
"yaml": "2.3.4"
},
"bin": {
"lint-staged": "bin/lint-staged.js"
},
"engines": {
"node": ">=18.12.0"
}
},
"node_modules/lint-staged/node_modules/chalk": {
"version": "5.3.0",
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-5.3.0.tgz",
"integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
"dev": true,
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
}
},
"node_modules/lint-staged/node_modules/commander": {
"version": "11.1.0",
"resolved": "https://registry.npmmirror.com/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"dev": true,
"engines": {
"node": ">=16"
}
},
"node_modules/lint-staged/node_modules/execa": {
"version": "8.0.1",
"resolved": "https://registry.npmmirror.com/execa/-/execa-8.0.1.tgz",
"integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^8.0.1",
"human-signals": "^5.0.0",
"is-stream": "^3.0.0",
"merge-stream": "^2.0.0",
"npm-run-path": "^5.1.0",
"onetime": "^6.0.0",
"signal-exit": "^4.1.0",
"strip-final-newline": "^3.0.0"
},
"engines": {
"node": ">=16.17"
}
},
"node_modules/lint-staged/node_modules/get-stream": {
"version": "8.0.1",
"resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-8.0.1.tgz",
"integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
"dev": true,
"engines": {
"node": ">=16"
}
},
"node_modules/lint-staged/node_modules/human-signals": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-5.0.0.tgz",
"integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
"dev": true,
"engines": {
"node": ">=16.17.0"
}
},
"node_modules/lint-staged/node_modules/is-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz",
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/lint-staged/node_modules/lilconfig": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.0.0.tgz",
"integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==",
"dev": true,
"engines": {
"node": ">=14"
}
},
"node_modules/lint-staged/node_modules/mimic-fn": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz",
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/lint-staged/node_modules/npm-run-path": {
"version": "5.3.0",
"resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.3.0.tgz",
"integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
"dev": true,
"dependencies": {
"path-key": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/lint-staged/node_modules/onetime": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz",
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
"dev": true,
"dependencies": {
"mimic-fn": "^4.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/lint-staged/node_modules/path-key": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz",
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/lint-staged/node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"dev": true,
"engines": {
"node": ">=14"
}
},
"node_modules/lint-staged/node_modules/strip-final-newline": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/lint-staged/node_modules/yaml": {
"version": "2.3.4",
"resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.3.4.tgz",
"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
"dev": true,
"engines": {
"node": ">= 14"
}
},
"node_modules/listr2": {
"version": "8.0.1",
"resolved": "https://registry.npmmirror.com/listr2/-/listr2-8.0.1.tgz",
"integrity": "sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==",
"dev": true,
"dependencies": {
"cli-truncate": "^4.0.0",
"colorette": "^2.0.20",
"eventemitter3": "^5.0.1",
"log-update": "^6.0.0",
"rfdc": "^1.3.0",
"wrap-ansi": "^9.0.0"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/listr2/node_modules/ansi-regex": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz",
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/listr2/node_modules/ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/listr2/node_modules/emoji-regex": {
"version": "10.3.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-10.3.0.tgz",
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
"dev": true
},
"node_modules/listr2/node_modules/eventemitter3": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.1.tgz",
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
"dev": true
},
"node_modules/listr2/node_modules/string-width": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-7.1.0.tgz",
"integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
"dev": true,
"dependencies": {
"emoji-regex": "^10.3.0",
"get-east-asian-width": "^1.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/listr2/node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/listr2/node_modules/wrap-ansi": {
"version": "9.0.0",
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
"integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
"dev": true,
"dependencies": {
"ansi-styles": "^6.2.1",
"string-width": "^7.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/load-yaml-file": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/load-yaml-file/-/load-yaml-file-0.2.0.tgz",
@@ -23544,6 +24034,157 @@
"node": ">=8"
}
},
"node_modules/log-update": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/log-update/-/log-update-6.0.0.tgz",
"integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==",
"dev": true,
"dependencies": {
"ansi-escapes": "^6.2.0",
"cli-cursor": "^4.0.0",
"slice-ansi": "^7.0.0",
"strip-ansi": "^7.1.0",
"wrap-ansi": "^9.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/log-update/node_modules/ansi-escapes": {
"version": "6.2.0",
"resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-6.2.0.tgz",
"integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==",
"dev": true,
"dependencies": {
"type-fest": "^3.0.0"
},
"engines": {
"node": ">=14.16"
}
},
"node_modules/log-update/node_modules/ansi-regex": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz",
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/log-update/node_modules/ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/log-update/node_modules/cli-cursor": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-4.0.0.tgz",
"integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
"dev": true,
"dependencies": {
"restore-cursor": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/log-update/node_modules/emoji-regex": {
"version": "10.3.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-10.3.0.tgz",
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
"dev": true
},
"node_modules/log-update/node_modules/is-fullwidth-code-point": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz",
"integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==",
"dev": true,
"dependencies": {
"get-east-asian-width": "^1.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/log-update/node_modules/restore-cursor": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-4.0.0.tgz",
"integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
"dev": true,
"dependencies": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/log-update/node_modules/slice-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-7.1.0.tgz",
"integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==",
"dev": true,
"dependencies": {
"ansi-styles": "^6.2.1",
"is-fullwidth-code-point": "^5.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/log-update/node_modules/string-width": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-7.1.0.tgz",
"integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
"dev": true,
"dependencies": {
"emoji-regex": "^10.3.0",
"get-east-asian-width": "^1.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/log-update/node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/log-update/node_modules/type-fest": {
"version": "3.13.1",
"resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-3.13.1.tgz",
"integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==",
"dev": true,
"engines": {
"node": ">=14.16"
}
},
"node_modules/log-update/node_modules/wrap-ansi": {
"version": "9.0.0",
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
"integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
"dev": true,
"dependencies": {
"ansi-styles": "^6.2.1",
"string-width": "^7.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/logkitty": {
"version": "0.7.1",
"resolved": "https://registry.npmmirror.com/logkitty/-/logkitty-0.7.1.tgz",
@@ -25728,6 +26369,26 @@
"resolved": "https://registry.npmmirror.com/mobile-detect/-/mobile-detect-1.4.5.tgz",
"integrity": "sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g=="
},
"node_modules/mockjs": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/mockjs/-/mockjs-1.1.0.tgz",
"integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==",
"dev": true,
"dependencies": {
"commander": "*"
},
"bin": {
"random": "bin/random"
}
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"engines": {
"node": "*"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz",
@@ -27482,6 +28143,18 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pidtree": {
"version": "0.6.0",
"resolved": "https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz",
"integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
"dev": true,
"bin": {
"pidtree": "bin/pidtree.js"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/pify": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz",
@@ -28528,19 +29201,28 @@
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"version": "3.2.5",
"resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.2.5.tgz",
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
"dev": true,
"optional": true,
"peer": true,
"bin": {
"prettier": "bin-prettier.js"
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=10.13.0"
"node": ">=14"
}
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
"node_modules/prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"dependencies": {
"fast-diff": "^1.1.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/pretty-bytes": {
@@ -28597,6 +29279,14 @@
"node": ">=4"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -30436,6 +31126,12 @@
"node": ">=0.10.0"
}
},
"node_modules/rfdc": {
"version": "1.3.1",
"resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.1.tgz",
"integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
"dev": true
},
"node_modules/rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-2.7.1.tgz",
@@ -31856,6 +32552,15 @@
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/string-argv": {
"version": "0.3.2",
"resolved": "https://registry.npmmirror.com/string-argv/-/string-argv-0.3.2.tgz",
"integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
"dev": true,
"engines": {
"node": ">=0.6.19"
}
},
"node_modules/string-length": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz",
@@ -32468,6 +33173,19 @@
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true
},
"node_modules/synckit": {
"version": "0.8.8",
"resolved": "https://registry.npmmirror.com/synckit/-/synckit-0.8.8.tgz",
"integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
"dev": true,
"dependencies": {
"@pkgr/core": "^0.1.0",
"tslib": "^2.6.2"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
}
},
"node_modules/table": {
"version": "6.8.1",
"resolved": "https://registry.npmmirror.com/table/-/table-6.8.1.tgz",
+15 -3
View File
@@ -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,6 +55,8 @@
"@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",
"taro-ui": "^3.3.0"
@@ -62,7 +65,8 @@
"@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",
@@ -77,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",
@@ -88,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"
}
}
+3 -2
View File
@@ -2,7 +2,7 @@
"miniprogramRoot": "dist/",
"projectname": "EVA-Notify",
"description": "A Wechat miniprogram project of EVA platform",
"appid": "wxa76ef89a218f32f8",
"appid": "wx636eb7cf2b84f305",
"setting": {
"urlCheck": true,
"es6": false,
@@ -14,7 +14,8 @@
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"packNpmRelationList": []
},
"compileType": "miniprogram",
"libVersion": "3.3.4",
+3 -1
View File
@@ -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
}
}
+17 -2
View File
@@ -1,9 +1,20 @@
export default defineAppConfig({
pages: ['pages/index/index', 'pages/repair/repair', 'pages/user/user'],
pages: [
'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',
navigationBarTitleText: 'EVA Notify',
navigationBarTextStyle: 'black',
},
tabBar: {
@@ -17,6 +28,10 @@ export default defineAppConfig({
pagePath: 'pages/repair/repair',
text: '维修',
},
{
pagePath: 'pages/member/member',
text: '管理',
},
{
pagePath: 'pages/user/user',
text: '我的',
+2
View File
@@ -2,10 +2,12 @@ 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.');
getLocaleData();
});
// children 是将要会渲染的页面
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709817911051" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4420" width="24" height="24" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M523.52 965.12a448 448 0 1 1 448-448 448 448 0 0 1-448 448z m0-832a384 384 0 1 0 384 384 384 384 0 0 0-384-384z" p-id="4421" fill="#c89bc7"></path><path d="M523.52 772.16a32 32 0 0 1-32-32V448a32 32 0 0 1 64 0v292.8a32 32 0 0 1-32 31.36z" p-id="4422" fill="#c89bc7"></path><path d="M523.52 293.12m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" p-id="4423" fill="#c89bc7"></path></svg>

After

Width:  |  Height:  |  Size: 710 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709729147345" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7587" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M960 170.56L869.44 80 512 437.44 154.56 80 64 170.56 421.44 528 64 885.44l90.56 90.56L512 618.56 869.44 976 960 885.44 602.56 528 960 170.56z" p-id="7588" fill="#d4237a"></path></svg>

After

Width:  |  Height:  |  Size: 514 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709729289782" class="icon" viewBox="0 0 1418 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8708" width="44.3125" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M491.191709 1023.803077L0.136305 539.63733l111.888035-110.273886 379.167369 373.89186L1305.549204 0.433064 1417.437238 110.706951 491.191709 1023.803077z" p-id="8709" fill="#12c53d"></path></svg>

After

Width:  |  Height:  |  Size: 531 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="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

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="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

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="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

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="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

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

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

+1
View File
@@ -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,
};
+49
View File
@@ -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,
};
+25
View File
@@ -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,
};
+24
View File
@@ -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,
});
}}
/>
);
}
}
+3
View File
@@ -0,0 +1,3 @@
export default {
component: true,
};
+3
View File
@@ -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';
+91
View File
@@ -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}
/>
);
}
}
+14 -9
View File
@@ -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: {},
});
+67
View File
@@ -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>
);
}
}
+29
View File
@@ -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';
+108
View File
@@ -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();
}
}
}
+24
View File
@@ -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>
);
}
}
+27
View File
@@ -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
View File
@@ -1,4 +1,3 @@
export default definePageConfig({
navigationBarTitleText: '首页',
usingComponents: {},
});
+104 -9
View File
@@ -1,25 +1,120 @@
import { View, Text } from '@tarojs/components';
import { View } from '@tarojs/components';
import { Component, ReactNode } from 'react';
import { AtButton } from 'taro-ui';
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';
class Index extends Component {
class CardContent {
title: string;
note: string;
extra: JSX.Element | string;
content: () => JSX.Element;
}
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 = {
msg: 'Hello World!',
open: false,
};
props = {
title: '',
content: <View></View>,
};
onReady() {
console.log('Index is ready');
handleClick(value: boolean) {
this.setState({ open: value });
}
render(): ReactNode {
return (
<View>
<AtButton type='primary' size='normal'></AtButton>
<Text>{this.state.msg}</Text>
<AtAccordion
open={this.state.open}
onClick={this.handleClick.bind(this)}
title={this.props.title}
>
{this.props.content}
</AtAccordion>
</View>
);
}
}
export default Index;
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>
<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>
);
}
}
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+23
View File
@@ -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>
);
}
}
+253 -3
View File
@@ -1,11 +1,261 @@
import { View, Text } from '@tarojs/components';
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',
});
}
export default class RepairPage extends Component {
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>
<Text>Repair Page</Text>
<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>
);
}
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+16
View File
@@ -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>;
}
}
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+88
View File
@@ -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>
);
}
}
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+108
View File
@@ -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: {},
});
+44
View File
@@ -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>
);
}
}
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+97
View File
@@ -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>
);
}
}
+166 -2
View File
@@ -1,11 +1,175 @@
import { View, Text } from '@tarojs/components';
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>
<Text>User Page</Text>
<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>
);
}
+5
View File
@@ -0,0 +1,5 @@
export interface AboutPageText {}
export const aboutPageZhCn: AboutPageText = {};
export const aboutPageEnUs: AboutPageText = {};
+47
View File
@@ -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',
},
};
+32
View File
@@ -0,0 +1,32 @@
export interface InformPageText {
phoneText: {
title: string;
placeholder: string;
};
nameText: {
title: string;
placeholder: string;
};
}
export const informPageZhCn: InformPageText = {
phoneText: {
title: '手机号码',
placeholder: '便于查询工单',
},
nameText: {
title: '真实姓名',
placeholder: '必填,与工单绑定',
},
};
export const informPageEnUs: InformPageText = {
phoneText: {
title: 'Phone',
placeholder: 'Used for querying tickets',
},
nameText: {
title: 'Real Name',
placeholder: '(Required) Bounded to your ticket',
},
};
+156
View File
@@ -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,
},
},
};
+32
View File
@@ -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',
},
};
+32
View File
@@ -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',
},
};
+11
View File
@@ -0,0 +1,11 @@
export interface PageFooterText {
dividerText: string;
}
export const pageFooterZhCn: PageFooterText = {
dividerText: 'EVA Notify',
};
export const pageFooterEnUs: PageFooterText = {
dividerText: 'EVA Notify',
};
+140
View File
@@ -0,0 +1,140 @@
export interface RepairPageText {
currentTicket: {
errorMessage: string;
title: string;
note: string;
extra: string;
};
typeText: {
computer: string;
appliance: string;
};
deviceText: {
title: string;
placeholder: string;
};
deviceModelText: {
title: string;
placeholder: string;
};
ownerText: {
title: string;
placeholder: string;
};
phoneText: {
title: string;
placeholder: string;
};
descriptionText: {
title: string;
placeholder: string;
};
checkboxText: {
none: string;
usbDisk: string;
mouseOrReceiver: string;
powerAdapter: string;
others: {
label: string;
desc: string;
};
};
cardText: {
note: string;
title: string;
};
}
export const repairPageZhCn: RepairPageText = {
currentTicket: {
errorMessage: '未获取到工单!',
title: '',
note: '',
extra: '',
},
typeText: {
computer: '电脑',
appliance: '电器',
},
deviceText: {
title: '设备品牌',
placeholder: '如:ROG',
},
deviceModelText: {
title: '设备型号',
placeholder: '如:幻 14 2022',
},
ownerText: {
title: '机主姓名',
placeholder: '如:晓洋',
},
phoneText: {
title: '联系方式',
placeholder: '如:18888888888',
},
descriptionText: {
title: '问题描述',
placeholder: '如: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',
},
};
+13
View File
@@ -0,0 +1,13 @@
export interface ReportPageText {
placeHolderText: string;
}
export const reportPageZhCn: ReportPageText = {
placeHolderText:
'无论是有关于小程序的建议,还是关于E志者协会的建议,都可以提出来哦!',
};
export const reportPageEnUs: ReportPageText = {
placeHolderText:
'Feel free to post your suggestions about the weapp or about us!',
};
+20
View File
@@ -0,0 +1,20 @@
export interface TabBarText {
indexText: string;
repairText: string;
userText: string;
memberText: string;
}
export const tabBarZhCn: TabBarText = {
indexText: '主页',
repairText: '维修',
userText: '我的',
memberText: '管理',
};
export const tabBarEnUs: TabBarText = {
indexText: 'Home',
repairText: 'Repair',
userText: 'Account',
memberText: 'Member',
};
+57
View File
@@ -0,0 +1,57 @@
interface StepItem {
title: string;
}
type StatusStr = '1' | '2' | '3' | '4' | '5';
export interface TicketDetailText {
stepItems: Array<StepItem>;
createTicketMessage: string;
statusModifyPrefix: string;
statusModifyMessage: Map<StatusStr, string>;
descTitle: string;
tookAway: string;
addNote: string;
}
export const ticketDetailZhCn: TicketDetailText = {
stepItems: [
{ title: '创建成功' },
{ title: '维修中' },
{ title: '待取回' },
{ title: '工单完成' },
],
createTicketMessage: '创建了维修',
statusModifyPrefix: '将维修状态更改为:',
statusModifyMessage: new Map<StatusStr, string>([
['1', '维修中'],
['2', '2(?)'],
['3', '3(?)'],
['4', '维修成功待取回'],
['5', '维修成功已取回'],
]),
descTitle: '问题描述',
tookAway: '已取回',
addNote: '添加评论',
};
export const ticketDetailEnUs: TicketDetailText = {
stepItems: [
{ title: 'Created' },
{ title: 'Repairing' },
{ title: 'Finished' },
{ title: 'Retrieved' },
],
createTicketMessage: 'Created ticket',
statusModifyPrefix: 'Modified repair status to: ',
statusModifyMessage: new Map<StatusStr, string>([
['1', 'Repairing'],
['2', '2(?)'],
['3', '3(?)'],
['4', 'Device to be retrieved'],
['5', 'Ticket finished'],
]),
descTitle: 'Problem description',
tookAway: 'Already retrieved',
addNote: 'Add a comment',
};
+32
View File
@@ -0,0 +1,32 @@
type FixStatus = 1 | 2 | 3 | 4 | 5;
export interface TicketListText {
createdAt(time: string): string;
statusMap: Map<FixStatus, string>;
}
export const ticketListZhCn: TicketListText = {
createdAt: (time) => {
return '创建于' + ' ' + time;
},
statusMap: new Map([
[1, '创建成功'],
[2, '维修中'],
[3, '待取回'],
[4, '已取回'],
[5, '已取回'],
]),
};
export const ticketListEnUs: TicketListText = {
createdAt: (time) => {
return 'Created at' + ' ' + time;
},
statusMap: new Map([
[1, 'Created'],
[2, 'Repairing'],
[3, 'Pending Retrieval'],
[4, 'Retrieved'],
[5, 'Retrieved'],
]),
};
+80
View File
@@ -0,0 +1,80 @@
export interface UserPageText {
memberEntry: {
front: string;
behind: string;
};
ticketColumn: {
title: string;
note: string;
};
infoColumn: {
title: string;
note: string;
};
settingsColumn: {
title: string;
note: string;
};
reportColumn: {
title: string;
note: string;
};
aboutColumn: {
title: string;
note: string;
};
}
export const userPageZhCn: UserPageText = {
memberEntry: {
front: '再点击 ',
behind: ' 次以进入协会成员登录页面',
},
ticketColumn: {
title: '我的工单',
note: '在这里查看历史工单!',
},
infoColumn: {
title: '我的信息',
note: '能帮助亦可更好地找到你哦!',
},
settingsColumn: {
title: '应用设置',
note: '在这里配置小程序',
},
reportColumn: {
title: '意见反馈',
note: '有什么想说的都可以告诉亦可哦!',
},
aboutColumn: {
title: '关于我们',
note: '查看开发者信息',
},
};
export const userPageEnUs: UserPageText = {
memberEntry: {
front: 'Click ',
behind: ' more times to enter member login page',
},
ticketColumn: {
title: 'My Tickets',
note: 'View the history of your tickets here!',
},
infoColumn: {
title: 'My Information',
note: 'It will help us contact you!',
},
settingsColumn: {
title: 'Settings',
note: 'Configure the applet here!',
},
reportColumn: {
title: 'Report',
note: 'Let us know if you have any suggestions!',
},
aboutColumn: {
title: 'About Us',
note: 'View developer information.',
},
};
+17
View File
@@ -0,0 +1,17 @@
import { Moment } from 'moment';
export interface CommonText {
createdAtText(time: Moment): string;
}
export const commonTextZhCn: CommonText = {
createdAtText(time: Moment): string {
return '创建于 ' + time.format('YYYY-MM-DD HH:mm');
},
};
export const commonTextEnUs: CommonText = {
createdAtText(time: Moment): string {
return 'Created at ' + time.format('YYYY-MM-DD HH:mm');
},
};
+105
View File
@@ -0,0 +1,105 @@
import { PageFooterText, pageFooterZhCn, pageFooterEnUs } from './PageFooter';
import { MainPageText, mainPageZhCn, mainPageEnUs } from './MainPage';
import { UserPageText, userPageZhCn, userPageEnUs } from './UserPage';
import { TabBarText, tabBarEnUs, tabBarZhCn } from './TabBar';
import { ReportPageText, reportPageEnUs, reportPageZhCn } from './ReportPage';
import { InformPageText, informPageZhCn, informPageEnUs } from './InformPage';
import { AboutPageText, aboutPageEnUs, aboutPageZhCn } from './AboutPage';
import { ButtonText, buttonEnUs, buttonZhCn } from './Button';
import { MemberPageText, memberPageEnUs, memberPageZhCn } from './MemberPage';
import { TicketListText, ticketListEnUs, ticketListZhCn } from './TicketList';
import { NavBarTitle, navBarTitleEnUs, navBarTitleZhCn } from './NavBarTitle';
import { RepairPageText, repairPageEnUs, repairPageZhCn } from './RepairPage';
import {
TicketDetailText,
ticketDetailEnUs,
ticketDetailZhCn,
} from './TicketDetail';
import { CommonText, commonTextEnUs, commonTextZhCn } from './common';
interface TextRecord {
common: CommonText;
pageFooter: PageFooterText;
mainPage: MainPageText;
userPage: UserPageText;
tabBar: TabBarText;
reportPage: ReportPageText;
informPage: InformPageText;
aboutPage: AboutPageText;
button: ButtonText;
memberPage: MemberPageText;
ticketList: TicketListText;
navBar: NavBarTitle;
repairPage: RepairPageText;
ticketDetail: TicketDetailText;
}
const textZhCn: TextRecord = {
common: commonTextZhCn,
pageFooter: pageFooterZhCn,
mainPage: mainPageZhCn,
userPage: userPageZhCn,
tabBar: tabBarZhCn,
reportPage: reportPageZhCn,
informPage: informPageZhCn,
aboutPage: aboutPageZhCn,
button: buttonZhCn,
memberPage: memberPageZhCn,
ticketList: ticketListZhCn,
navBar: navBarTitleZhCn,
repairPage: repairPageZhCn,
ticketDetail: ticketDetailZhCn,
};
const textEnUs: TextRecord = {
common: commonTextEnUs,
pageFooter: pageFooterEnUs,
mainPage: mainPageEnUs,
userPage: userPageEnUs,
tabBar: tabBarEnUs,
reportPage: reportPageEnUs,
informPage: informPageEnUs,
aboutPage: aboutPageEnUs,
button: buttonEnUs,
memberPage: memberPageEnUs,
ticketList: ticketListEnUs,
navBar: navBarTitleEnUs,
repairPage: repairPageEnUs,
ticketDetail: ticketDetailEnUs,
};
// type Lang = 'zh_CN' | 'en_US' | ...;
export type Lang = 'zh_CN' | 'en_US';
class PlainText {
private readonly textZhCn: TextRecord;
private readonly textEnUs: TextRecord;
private lang: Lang;
constructor() {
this.textZhCn = textZhCn;
this.textEnUs = textEnUs;
this.lang = 'zh_CN';
}
setLang(lang: Lang) {
this.lang = lang;
}
get(): TextRecord {
if (this.lang == 'zh_CN') {
return this.textZhCn;
} else if (this.lang == 'en_US') {
return this.textEnUs;
}
return this.textZhCn;
}
getCurLang(): Lang {
return this.lang;
}
}
const pt = new PlainText();
export default pt;

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