fix:慢慢改造
This commit is contained in:
parent
6460344c7a
commit
012c7c8c17
1
.env
1
.env
@ -1,4 +1,3 @@
|
||||
VITE_HOST = https://pi.xuexiaole.com
|
||||
# VITE_HOST = http://192.168.0.103
|
||||
VITE_OSS_HOST = https://xuexiaole-1313840333.cos.ap-guangzhou.myqcloud.com/xuexiaoleClient
|
||||
VITE_WS_URL = wss://pi.xuexiaole.com/ws/device
|
@ -1,3 +1,3 @@
|
||||
VITE_HOST = https://test.pi.xuexiaole.com
|
||||
VITE_HOST = http://127.0.0.1:9053
|
||||
VITE_OSS_HOST = https://xuexiaole-1313840333.cos.ap-guangzhou.myqcloud.com/xuexiaoleClient
|
||||
VITE_WS_URL = wss://test.pi.xuexiaole.com/ws/device
|
@ -1,3 +1,3 @@
|
||||
VITE_HOST = https://test.pi.xuexiaole.com
|
||||
VITE_HOST = http://test.xuexiaole.com:8053
|
||||
VITE_OSS_HOST = https://xuexiaole-1313840333.cos.ap-guangzhou.myqcloud.com/xuexiaoleClient
|
||||
VITE_WS_URL = wss://test.pi.xuexiaole.com/ws/device
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,6 +6,8 @@ yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
.temp
|
||||
*.gz
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
|
@ -2,12 +2,13 @@ module.exports = {
|
||||
printWidth: 100,
|
||||
tabWidth: 2,
|
||||
useTabs: false,
|
||||
semi: true,
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
jsxSingleQuote: true,
|
||||
bracketSpacing: true,
|
||||
bracketSameLine: false,
|
||||
arrowParens: 'avoid',
|
||||
trailingComma: 'all',
|
||||
vueIndentScriptAndStyle: false,
|
||||
endOfLine: 'lf',
|
||||
};
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -47,5 +47,6 @@
|
||||
"src/uni_modules/uni-popup/components/uni-popup/i18n",
|
||||
"src/uni_modules/uni-search-bar/components/uni-search-bar/i18n",
|
||||
"src/uni_modules/z-paging/components/z-paging/i18n"
|
||||
]
|
||||
],
|
||||
"cSpell.words": ["xuexiaole"]
|
||||
}
|
||||
|
BIN
client-dist.zip
BIN
client-dist.zip
Binary file not shown.
28
package.json
28
package.json
@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "xuexiaole-client",
|
||||
"name": "xuexiaole-mobile",
|
||||
"version": "0.1.0",
|
||||
"scripts": {
|
||||
"dev:app": "uni -p app",
|
||||
"dev:app-android": "uni -p app-android",
|
||||
"dev:app-ios": "uni -p app-ios",
|
||||
"dev:custom": "uni -p",
|
||||
"dev:h5": "uni -p h5-test",
|
||||
"dev:h5": "uni --mode dev",
|
||||
"dev:h5-mp": "uni --mode mp",
|
||||
"dev:h5:ssr": "uni --ssr",
|
||||
"dev:mp-alipay": "uni -p mp-alipay",
|
||||
"dev:mp-baidu": "uni -p mp-baidu",
|
||||
@ -56,16 +57,17 @@
|
||||
"@dcloudio/uni-mp-toutiao": "3.0.0-3081220230817001",
|
||||
"@dcloudio/uni-mp-weixin": "3.0.0-3081220230817001",
|
||||
"@dcloudio/uni-quickapp-webview": "3.0.0-3081220230817001",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"code-inspector-plugin": "^0.10.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"echarts": "^5.5.1",
|
||||
"lint-staged": "^15.0.1",
|
||||
"pinia": "^2.0.36",
|
||||
"qs": "^6.14.0",
|
||||
"sass": "^1.72.0",
|
||||
"unplugin-vue-define-options": "^1.4.2",
|
||||
"vue": "^3.3.4",
|
||||
"vue-i18n": "^9.1.9",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"vue-qrcode-reader": "^5.5.7",
|
||||
"weixin-js-sdk": "^1.6.5"
|
||||
},
|
||||
@ -102,25 +104,5 @@
|
||||
"prettier --write",
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"uni-app": {
|
||||
"scripts": {
|
||||
"h5-test": {
|
||||
"title": "h5-test",
|
||||
"env": {
|
||||
"UNI_PLATFORM": "h5",
|
||||
"VITE_HOST": "https://test.pi.xuexiaole.com",
|
||||
"VITE_WS_URL": "wss://test.pi.xuexiaole.com/ws/device"
|
||||
}
|
||||
},
|
||||
"h5-prod": {
|
||||
"title": "h5-prod",
|
||||
"env": {
|
||||
"UNI_PLATFORM": "h5",
|
||||
"VITE_HOST": "https://pi.xuexiaole.com",
|
||||
"VITE_WS_URL": "wss://pi.xuexiaole.com/ws/device"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
498
pnpm-lock.yaml
generated
498
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
17
src/App.vue
17
src/App.vue
@ -1,16 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, nextTick } from 'vue';
|
||||
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app';
|
||||
import { onMounted, nextTick } from 'vue'
|
||||
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
||||
import { parseUrlParams } from '@/utils/tool'
|
||||
|
||||
onLaunch(() => {
|
||||
console.log('App Launch');
|
||||
});
|
||||
console.log('App Launch')
|
||||
})
|
||||
onShow(() => {
|
||||
console.log('App Show');
|
||||
});
|
||||
console.log('App Show')
|
||||
})
|
||||
onHide(() => {
|
||||
console.log('App Hide');
|
||||
});
|
||||
console.log('App Hide')
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
page {
|
||||
|
@ -39,7 +39,10 @@ export const smsLoginApi = data =>
|
||||
$req({
|
||||
method: 'post',
|
||||
url: '/smsLogin',
|
||||
data,
|
||||
data: {
|
||||
...data,
|
||||
clientType: 'MOBILE',
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -1,14 +1,15 @@
|
||||
import $req from '../request';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { user } from '@/store';
|
||||
import { getCache } from '@/utils';
|
||||
import $req from '../request'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { user } from '@/store'
|
||||
import { getCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
// 课表日历
|
||||
export const getScheduleList = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: '/phone/inspectorTeacher/getCourseTableById',
|
||||
data,
|
||||
});
|
||||
})
|
||||
|
||||
// 查询指定日期学生数据
|
||||
export const getCourseDate = (data?: Record<string, any>): Promise<any> =>
|
||||
@ -18,28 +19,28 @@ export const getCourseDate = (data?: Record<string, any>): Promise<any> =>
|
||||
`/phone/inspectorTeacher/getCourseTabletStudentVoByTime` +
|
||||
`${data.date ? `?courseDate=${data.date}` : ''}`,
|
||||
// data,
|
||||
});
|
||||
})
|
||||
|
||||
// 开始督学
|
||||
export const startInpector = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'post',
|
||||
url: `/phone/inspectorTeacher/startInspector?courseDate=${data.courseDate}`,
|
||||
});
|
||||
})
|
||||
|
||||
// 结束督学
|
||||
export const endInpector = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'post',
|
||||
url: `/phone/inspectorTeacher/endInspector?courseDate=${data.courseDate}`,
|
||||
});
|
||||
})
|
||||
|
||||
// 督学实况
|
||||
export const condition = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'post',
|
||||
url: `/phone/inspectorTeacher/inspector_real?courseDate=${data.courseDate}`,
|
||||
});
|
||||
})
|
||||
|
||||
// 获取学员课表日历
|
||||
export const getCourseData = (data?: Record<string, any>): Promise<any> =>
|
||||
@ -47,33 +48,33 @@ export const getCourseData = (data?: Record<string, any>): Promise<any> =>
|
||||
method: 'get',
|
||||
url: `/phone/inspectorTeacher/getStuCourseTable?userId=${data.id}`,
|
||||
// data,
|
||||
});
|
||||
})
|
||||
|
||||
// 获取学科
|
||||
export const getSubject = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/subject/list/${data.gradeId}`,
|
||||
});
|
||||
})
|
||||
// 获取学科教材
|
||||
export const getBooks = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/userTextBook/list?gradeId=${data.gradeId}&subjectId=${data.subjectId}&userId=${data.userId}¤t=${data.current}`,
|
||||
});
|
||||
})
|
||||
|
||||
// 获取教材章节
|
||||
export const getChaper = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/subjectChapter/tree?textBookId=${data.textBookId}`,
|
||||
});
|
||||
})
|
||||
// 获取教材章节知识点
|
||||
export const getKnowledge = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/subjectKnowledge/tree?chapterId=${data.chapterId}`,
|
||||
});
|
||||
})
|
||||
|
||||
// 发布计划
|
||||
export const publishPlan = (data?: Record<string, any>): Promise<any> =>
|
||||
@ -81,25 +82,25 @@ export const publishPlan = (data?: Record<string, any>): Promise<any> =>
|
||||
method: 'post',
|
||||
url: `/phone/inspectorTeacher/publishPlan`,
|
||||
data,
|
||||
});
|
||||
})
|
||||
// 获取学员计划
|
||||
export const getStuPlan = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/phone/inspectorTeacher/getStuPlanByDate?userId=${data.userId}&courseDate=${data.courseDate}`,
|
||||
});
|
||||
})
|
||||
|
||||
// 获取督学师信息
|
||||
export const getUserInfo = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/phone/inspectorTeacher/getCurrentTeacher`,
|
||||
});
|
||||
})
|
||||
// 文件上传
|
||||
export const uploadFile = async (file): Promise<any> => {
|
||||
const { token } = storeToRefs(user());
|
||||
const { token } = storeToRefs(user())
|
||||
|
||||
const mergerToken = token.value || getCache('token');
|
||||
const mergerToken = token.value || db.get('token')
|
||||
|
||||
const data = await uni.uploadFile({
|
||||
url: `/api/main/sysFileInfo/tenUploadAll`, // ${import.meta.env.VITE_HOST}
|
||||
@ -109,9 +110,9 @@ export const uploadFile = async (file): Promise<any> => {
|
||||
// 'content-type': 'multipart/form-data',
|
||||
Authorization: mergerToken ? `Bearer ${mergerToken}` : token,
|
||||
},
|
||||
});
|
||||
return JSON.parse(data.data);
|
||||
};
|
||||
})
|
||||
return JSON.parse(data.data)
|
||||
}
|
||||
|
||||
// 完善督学师资料 /phone/inspectorTeacher/updateTeacherInfo
|
||||
export const updateTeacherInfo = (data?: Record<string, any>): Promise<any> =>
|
||||
@ -119,25 +120,25 @@ export const updateTeacherInfo = (data?: Record<string, any>): Promise<any> =>
|
||||
method: 'post',
|
||||
url: `/phone/inspectorTeacher/updateTeacherInfo`,
|
||||
data,
|
||||
});
|
||||
})
|
||||
|
||||
// 沟通列表
|
||||
export const getTalkList = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/phone/inspectorTeacher/inspectorTalkListPage?current=${data.current}`,
|
||||
});
|
||||
})
|
||||
|
||||
// 沟通详情
|
||||
export const getTalkDetails = (data?: Record<string, any>): Promise<any> => {
|
||||
const param = data.inspectorTalkRecordId
|
||||
? `?inspectorTalkRecordId=${data.inspectorTalkRecordId}&userId=${data.userId}`
|
||||
: `?userId=${data.userId}`;
|
||||
: `?userId=${data.userId}`
|
||||
return $req({
|
||||
method: 'get',
|
||||
url: `/phone/inspectorTeacher/studentInspectorTalkPage${param}`,
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
// 消息存储
|
||||
export const saveTalk = (data?: Record<string, any>): Promise<any> =>
|
||||
@ -145,7 +146,7 @@ export const saveTalk = (data?: Record<string, any>): Promise<any> =>
|
||||
method: 'post',
|
||||
url: `/inspectorStudent/sendInspectorTalkRecord`,
|
||||
data,
|
||||
});
|
||||
})
|
||||
|
||||
// 验证码校验
|
||||
export const validCode = (data?: Record<string, any>): Promise<any> =>
|
||||
@ -153,13 +154,13 @@ export const validCode = (data?: Record<string, any>): Promise<any> =>
|
||||
method: 'post',
|
||||
url: `/sms/validateMessage?phoneNumbers=${data.phone}&code=${data.code}`,
|
||||
data,
|
||||
});
|
||||
})
|
||||
// 获取我的未读信息
|
||||
export const getUnreadCount = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/phone/inspectorTeacher/myUnreadCount`,
|
||||
});
|
||||
})
|
||||
|
||||
// 消息标记为已读
|
||||
export const readMsg = (data?: Record<string, any>): Promise<any> =>
|
||||
@ -167,31 +168,31 @@ export const readMsg = (data?: Record<string, any>): Promise<any> =>
|
||||
method: 'post',
|
||||
url: `/inspectorStudent/readTalkRecord`,
|
||||
data,
|
||||
});
|
||||
})
|
||||
|
||||
// 督学师是否已完善资料
|
||||
export const needPerfectInfo = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/phone/inspectorTeacher/is_perfect`,
|
||||
});
|
||||
})
|
||||
// 学生是否可以进行精准学判断
|
||||
export const getPrecisionFlag = (data?: Record<string, any>): Promise<any> =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/userTrainTitle/airPrecisionFlag?subjectId=${data.subjectId}&userId=${data.userId}`,
|
||||
});
|
||||
})
|
||||
|
||||
export const getKnowledgeFlag = (knowledgeId: string): Promise<boolean> => {
|
||||
return $req({
|
||||
method: 'get',
|
||||
url: `/subjectKnowledge/titleFlag?id=${knowledgeId}`,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
export const getKnowledgeVideo = (chapterId: string | number): Promise<any> => {
|
||||
return $req({
|
||||
method: 'get',
|
||||
url: `/subjectChapterVideo/list?chapterId=${chapterId}`,
|
||||
});
|
||||
})
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import $req from '../request';
|
||||
import $req from '../request'
|
||||
import { request } from '../request/request'
|
||||
|
||||
/**
|
||||
* 家长绑定的孩子
|
||||
@ -9,17 +10,13 @@ export const getParentBindChildApi = (params: anyObj) =>
|
||||
method: 'get',
|
||||
url: '/parentBindChild/list',
|
||||
params,
|
||||
});
|
||||
})
|
||||
/**
|
||||
* 家长绑定的设备
|
||||
* @param params 请求参数
|
||||
*/
|
||||
export const getParentBindDeviceApi = (params: anyObj) =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: '/parentBindDevice/list',
|
||||
params,
|
||||
});
|
||||
export const getParentBindDeviceApi = async (params: anyObj) =>
|
||||
await request.get<any>('/parentBindDevice/list', params)
|
||||
/**
|
||||
* 我的孩子-绑定的家长
|
||||
* @param params 请求参数
|
||||
@ -28,7 +25,7 @@ export const parentBindChildApi = (id: string) =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/parentBindChild/${id}`,
|
||||
});
|
||||
})
|
||||
/**
|
||||
* 我的孩子-解除绑定家长
|
||||
* @param params 请求参数
|
||||
@ -38,7 +35,7 @@ export const childUnBoundParentApi = (data: anyObj) =>
|
||||
method: 'post',
|
||||
url: '/parentBindChild/unBound',
|
||||
data,
|
||||
});
|
||||
})
|
||||
/**
|
||||
* 我的设备-解除绑定
|
||||
* @param params 请求参数
|
||||
@ -48,16 +45,14 @@ export const parentUnBoundDeviceApi = (data: anyObj) =>
|
||||
method: 'post',
|
||||
url: '/parentBindDevice/unBound',
|
||||
data,
|
||||
});
|
||||
})
|
||||
/**
|
||||
* 我的设备-当前登录
|
||||
* @param params 请求参数
|
||||
*/
|
||||
export const parentDeviceCurrentLoginApi = (id: string) =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: `/parentBindDevice/${id}`,
|
||||
});
|
||||
export const parentDeviceCurrentLoginApi = async (id: string) =>
|
||||
await request.get<any>(`/parentBindDevice/${id}`)
|
||||
|
||||
/**
|
||||
* 设备管理-绑定申请列表
|
||||
* @param params 请求参数
|
||||
@ -66,7 +61,7 @@ export const applyBindInfoListApi = () =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: '/parentBind/applyInfoList',
|
||||
});
|
||||
})
|
||||
/**
|
||||
* 设备管理-当前登录用户是否管理员
|
||||
* @param params 请求参数
|
||||
@ -75,4 +70,4 @@ export const userInfoPermitApi = () =>
|
||||
$req({
|
||||
method: 'get',
|
||||
url: '/parentBind/applyInfoPermit',
|
||||
});
|
||||
})
|
||||
|
@ -1,44 +1,44 @@
|
||||
import { user } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getCache } from '@/utils';
|
||||
import { user } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { getCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
|
||||
const CONFIG = {
|
||||
// host: import.meta.env.VITE_HOST || '',
|
||||
// baseURL: 'http://127.0.0.1:9053/api/main',
|
||||
baseURL: '/api/main',
|
||||
baseURL: `${import.meta.env.VITE_HOST}/api/main`,
|
||||
// baseURL: '/api/main',
|
||||
timeout: 60000,
|
||||
method: 'GET',
|
||||
};
|
||||
}
|
||||
|
||||
export class HttpError extends Error {
|
||||
data: any;
|
||||
data: any
|
||||
constructor(message: string, data: Record<string, any>) {
|
||||
super(message);
|
||||
this.data = data;
|
||||
super(message)
|
||||
this.data = data
|
||||
}
|
||||
}
|
||||
|
||||
const request = async (config: Record<string, any>): Promise<any> => {
|
||||
const networkType = await uni.getNetworkType();
|
||||
const networkType = await uni.getNetworkType()
|
||||
if (networkType.networkType === 'none') {
|
||||
uni.showModal({
|
||||
content: '暂无网络,请恢复网络后使用',
|
||||
confirmText: '知道了',
|
||||
showCancel: false,
|
||||
confirmColor: '#ffe60f',
|
||||
});
|
||||
})
|
||||
return Promise.reject(
|
||||
new HttpError('暂无网络,请恢复网络后使用', {
|
||||
code: '-1',
|
||||
}),
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const { clear } = user();
|
||||
const { token } = storeToRefs(user());
|
||||
const mergerToken = token.value || getCache('token');
|
||||
const method = (config.method || CONFIG.method).toUpperCase();
|
||||
const { clear } = user()
|
||||
const { token } = storeToRefs(user())
|
||||
const mergerToken = token.value || db.get('token')
|
||||
const method = (config.method || CONFIG.method).toUpperCase()
|
||||
|
||||
uni.request({
|
||||
method,
|
||||
@ -53,41 +53,41 @@ const request = async (config: Record<string, any>): Promise<any> => {
|
||||
complete(res: anyObj) {
|
||||
if (res.statusCode === 200) {
|
||||
if (res.data.code === 200) {
|
||||
return resolve(res.data);
|
||||
return resolve(res.data)
|
||||
} else {
|
||||
if (!config.showToast) {
|
||||
uni.showToast({
|
||||
title: res.data?.message,
|
||||
icon: 'none',
|
||||
duration: 3000,
|
||||
});
|
||||
})
|
||||
}
|
||||
return reject(new HttpError(res.data?.message, res.data));
|
||||
return reject(new HttpError(res.data?.message, res.data))
|
||||
}
|
||||
} else {
|
||||
res.href = (config.baseURL || CONFIG.baseURL) + config.url;
|
||||
res.href = (config.baseURL || CONFIG.baseURL) + config.url
|
||||
if (res.statusCode === 401) {
|
||||
clear();
|
||||
clear()
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/index',
|
||||
});
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title:
|
||||
res.statusCode === 500 ? '服务异常' : res?.data?.message || '服务异常,请稍后重试',
|
||||
});
|
||||
})
|
||||
}
|
||||
return reject(
|
||||
new HttpError(res.data?.message, {
|
||||
code: res.statusCode,
|
||||
data: res.data,
|
||||
}),
|
||||
);
|
||||
)
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default request;
|
||||
export default request
|
||||
|
29
src/api/request/config.ts
Normal file
29
src/api/request/config.ts
Normal file
@ -0,0 +1,29 @@
|
||||
// 基础配置
|
||||
export const BASE_URL = `${import.meta.env.VITE_HOST}/api/main` // 基础URL
|
||||
export const REQUEST_TIMEOUT = 10000 // 10秒超时
|
||||
|
||||
// 状态码
|
||||
export const HTTP_STATUS = {
|
||||
SUCCESS: 200,
|
||||
CREATED: 201,
|
||||
ACCEPTED: 202,
|
||||
CLIENT_ERROR: 400,
|
||||
AUTHENTICATE: 401,
|
||||
FORBIDDEN: 403,
|
||||
NOT_FOUND: 404,
|
||||
SERVER_ERROR: 500,
|
||||
BAD_GATEWAY: 502,
|
||||
SERVICE_UNAVAILABLE: 503,
|
||||
GATEWAY_TIMEOUT: 504,
|
||||
}
|
||||
|
||||
// 错误信息
|
||||
export const ERROR_MSG = {
|
||||
NETWORK_ERROR: '网络异常,请检查网络连接',
|
||||
TIMEOUT_ERROR: '请求超时,请稍后重试',
|
||||
SERVER_ERROR: '服务器异常,请稍后重试',
|
||||
AUTH_ERROR: '登录状态已过期,请重新登录',
|
||||
FORBIDDEN_ERROR: '没有权限访问该资源',
|
||||
NOT_FOUND_ERROR: '请求的资源不存在',
|
||||
DEFAULT_ERROR: '请求失败,请稍后重试',
|
||||
}
|
98
src/api/request/interceptor.ts
Normal file
98
src/api/request/interceptor.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import { type RequestOptions, type ResponseData, type ErrorResponse } from './types'
|
||||
import { HTTP_STATUS, ERROR_MSG } from './config'
|
||||
import router from '@/router/router'
|
||||
import db from '@/utils/db'
|
||||
import toast from '@/utils/toast'
|
||||
|
||||
// 请求拦截器
|
||||
export const requestInterceptor = async (options: RequestOptions): Promise<RequestOptions> => {
|
||||
// 设置请求头
|
||||
const header: any = {
|
||||
...options?.header,
|
||||
}
|
||||
|
||||
// 获取token
|
||||
const token = db.get('token')
|
||||
// 如果有token,添加到请求头
|
||||
if (token) {
|
||||
header['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
|
||||
return {
|
||||
...options,
|
||||
header,
|
||||
}
|
||||
}
|
||||
|
||||
// 响应拦截器
|
||||
export const responseInterceptor = async <T>(
|
||||
response: ResponseData<T>,
|
||||
): Promise<ResponseData<T>> => {
|
||||
const { statusCode, data } = response as any
|
||||
console.log('response', response)
|
||||
|
||||
// 处理成功响应
|
||||
if (statusCode === HTTP_STATUS.SUCCESS) {
|
||||
if (data.code === 200) return response
|
||||
throw {
|
||||
statusCode,
|
||||
errMsg: data.data,
|
||||
}
|
||||
} else {
|
||||
throw {
|
||||
statusCode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 错误拦截器
|
||||
export const errorInterceptor = (error: any): Promise<ErrorResponse> => {
|
||||
let message
|
||||
const { statusCode, errMsg } = error
|
||||
let toLogin = false
|
||||
if (statusCode === HTTP_STATUS.SUCCESS) {
|
||||
message = errMsg
|
||||
} else {
|
||||
// 处理特定状态码
|
||||
switch (error.statusCode) {
|
||||
case HTTP_STATUS.AUTHENTICATE:
|
||||
toLogin = true
|
||||
message = ERROR_MSG.AUTH_ERROR
|
||||
break
|
||||
|
||||
case HTTP_STATUS.FORBIDDEN:
|
||||
toLogin = true
|
||||
message = ERROR_MSG.FORBIDDEN_ERROR
|
||||
break
|
||||
|
||||
case HTTP_STATUS.NOT_FOUND:
|
||||
message = ERROR_MSG.NOT_FOUND_ERROR
|
||||
break
|
||||
|
||||
case HTTP_STATUS.SERVER_ERROR:
|
||||
case HTTP_STATUS.BAD_GATEWAY:
|
||||
case HTTP_STATUS.SERVICE_UNAVAILABLE:
|
||||
case HTTP_STATUS.GATEWAY_TIMEOUT:
|
||||
message = ERROR_MSG.SERVER_ERROR
|
||||
break
|
||||
|
||||
default:
|
||||
message = ERROR_MSG.DEFAULT_ERROR
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 显示错误提示
|
||||
if (message) {
|
||||
toast.error(message)
|
||||
if (toLogin) {
|
||||
router.toLogin()
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject({
|
||||
code: -1,
|
||||
message,
|
||||
data: error,
|
||||
})
|
||||
}
|
75
src/api/request/request.ts
Normal file
75
src/api/request/request.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import { type RequestOptions, type ResponseData } from './types'
|
||||
import { BASE_URL, REQUEST_TIMEOUT } from './config'
|
||||
import { requestInterceptor, responseInterceptor, errorInterceptor } from './interceptor'
|
||||
import obj from '@/utils/obj'
|
||||
|
||||
class HttpRequest {
|
||||
private baseURL: string
|
||||
private timeout: number
|
||||
|
||||
constructor() {
|
||||
this.baseURL = BASE_URL
|
||||
this.timeout = REQUEST_TIMEOUT
|
||||
}
|
||||
|
||||
public async http<T>(options: RequestOptions): Promise<T> {
|
||||
try {
|
||||
obj.clearNullProps(options.data)
|
||||
const interceptedOptions = await requestInterceptor(options)
|
||||
// URL处理
|
||||
let url = this.baseURL + interceptedOptions.url
|
||||
const response = (await uni.request({
|
||||
...interceptedOptions,
|
||||
url,
|
||||
timeout: this.timeout,
|
||||
})) as unknown as ResponseData<T>
|
||||
|
||||
return (await responseInterceptor(response)).data
|
||||
} catch (error) {
|
||||
return errorInterceptor(error) as any
|
||||
}
|
||||
}
|
||||
|
||||
public async get<T>(url: string, data?: any, options: Partial<RequestOptions> = {}): Promise<T> {
|
||||
return this.http<T>({
|
||||
url,
|
||||
data,
|
||||
method: 'GET',
|
||||
...options,
|
||||
})
|
||||
}
|
||||
|
||||
// 默认是json格式
|
||||
public async post<T>(url: string, data?: any, options: Partial<RequestOptions> = {}): Promise<T> {
|
||||
return this.http<T>({
|
||||
url,
|
||||
data,
|
||||
method: 'POST',
|
||||
...options,
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
...options.header,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 表单格式
|
||||
public async postForm<T>(
|
||||
url: string,
|
||||
data?: any,
|
||||
options: Partial<RequestOptions> = {},
|
||||
): Promise<T> {
|
||||
return this.http<T>({
|
||||
url,
|
||||
data,
|
||||
method: 'POST',
|
||||
...options,
|
||||
header: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
...options.header,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const request = new HttpRequest()
|
28
src/api/request/types.ts
Normal file
28
src/api/request/types.ts
Normal file
@ -0,0 +1,28 @@
|
||||
// 请求方法类型
|
||||
export type Method = 'GET' | 'POST' | 'PUT' | 'DELETE'
|
||||
|
||||
// 请求配置接口
|
||||
export interface RequestOptions {
|
||||
url: string
|
||||
method: Method
|
||||
data?: any
|
||||
header?: Record<string, string>
|
||||
timeout?: number
|
||||
dataType?: string
|
||||
responseType?: string
|
||||
}
|
||||
|
||||
// 响应数据接口
|
||||
export interface ResponseData<T = any> {
|
||||
data: T
|
||||
statusCode: number
|
||||
header: Record<string, string>
|
||||
errMsg?: string
|
||||
}
|
||||
|
||||
// 错误响应接口
|
||||
export interface ErrorResponse {
|
||||
code: number
|
||||
message: string
|
||||
data?: any
|
||||
}
|
@ -22,38 +22,37 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { bindApplyStore } from '@/store';
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { bindApplyStore } from '@/store'
|
||||
|
||||
import { getCache } from '@/utils';
|
||||
import { getCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
selectedIndex: number;
|
||||
selectedIndex: number
|
||||
}>(),
|
||||
{ selectedIndex: 0 },
|
||||
);
|
||||
const { getApplyBindInfoList } = bindApplyStore();
|
||||
)
|
||||
const { getApplyBindInfoList } = bindApplyStore()
|
||||
|
||||
const currentIndex = ref(0);
|
||||
const list = ref([]);
|
||||
const color = ref<string>('#8E8D9D');
|
||||
const selectedColor = ref<string>('#625EFF');
|
||||
const notice = ref(false);
|
||||
const currentIndex = ref(0)
|
||||
const list = ref([])
|
||||
const color = ref<string>('#8E8D9D')
|
||||
const selectedColor = ref<string>('#625EFF')
|
||||
const notice = ref(false)
|
||||
function switchTab(item, index) {
|
||||
currentIndex.value = index;
|
||||
let url = item.pagePath;
|
||||
uni.redirectTo({ url: url });
|
||||
currentIndex.value = index
|
||||
let url = item.pagePath
|
||||
uni.redirectTo({ url: url })
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
currentIndex.value = props.selectedIndex;
|
||||
let adminType = getCache('userInfo').adminType;
|
||||
if (adminType === 16) {
|
||||
currentIndex.value = props.selectedIndex
|
||||
// 家长
|
||||
await getApplyBindInfoList();
|
||||
notice.value = getCache('applyBindMsg');
|
||||
await getApplyBindInfoList()
|
||||
notice.value = db.get('applyBindMsg')
|
||||
list.value = [
|
||||
{
|
||||
pagePath: '/pages/home/index',
|
||||
@ -79,34 +78,66 @@ onMounted(async () => {
|
||||
selectedIconPath: '/static/tabBar/mine.png',
|
||||
text: '我的',
|
||||
},
|
||||
];
|
||||
} else if (adminType === 6) {
|
||||
// 督学
|
||||
uni.reLaunch({
|
||||
url: '/pages/inspector/schedule/index',
|
||||
});
|
||||
list.value = [
|
||||
{
|
||||
pagePath: '/pages/inspector/schedule/index',
|
||||
iconPath: '/static/tabBar/scheduleNo.png',
|
||||
selectedIconPath: '/static/tabBar/schedule.png',
|
||||
text: '课表',
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/inspector/student/index',
|
||||
iconPath: '/static/tabBar/studentNo.png',
|
||||
selectedIconPath: '/static/tabBar/student.png',
|
||||
text: '学员',
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/inspector/mine/index',
|
||||
iconPath: '/static/tabBar/mineno.png',
|
||||
selectedIconPath: '/static/tabBar/mine.png',
|
||||
text: '我的',
|
||||
},
|
||||
];
|
||||
}
|
||||
});
|
||||
]
|
||||
|
||||
// let adminType = getCache('userInfo').adminType;
|
||||
// if (adminType === 16) {
|
||||
// // 家长
|
||||
// await getApplyBindInfoList();
|
||||
// notice.value = getCache('applyBindMsg');
|
||||
// list.value = [
|
||||
// {
|
||||
// pagePath: '/pages/home/index',
|
||||
// iconPath: '/static/tabBar/homeno.png',
|
||||
// selectedIconPath: '/static/tabBar/home.png',
|
||||
// text: '首页',
|
||||
// },
|
||||
// {
|
||||
// pagePath: '/pages/academicReport/index',
|
||||
// iconPath: '/static/tabBar/studyReportNo.png',
|
||||
// selectedIconPath: '/static/tabBar/studyReport.png',
|
||||
// text: '学情报告',
|
||||
// },
|
||||
// {
|
||||
// pagePath: '/pages/applicationManagement/index',
|
||||
// iconPath: '/static/tabBar/applicationNo.png',
|
||||
// selectedIconPath: '/static/tabBar/application.png',
|
||||
// text: '应用管控',
|
||||
// },
|
||||
// {
|
||||
// pagePath: '/pages/mine/index',
|
||||
// iconPath: '/static/tabBar/mineno.png',
|
||||
// selectedIconPath: '/static/tabBar/mine.png',
|
||||
// text: '我的',
|
||||
// },
|
||||
// ];
|
||||
// } else if (adminType === 6) {
|
||||
// // 督学
|
||||
// uni.reLaunch({
|
||||
// url: '/pages/inspector/schedule/index',
|
||||
// });
|
||||
// list.value = [
|
||||
// {
|
||||
// pagePath: '/pages/inspector/schedule/index',
|
||||
// iconPath: '/static/tabBar/scheduleNo.png',
|
||||
// selectedIconPath: '/static/tabBar/schedule.png',
|
||||
// text: '课表',
|
||||
// },
|
||||
// {
|
||||
// pagePath: '/pages/inspector/student/index',
|
||||
// iconPath: '/static/tabBar/studentNo.png',
|
||||
// selectedIconPath: '/static/tabBar/student.png',
|
||||
// text: '学员',
|
||||
// },
|
||||
// {
|
||||
// pagePath: '/pages/inspector/mine/index',
|
||||
// iconPath: '/static/tabBar/mineno.png',
|
||||
// selectedIconPath: '/static/tabBar/mine.png',
|
||||
// text: '我的',
|
||||
// },
|
||||
// ];
|
||||
// }
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -1,2 +1,2 @@
|
||||
export * from './useKey';
|
||||
export * from './useTools';
|
||||
export * from './useKey'
|
||||
export * from './useTools'
|
||||
|
@ -32,61 +32,61 @@
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import Empty from '@/components/Empty/index.vue';
|
||||
import ChildrenBox from './components/childrenBox.vue';
|
||||
import SubjectFilter from './components/subjectFilter.vue';
|
||||
import TabBar from '@/components/Tabbar/index.vue';
|
||||
import StudyTime from './components/studyTime.vue';
|
||||
import VideoTime from './components/videoTime.vue';
|
||||
import KnowledgeChart from './components/knowledgeChart.vue';
|
||||
import ExerciseStatistics from './components/exerciseStatistics.vue';
|
||||
import LanguageStatistics from './components/languageStatistics.vue';
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import Empty from '@/components/Empty/index.vue'
|
||||
import ChildrenBox from './components/childrenBox.vue'
|
||||
import SubjectFilter from './components/subjectFilter.vue'
|
||||
import TabBar from '@/components/Tabbar/index.vue'
|
||||
import StudyTime from './components/studyTime.vue'
|
||||
import VideoTime from './components/videoTime.vue'
|
||||
import KnowledgeChart from './components/knowledgeChart.vue'
|
||||
import ExerciseStatistics from './components/exerciseStatistics.vue'
|
||||
import LanguageStatistics from './components/languageStatistics.vue'
|
||||
|
||||
import type { ChildrenType } from '@/pages/mine/interface';
|
||||
import type { SubjectType, StudyTimeType } from './interface';
|
||||
import './index.scss';
|
||||
import { getParentBindChildApi, subjectApi } from '@/api';
|
||||
import { user } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import type { ChildrenType } from '@/pages/mine/interface'
|
||||
import type { SubjectType, StudyTimeType } from './interface'
|
||||
import './index.scss'
|
||||
import { getParentBindChildApi, subjectApi } from '@/api'
|
||||
import { user } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
const { userInfo } = storeToRefs(user());
|
||||
const { userInfo } = storeToRefs(user())
|
||||
|
||||
const childrenList = ref<ChildrenType[]>(); // 所有孩子
|
||||
const empty = ref(false);
|
||||
const showChildrenInfo = ref<ChildrenType>(); // 展示的孩子
|
||||
const subjectList = ref<SubjectType[]>(); // 学科
|
||||
const childrenList = ref<ChildrenType[]>() // 所有孩子
|
||||
const empty = ref(false)
|
||||
const showChildrenInfo = ref<ChildrenType>() // 展示的孩子
|
||||
const subjectList = ref<SubjectType[]>() // 学科
|
||||
|
||||
const chooseSubject = ref<SubjectType>(); // 选中学科
|
||||
const chooseSubject = ref<SubjectType>() // 选中学科
|
||||
|
||||
async function handleUpdateShowChild(val: ChildrenType) {
|
||||
showChildrenInfo.value = val;
|
||||
showChildrenInfo.value = val
|
||||
chooseSubject.value = {
|
||||
name: '',
|
||||
pictureUrl: '',
|
||||
subject: '',
|
||||
subjectId: undefined,
|
||||
};
|
||||
}
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
});
|
||||
await getSubject();
|
||||
})
|
||||
await getSubject()
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
// 学科选择
|
||||
function tapFilterSubject(i: SubjectType) {
|
||||
chooseSubject.value = i;
|
||||
chooseSubject.value = i
|
||||
}
|
||||
|
||||
// 孩子列表
|
||||
async function getParentBindChild() {
|
||||
const { data } = await getParentBindChildApi({ parentId: userInfo.value.id, size: -1 });
|
||||
empty.value = data.rows.length === 0 ? true : false;
|
||||
childrenList.value = data.rows;
|
||||
showChildrenInfo.value = data.rows[0];
|
||||
const { data } = await getParentBindChildApi({ parentId: userInfo.value.id, size: -1 })
|
||||
empty.value = data.rows.length === 0 ? true : false
|
||||
childrenList.value = data.rows
|
||||
showChildrenInfo.value = data.rows[0]
|
||||
}
|
||||
// 学科列表
|
||||
async function getSubject() {
|
||||
@ -94,25 +94,25 @@ async function getSubject() {
|
||||
uni.showToast({
|
||||
title: '当前学生无年级,无法查看学情报告',
|
||||
icon: 'none',
|
||||
});
|
||||
subjectList.value = [];
|
||||
return;
|
||||
})
|
||||
subjectList.value = []
|
||||
return
|
||||
}
|
||||
const { data } = await subjectApi(showChildrenInfo.value.gradeId);
|
||||
subjectList.value = data;
|
||||
chooseSubject.value = data[0];
|
||||
const { data } = await subjectApi(showChildrenInfo.value.gradeId)
|
||||
subjectList.value = data
|
||||
chooseSubject.value = data[0]
|
||||
}
|
||||
onMounted(async () => {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
});
|
||||
await getParentBindChild();
|
||||
await getSubject();
|
||||
})
|
||||
await getParentBindChild()
|
||||
await getSubject()
|
||||
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
} catch (err) {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
@ -272,6 +272,8 @@ async function deviceCurrentLogin(id: string) {
|
||||
}
|
||||
// 设备应用
|
||||
async function fetchAppRecord() {
|
||||
// 序列号不存在
|
||||
if (!showEquipment.value.simSerialNumber) return;
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
|
@ -77,21 +77,22 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { getParentBindDeviceApi, parentDeviceCurrentLoginApi } from '@/api';
|
||||
import TabBar from '@/components/Tabbar/index.vue';
|
||||
import { user } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import HomeBanner from '@/pages/home/banner/HomeBanner.vue';
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { getParentBindDeviceApi, parentDeviceCurrentLoginApi } from '@/api'
|
||||
import TabBar from '@/components/Tabbar/index.vue'
|
||||
import { user } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import HomeBanner from '@/pages/home/banner/HomeBanner.vue'
|
||||
import toast from '@/utils/toast'
|
||||
|
||||
const { userInfo } = storeToRefs(user());
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const scanQr = `${OSS_URL}/iconfont/scan_qr.png`;
|
||||
const arrow = `${OSS_URL}/iconfont/down_arrow.png`;
|
||||
const checked = `${OSS_URL}/iconfont/checked.png`;
|
||||
const unchecked = `${OSS_URL}/iconfont/unchecked.png`;
|
||||
const showAllDevice = ref(false);
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`;
|
||||
const { userInfo } = storeToRefs(user())
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const scanQr = `${OSS_URL}/iconfont/scan_qr.png`
|
||||
const arrow = `${OSS_URL}/iconfont/down_arrow.png`
|
||||
const checked = `${OSS_URL}/iconfont/checked.png`
|
||||
const unchecked = `${OSS_URL}/iconfont/unchecked.png`
|
||||
const showAllDevice = ref(false)
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
|
||||
const functionList = reactive([
|
||||
{
|
||||
@ -122,91 +123,82 @@ const functionList = reactive([
|
||||
developing: true,
|
||||
type: 3,
|
||||
},
|
||||
]);
|
||||
const equipmentList = ref([]);
|
||||
const showEquipment = ref();
|
||||
async function deviceCurrentLogin(id: string) {
|
||||
const { data } = await parentDeviceCurrentLoginApi(id);
|
||||
return data;
|
||||
}
|
||||
])
|
||||
const equipmentList = ref([])
|
||||
const showEquipment = ref()
|
||||
|
||||
// 选择设备
|
||||
function chooseEquipment(i) {
|
||||
showEquipment.value = i;
|
||||
showEquipment.value = i
|
||||
}
|
||||
|
||||
function bindDevice() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/bindDevice/index',
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 底部点击
|
||||
function change(i: any) {
|
||||
console.log('equipmentList.value', equipmentList.value.length);
|
||||
if (equipmentList.value.length === 0) {
|
||||
// uni.showToast({
|
||||
// title: '扫码绑定设备',
|
||||
// icon: 'none',
|
||||
// duration: 2000,
|
||||
// });
|
||||
uni.navigateTo({ url: '/pages/home/bindDevice/index' });
|
||||
return;
|
||||
uni.navigateTo({ url: '/pages/home/bindDevice/index' })
|
||||
return
|
||||
}
|
||||
if (i.developing) return;
|
||||
if (i.developing) return
|
||||
switch (i.type) {
|
||||
case 0:
|
||||
// 一键锁屏
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/LockScreen/index?simSerialNumber=' + showEquipment.value.simSerialNumber,
|
||||
});
|
||||
break;
|
||||
})
|
||||
break
|
||||
case 1:
|
||||
// 桌面预览
|
||||
uni.navigateTo({
|
||||
url:
|
||||
'/pages/home/DesktopPreview/index?simSerialNumber=' + showEquipment.value.simSerialNumber,
|
||||
});
|
||||
break;
|
||||
})
|
||||
break
|
||||
case 2:
|
||||
// 时间管控
|
||||
uni.navigateTo({
|
||||
url:
|
||||
'/pages/home/TimeManagement/index?simSerialNumber=' + showEquipment.value.simSerialNumber,
|
||||
});
|
||||
break;
|
||||
})
|
||||
break
|
||||
case 3:
|
||||
// 视频通话
|
||||
console.log('视频通话');
|
||||
break;
|
||||
console.log('视频通话')
|
||||
break
|
||||
}
|
||||
}
|
||||
// 我的设备
|
||||
async function getParentBindDevice() {
|
||||
equipmentList.value = [];
|
||||
equipmentList.value = []
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
mask: true,
|
||||
});
|
||||
const { data } = await getParentBindDeviceApi({ parentId: userInfo.value.id, size: -1 });
|
||||
toast.loading()
|
||||
const data = await getParentBindDeviceApi({ parentId: userInfo.value.id, size: -1 })
|
||||
for (let i in data.rows) {
|
||||
const _r = await deviceCurrentLogin(data.rows[i].id);
|
||||
const _r = await parentDeviceCurrentLoginApi(data.rows[i].id)
|
||||
equipmentList.value.push({
|
||||
...data.rows[i],
|
||||
curDeviceUserName: _r.curDeviceUserName,
|
||||
curDeviceUserAvatar: _r.curDeviceUserAvatar,
|
||||
});
|
||||
})
|
||||
}
|
||||
showEquipment.value = data.rows.length > 0 ? equipmentList.value[0] : {};
|
||||
|
||||
uni.hideLoading();
|
||||
} catch (err) {
|
||||
uni.hideLoading();
|
||||
showEquipment.value = data.rows.length > 0 ? equipmentList.value[0] : {}
|
||||
} finally {
|
||||
toast.hide()
|
||||
}
|
||||
}
|
||||
onMounted(async () => {
|
||||
getParentBindDevice();
|
||||
});
|
||||
getParentBindDevice()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -41,46 +41,47 @@
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import CustomPopup from '@/components/CustomPopup/index.vue';
|
||||
import { formatDate, getAvatarUrl, getCache } from '@/utils';
|
||||
import { onShow, onLoad, onPullDownRefresh } from '@dcloudio/uni-app';
|
||||
import { onMounted, ref, watch, computed, nextTick } from 'vue';
|
||||
import leftIcon from '@/static/svg/icon-left.svg';
|
||||
import rightIcon from '@/static/svg/icon-right.svg';
|
||||
import { getTalkDetails, saveTalk, readMsg } from '@/api/modules/inspector';
|
||||
import { useSocket } from '@/hooks/useSocket';
|
||||
import dayjs from 'dayjs';
|
||||
import Notice from '@/static/svg/notice.svg';
|
||||
import CustomPopup from '@/components/CustomPopup/index.vue'
|
||||
import { formatDate, getAvatarUrl, getCache } from '@/utils'
|
||||
import { onShow, onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { onMounted, ref, watch, computed, nextTick } from 'vue'
|
||||
import leftIcon from '@/static/svg/icon-left.svg'
|
||||
import rightIcon from '@/static/svg/icon-right.svg'
|
||||
import { getTalkDetails, saveTalk, readMsg } from '@/api/modules/inspector'
|
||||
import { useSocket } from '@/hooks/useSocket'
|
||||
import dayjs from 'dayjs'
|
||||
import Notice from '@/static/svg/notice.svg'
|
||||
import db from '@/utils/db'
|
||||
|
||||
const row = ref('');
|
||||
const scrollContainerRef = ref();
|
||||
const showNotice = ref(false);
|
||||
const { init: socketInit, inspectorMessage, sendMsg } = useSocket();
|
||||
const stuData = ref<anyObj>({});
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`;
|
||||
const current = ref(1);
|
||||
const userInfo = ref<anyObj>({});
|
||||
const chatList = ref<any[]>([]);
|
||||
const noticeText = ref<string>('');
|
||||
const row = ref('')
|
||||
const scrollContainerRef = ref()
|
||||
const showNotice = ref(false)
|
||||
const { init: socketInit, inspectorMessage, sendMsg } = useSocket()
|
||||
const stuData = ref<anyObj>({})
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const current = ref(1)
|
||||
const userInfo = ref<anyObj>({})
|
||||
const chatList = ref<any[]>([])
|
||||
const noticeText = ref<string>('')
|
||||
|
||||
interface userInfoType {
|
||||
userName: string;
|
||||
userId: string;
|
||||
userName: string
|
||||
userId: string
|
||||
}
|
||||
|
||||
const FIVE_MINUTES = 5 * 60 * 1000;
|
||||
const lastMessageTs = computed(() => dayjs(chatList.value.at(-2)?.createTime).valueOf() ?? 0);
|
||||
const content = ref('');
|
||||
const FIVE_MINUTES = 5 * 60 * 1000
|
||||
const lastMessageTs = computed(() => dayjs(chatList.value.at(-2)?.createTime).valueOf() ?? 0)
|
||||
const content = ref('')
|
||||
|
||||
const inputFouse = async () => {
|
||||
row.value = '';
|
||||
row.value = ''
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
row.value = 'item-' + (chatList.value.length - 1);
|
||||
}, 300);
|
||||
});
|
||||
};
|
||||
row.value = 'item-' + (chatList.value.length - 1)
|
||||
}, 300)
|
||||
})
|
||||
}
|
||||
|
||||
async function send() {
|
||||
const { code, data } = await saveTalk({
|
||||
@ -90,7 +91,7 @@ async function send() {
|
||||
messageType: 1,
|
||||
sender: 1,
|
||||
messageContent: content.value,
|
||||
});
|
||||
})
|
||||
if (code === 200) {
|
||||
const msg = {
|
||||
id: data.id,
|
||||
@ -103,14 +104,14 @@ async function send() {
|
||||
avatarUrl: userInfo.value.avatarUrl,
|
||||
senderName: userInfo.value.nickName,
|
||||
senderAvatarUrl: userInfo.value.avatarUrl,
|
||||
};
|
||||
}
|
||||
const newMessage = {
|
||||
sender: 1,
|
||||
messageContent: content.value,
|
||||
avatar: '',
|
||||
avatarUrl: userInfo.value.avatarUrl,
|
||||
createTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
||||
};
|
||||
}
|
||||
chatList.value = [
|
||||
...chatList.value,
|
||||
lastMessageTs.value === 0 ||
|
||||
@ -118,22 +119,22 @@ async function send() {
|
||||
? { timeDate: formatDate(newMessage.createTime), type: 'divider' }
|
||||
: null,
|
||||
newMessage,
|
||||
].filter(Boolean) as anyObj[];
|
||||
].filter(Boolean) as anyObj[]
|
||||
|
||||
sendMsg({ type: 'inspectorTalkMessage', msg });
|
||||
content.value = '';
|
||||
sendMsg({ type: 'inspectorTalkMessage', msg })
|
||||
content.value = ''
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
row.value = 'item-' + (chatList.value.length - 1);
|
||||
}, 500);
|
||||
});
|
||||
row.value = 'item-' + (chatList.value.length - 1)
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 设置请提醒
|
||||
function notice(row: anyObj) {
|
||||
showNotice.value = true;
|
||||
noticeText.value = row.messageContent;
|
||||
showNotice.value = true
|
||||
noticeText.value = row.messageContent
|
||||
}
|
||||
|
||||
// 确认设置提醒
|
||||
@ -142,114 +143,114 @@ function confirmNotice() {
|
||||
type: 'systemMessage',
|
||||
userId: stuData.value.sender === 2 ? stuData.value.senderId : stuData.value.receiverId,
|
||||
msg: noticeText.value,
|
||||
};
|
||||
sendMsg(msg);
|
||||
showNotice.value = false;
|
||||
}
|
||||
sendMsg(msg)
|
||||
showNotice.value = false
|
||||
}
|
||||
|
||||
async function getDetails() {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
});
|
||||
})
|
||||
const { code, data } = await getTalkDetails({
|
||||
inspectorTalkRecordId: chatList.value[0]?.id ?? (chatList.value[1]?.id || undefined),
|
||||
userId: stuData.value.sender === 2 ? stuData.value.senderId : stuData.value.receiverId,
|
||||
});
|
||||
uni.hideLoading();
|
||||
uni.stopPullDownRefresh();
|
||||
})
|
||||
uni.hideLoading()
|
||||
uni.stopPullDownRefresh()
|
||||
if (code === 200) {
|
||||
const ids = chatList.value.filter(item => item.status === 1).map(item => item.id);
|
||||
const ids = chatList.value.filter(item => item.status === 1).map(item => item.id)
|
||||
if (ids.length) {
|
||||
readMsg({
|
||||
receiverId: userInfo.value.userId,
|
||||
senderId: stuData.value.sender === 2 ? stuData.value.senderId : stuData.value.receiverId,
|
||||
});
|
||||
})
|
||||
}
|
||||
const newChat = insertDividers(data);
|
||||
chatList.value = [...newChat, ...chatList.value];
|
||||
const newChat = insertDividers(data)
|
||||
chatList.value = [...newChat, ...chatList.value]
|
||||
chatList.value = chatList.value.map((v: any) => {
|
||||
if (v.sender === 1) {
|
||||
return { ...v, avatarUrl: userInfo.value.avatarUrl };
|
||||
return { ...v, avatarUrl: userInfo.value.avatarUrl }
|
||||
}
|
||||
return { ...v };
|
||||
});
|
||||
return { ...v }
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
uni.stopPullDownRefresh();
|
||||
uni.hideLoading()
|
||||
uni.stopPullDownRefresh()
|
||||
}
|
||||
}
|
||||
|
||||
function insertDividers(messages: anyObj[]) {
|
||||
const result = [];
|
||||
const result = []
|
||||
if (messages.length > 0) {
|
||||
result.push({ timeDate: formatDate(messages[0].createTime), type: 'divider' });
|
||||
result.push({ timeDate: formatDate(messages[0].createTime), type: 'divider' })
|
||||
}
|
||||
return messages.reduce((acc, currentMessage, index) => {
|
||||
acc.push(currentMessage);
|
||||
acc.push(currentMessage)
|
||||
if (index < messages.length - 1 && currentMessage.type !== 'divider') {
|
||||
const nextMessage = messages[index + 1];
|
||||
const nextMessage = messages[index + 1]
|
||||
if (
|
||||
dayjs(nextMessage.createTime).valueOf() - dayjs(currentMessage.createTime).valueOf() >=
|
||||
FIVE_MINUTES
|
||||
) {
|
||||
acc.push({ timeDate: formatDate(nextMessage.createTime), type: 'divider' });
|
||||
acc.push({ timeDate: formatDate(nextMessage.createTime), type: 'divider' })
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}, result) as anyObj[];
|
||||
return acc
|
||||
}, result) as anyObj[]
|
||||
}
|
||||
|
||||
watch(inspectorMessage, msg => {
|
||||
if (!msg) return;
|
||||
const newMsgTs = dayjs(msg.createTime).valueOf();
|
||||
console.log('msg1', msg);
|
||||
if (!msg) return
|
||||
const newMsgTs = dayjs(msg.createTime).valueOf()
|
||||
console.log('msg1', msg)
|
||||
const newMsg = {
|
||||
sender: 2,
|
||||
avatarUrl: msg.senderAvatarUrl || defaultAvatar,
|
||||
createTime: msg.createTime,
|
||||
messageContent: msg.messageContent,
|
||||
};
|
||||
chatList.value.push(newMsg);
|
||||
}
|
||||
chatList.value.push(newMsg)
|
||||
chatList.value = [
|
||||
...chatList.value,
|
||||
lastMessageTs.value === 0 || newMsgTs - lastMessageTs.value > FIVE_MINUTES
|
||||
? { timeDate: formatDate(msg.createTime), type: 'divider' }
|
||||
: null,
|
||||
];
|
||||
readMsg({ receiverId: msg.receiverId, senderId: msg.senderId });
|
||||
]
|
||||
readMsg({ receiverId: msg.receiverId, senderId: msg.senderId })
|
||||
nextTick(() => {
|
||||
row.value = 'item-' + (chatList.value.length - 1);
|
||||
});
|
||||
});
|
||||
row.value = 'item-' + (chatList.value.length - 1)
|
||||
})
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// userInfo.value = uni.getStorageSync('QY_USERINFO');
|
||||
userInfo.value = getCache('dxs_userInfo');
|
||||
socketInit();
|
||||
userInfo.value = db.get('dxs_userInfo')
|
||||
socketInit()
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
row.value = 'item-' + (chatList.value.length - 1);
|
||||
}, 500);
|
||||
});
|
||||
row.value = 'item-' + (chatList.value.length - 1)
|
||||
}, 500)
|
||||
})
|
||||
readMsg({
|
||||
receiverId: userInfo.value.userId,
|
||||
senderId: stuData.value.sender === 2 ? stuData.value.senderId : stuData.value.receiverId,
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
onShow(() => {
|
||||
stuData.value = uni.getStorageSync('stu');
|
||||
});
|
||||
stuData.value = uni.getStorageSync('stu')
|
||||
})
|
||||
onPullDownRefresh(() => {
|
||||
getDetails();
|
||||
});
|
||||
getDetails()
|
||||
})
|
||||
onLoad(() => {
|
||||
nextTick(() => {
|
||||
// uni.startPullDownRefresh();
|
||||
getDetails();
|
||||
});
|
||||
});
|
||||
getDetails()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
|
@ -29,65 +29,66 @@
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { getTalkList } from '@/api/modules/inspector';
|
||||
import Empty from '@/components/Empty/index.vue';
|
||||
import { formatDate, getCache } from '@/utils';
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`;
|
||||
const list = ref<any[]>([]);
|
||||
const state = ref<string>('loading');
|
||||
import { useSocket } from '@/hooks/useSocket';
|
||||
const current = ref(1);
|
||||
const userInfo = ref<anyObj>({});
|
||||
const { init: socketInit, inspectorMessage } = useSocket();
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { getTalkList } from '@/api/modules/inspector'
|
||||
import Empty from '@/components/Empty/index.vue'
|
||||
import { formatDate, getCache } from '@/utils'
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const list = ref<any[]>([])
|
||||
const state = ref<string>('loading')
|
||||
import { useSocket } from '@/hooks/useSocket'
|
||||
import db from '@/utils/db'
|
||||
const current = ref(1)
|
||||
const userInfo = ref<anyObj>({})
|
||||
const { init: socketInit, inspectorMessage } = useSocket()
|
||||
async function getTalkData() {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
});
|
||||
const { code, data } = await getTalkList({ current: current.value });
|
||||
uni.hideLoading();
|
||||
})
|
||||
const { code, data } = await getTalkList({ current: current.value })
|
||||
uni.hideLoading()
|
||||
if (code === 200) {
|
||||
list.value = data.rows;
|
||||
list.value = data.rows
|
||||
if (data.rows.length < 10) {
|
||||
state.value = 'finished';
|
||||
state.value = 'finished'
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
// 详情
|
||||
function toDetails(row: anyObj) {
|
||||
uni.setStorageSync('stu', row);
|
||||
uni.setStorageSync('stu', row)
|
||||
uni.navigateTo({
|
||||
url: '/pages/inspector/chat/chatDetails',
|
||||
});
|
||||
})
|
||||
}
|
||||
function loadmore() {
|
||||
current.value++;
|
||||
getTalkData();
|
||||
current.value++
|
||||
getTalkData()
|
||||
}
|
||||
watch(
|
||||
inspectorMessage,
|
||||
msg => {
|
||||
if (!msg) return;
|
||||
const index = list.value.findIndex(e => e.senderId === msg.senderId);
|
||||
if (!msg) return
|
||||
const index = list.value.findIndex(e => e.senderId === msg.senderId)
|
||||
if (index !== -1) {
|
||||
list.value[index].messageContent = msg.messageContent;
|
||||
list.value[index].messageContent = msg.messageContent
|
||||
list.value[index].createTime = msg.createTime
|
||||
? msg.createTime
|
||||
: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss');
|
||||
list.value[index].unreadCount++;
|
||||
: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
|
||||
list.value[index].unreadCount++
|
||||
} else {
|
||||
const newMsg = {
|
||||
messageContent: msg.messageContent,
|
||||
createTime: msg.createTime,
|
||||
unreadCount: 1,
|
||||
avatarUrl: msg.avatarUrl || defaultAvatar,
|
||||
};
|
||||
list.value.unshift(newMsg);
|
||||
}
|
||||
list.value.unshift(newMsg)
|
||||
}
|
||||
if (msg.senderId === userInfo.value.userId) {
|
||||
//
|
||||
@ -97,15 +98,15 @@ watch(
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
)
|
||||
onShow(() => {
|
||||
getTalkData();
|
||||
});
|
||||
getTalkData()
|
||||
})
|
||||
onMounted(() => {
|
||||
// userInfo.value = uni.getStorageSync('QY_USERINFO');
|
||||
userInfo.value = getCache('dxs_userInfo');
|
||||
socketInit();
|
||||
});
|
||||
userInfo.value = db.get('dxs_userInfo')
|
||||
socketInit()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
|
@ -53,33 +53,34 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, inject, onBeforeMount, type Ref, ref } from 'vue';
|
||||
import type { UserInfo } from '@/types/inspector/mine';
|
||||
import { getUserInfo, queryUserRoles, switchRole } from '@/api/inspector/mine';
|
||||
import { getAvatarUrl, getCache, setCache } from '@/utils';
|
||||
import { getAuthUrlApi } from '@/api/login';
|
||||
import { user } from '@/store';
|
||||
import { computed, inject, onBeforeMount, type Ref, ref } from 'vue'
|
||||
import type { UserInfo } from '@/types/inspector/mine'
|
||||
import { getUserInfo, queryUserRoles, switchRole } from '@/api/inspector/mine'
|
||||
import { getAvatarUrl, getCache, setCache } from '@/utils'
|
||||
import { getAuthUrlApi } from '@/api/login'
|
||||
import { user } from '@/store'
|
||||
import db from '@/utils/db'
|
||||
|
||||
const roleRef = ref(null);
|
||||
const roleRef = ref(null)
|
||||
|
||||
const userInfo = inject<Ref<UserInfo>>('userInfo');
|
||||
const userInfo = inject<Ref<UserInfo>>('userInfo')
|
||||
|
||||
const roleList = ref<any[]>([]);
|
||||
const roleList = ref<any[]>([])
|
||||
|
||||
const { getUserInfo: getLoginUserInfo } = user();
|
||||
const { getUserInfo: getLoginUserInfo } = user()
|
||||
|
||||
const queryRole = async () => {
|
||||
const { data } = await queryUserRoles({ phone: userInfo.value.phone });
|
||||
const { data } = await queryUserRoles({ phone: userInfo.value.phone })
|
||||
roleList.value = (data ?? []).map(item => {
|
||||
return {
|
||||
text: item.adminType === 16 ? '家长' : '督学师',
|
||||
text: '家长', // item.adminType === 16 ? '家长' : '督学师',
|
||||
value: item.adminType,
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
})
|
||||
}
|
||||
onBeforeMount(() => {
|
||||
queryRole();
|
||||
});
|
||||
queryRole()
|
||||
})
|
||||
|
||||
const colors = [
|
||||
{
|
||||
@ -102,58 +103,65 @@ const colors = [
|
||||
color: '#328EFF',
|
||||
bgColor: '#FFF7F0',
|
||||
},
|
||||
];
|
||||
]
|
||||
|
||||
const userLabels = computed(() => {
|
||||
return (userInfo.value.label ?? '').split(',').map((label, index) => {
|
||||
const _colorObj = colors[index % colors.length];
|
||||
const _colorObj = colors[index % colors.length]
|
||||
return {
|
||||
text: label,
|
||||
color: _colorObj.color,
|
||||
bgColor: _colorObj.bgColor,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const showRole = () => {
|
||||
if (roleList.value.length === 1 || roleList.value.length === 0) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
roleRef.value.open('bottom');
|
||||
};
|
||||
roleRef.value.open('bottom')
|
||||
}
|
||||
|
||||
const selectRole = async item => {
|
||||
userInfo.value.role = item.text;
|
||||
const res = await switchRole(item.value);
|
||||
setCache('token', res.data);
|
||||
const data = await getLoginUserInfo();
|
||||
userInfo.value.role = item.text
|
||||
const res = await switchRole(item.value)
|
||||
db.set('token', res.data)
|
||||
const data = await getLoginUserInfo()
|
||||
if (!data.openid) {
|
||||
// 初次注册
|
||||
if (data.adminType === 16) {
|
||||
const authRes = await getAuthUrlApi();
|
||||
const authRes = await getAuthUrlApi()
|
||||
// #ifdef H5
|
||||
window.location.href = authRes.data;
|
||||
window.location.href = authRes.data
|
||||
// #endif
|
||||
// if (data.adminType === 16) {
|
||||
// const authRes = await getAuthUrlApi();
|
||||
// // #ifdef H5
|
||||
// window.location.href = authRes.data;
|
||||
// // #endif
|
||||
// } else {
|
||||
// uni.reLaunch({
|
||||
// url: '/pages/inspector/schedule/index',
|
||||
// });
|
||||
// }
|
||||
} else {
|
||||
uni.reLaunch({
|
||||
url: '/pages/inspector/schedule/index',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let adminType = getCache('userInfo').adminType;
|
||||
if (adminType === 16) {
|
||||
let adminType = db.get('userInfo').adminType
|
||||
uni.reLaunch({
|
||||
url: '/pages/home/index',
|
||||
});
|
||||
} else if (adminType === 6) {
|
||||
uni.reLaunch({
|
||||
url: '/pages/inspector/schedule/index',
|
||||
});
|
||||
}
|
||||
})
|
||||
// if (adminType === 16) {
|
||||
// uni.reLaunch({
|
||||
// url: '/pages/home/index',
|
||||
// });
|
||||
// } else if (adminType === 6) {
|
||||
// uni.reLaunch({
|
||||
// url: '/pages/inspector/schedule/index',
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
roleRef.value.close();
|
||||
};
|
||||
roleRef.value.close()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -155,116 +155,117 @@
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onLaunch, onShow, onHide, onLoad } from '@dcloudio/uni-app';
|
||||
import { onMounted, reactive, ref, computed } from 'vue';
|
||||
import Picker from './components/picker.vue';
|
||||
import DatePicker from './components/datePicker.vue';
|
||||
import DateTimePicker from './components/dateTimePicker.vue';
|
||||
import CustomPopup from '@/components/CustomPopup/index.vue';
|
||||
import { getCourseData, getSubject, publishPlan, getStuPlan } from '@/api/modules/inspector';
|
||||
import dayjs from 'dayjs';
|
||||
import { getCache } from '@/utils';
|
||||
const pageTitle = ref('');
|
||||
const minHour = ref<number>(0);
|
||||
const minMinute = ref<number>(0);
|
||||
const maxHour = ref<number>(23);
|
||||
const maxMinute = ref<number>(59);
|
||||
const form = ref<anyObj>({});
|
||||
const plan = ref<anyObj>({});
|
||||
const user = ref<anyObj>({});
|
||||
const showStuPopup = ref(false);
|
||||
const showDatePicker = ref(false);
|
||||
const showRemovePopup = ref(false);
|
||||
const showDateTimePicker = ref(false);
|
||||
const studyPlanIndex = ref(0); // 记录选中的任务序号
|
||||
const currentType = ref(''); // 当前选项类型
|
||||
const canlenderList = ref<any[]>([]);
|
||||
const subjectData = ref<any[]>([]);
|
||||
const titleText = ref('');
|
||||
const rangeType = ref('start');
|
||||
import { onLaunch, onShow, onHide, onLoad } from '@dcloudio/uni-app'
|
||||
import { onMounted, reactive, ref, computed } from 'vue'
|
||||
import Picker from './components/picker.vue'
|
||||
import DatePicker from './components/datePicker.vue'
|
||||
import DateTimePicker from './components/dateTimePicker.vue'
|
||||
import CustomPopup from '@/components/CustomPopup/index.vue'
|
||||
import { getCourseData, getSubject, publishPlan, getStuPlan } from '@/api/modules/inspector'
|
||||
import dayjs from 'dayjs'
|
||||
import { getCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
const pageTitle = ref('')
|
||||
const minHour = ref<number>(0)
|
||||
const minMinute = ref<number>(0)
|
||||
const maxHour = ref<number>(23)
|
||||
const maxMinute = ref<number>(59)
|
||||
const form = ref<anyObj>({})
|
||||
const plan = ref<anyObj>({})
|
||||
const user = ref<anyObj>({})
|
||||
const showStuPopup = ref(false)
|
||||
const showDatePicker = ref(false)
|
||||
const showRemovePopup = ref(false)
|
||||
const showDateTimePicker = ref(false)
|
||||
const studyPlanIndex = ref(0) // 记录选中的任务序号
|
||||
const currentType = ref('') // 当前选项类型
|
||||
const canlenderList = ref<any[]>([])
|
||||
const subjectData = ref<any[]>([])
|
||||
const titleText = ref('')
|
||||
const rangeType = ref('start')
|
||||
const tagClass = {
|
||||
0: 'yellow',
|
||||
1: 'yellow',
|
||||
2: 'blue',
|
||||
3: 'red',
|
||||
};
|
||||
}
|
||||
const tagName = {
|
||||
0: '自由学',
|
||||
1: '自由学',
|
||||
2: '精准学',
|
||||
3: '语感训练',
|
||||
};
|
||||
}
|
||||
// 选中计划任务
|
||||
const planList = ref<any[]>([]);
|
||||
const stuList = ref([]);
|
||||
const planList = ref<any[]>([])
|
||||
const stuList = ref([])
|
||||
const columns = computed(() => {
|
||||
return currentType.value === 'plan' ? subjectData.value : [];
|
||||
});
|
||||
return currentType.value === 'plan' ? subjectData.value : []
|
||||
})
|
||||
|
||||
// 选择对象
|
||||
function select(type: string, index?: number, dateType?: string) {
|
||||
currentType.value = type;
|
||||
studyPlanIndex.value = index;
|
||||
currentType.value = type
|
||||
studyPlanIndex.value = index
|
||||
switch (type) {
|
||||
case 'stundent':
|
||||
showStuPopup.value = true;
|
||||
break;
|
||||
showStuPopup.value = true
|
||||
break
|
||||
case 'plan':
|
||||
showStuPopup.value = true;
|
||||
break;
|
||||
showStuPopup.value = true
|
||||
break
|
||||
case 'date':
|
||||
if (!user.value.courseDate) {
|
||||
showDatePicker.value = true;
|
||||
showDatePicker.value = true
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'rangeDate':
|
||||
if (dateType === 'start') {
|
||||
titleText.value = '开始时间';
|
||||
rangeType.value = 'start';
|
||||
setRange();
|
||||
titleText.value = '开始时间'
|
||||
rangeType.value = 'start'
|
||||
setRange()
|
||||
} else {
|
||||
titleText.value = '结束时间';
|
||||
rangeType.value = 'end';
|
||||
setRange();
|
||||
titleText.value = '结束时间'
|
||||
rangeType.value = 'end'
|
||||
setRange()
|
||||
}
|
||||
showDateTimePicker.value = true;
|
||||
break;
|
||||
showDateTimePicker.value = true
|
||||
break
|
||||
}
|
||||
}
|
||||
function setRange() {
|
||||
let minute = 0;
|
||||
let hour = 0;
|
||||
let minute = 0
|
||||
let hour = 0
|
||||
|
||||
const key = rangeType.value === 'start' ? 'inspectorTimeEnd' : 'inspectorTimeStart';
|
||||
const time = planList.value[studyPlanIndex.value]?.[key].split(':') || [];
|
||||
minute = Number(time?.[1] || 0);
|
||||
hour = Number(time?.[0] || 0);
|
||||
const key = rangeType.value === 'start' ? 'inspectorTimeEnd' : 'inspectorTimeStart'
|
||||
const time = planList.value[studyPlanIndex.value]?.[key].split(':') || []
|
||||
minute = Number(time?.[1] || 0)
|
||||
hour = Number(time?.[0] || 0)
|
||||
|
||||
if (rangeType.value === 'start') {
|
||||
if (time.length === 2) {
|
||||
minute = minute - 1 > 0 ? minute - 1 : 1;
|
||||
minute = minute - 1 > 0 ? minute - 1 : 1
|
||||
} else {
|
||||
hour = 23;
|
||||
minute = 58;
|
||||
hour = 23
|
||||
minute = 58
|
||||
}
|
||||
maxHour.value = hour;
|
||||
maxMinute.value = minute;
|
||||
maxHour.value = hour
|
||||
maxMinute.value = minute
|
||||
} else {
|
||||
minute = minute + 1;
|
||||
minHour.value = hour;
|
||||
minMinute.value = minute;
|
||||
maxHour.value = 23;
|
||||
maxMinute.value = 59;
|
||||
minute = minute + 1
|
||||
minHour.value = hour
|
||||
minMinute.value = minute
|
||||
maxHour.value = 23
|
||||
maxMinute.value = 59
|
||||
}
|
||||
}
|
||||
// 选择确认
|
||||
function confirmSelect(val: any) {
|
||||
let row = planList.value[studyPlanIndex.value];
|
||||
let row = planList.value[studyPlanIndex.value]
|
||||
if (currentType.value === 'plan') {
|
||||
row.subjectId = val.value;
|
||||
row.subjectName = val.name;
|
||||
row.gradeId = user.value.gradeId;
|
||||
row.subjectId = val.value;
|
||||
row.subjectId = val.value
|
||||
row.subjectName = val.name
|
||||
row.gradeId = user.value.gradeId
|
||||
row.subjectId = val.value
|
||||
uni.setStorageSync('plan', {
|
||||
planList: planList.value,
|
||||
userId: user.value.userId,
|
||||
@ -272,113 +273,113 @@ function confirmSelect(val: any) {
|
||||
row: row,
|
||||
date: form.value.date,
|
||||
courseId: form.value.courseId,
|
||||
});
|
||||
uni.navigateTo({ url: '/pages/inspector/releasePlan/selectPlan' });
|
||||
})
|
||||
uni.navigateTo({ url: '/pages/inspector/releasePlan/selectPlan' })
|
||||
}
|
||||
showStuPopup.value = false;
|
||||
showStuPopup.value = false
|
||||
}
|
||||
function addPlan() {
|
||||
planList.value.push({});
|
||||
planList.value.push({})
|
||||
}
|
||||
function removePlan(index: number) {
|
||||
showRemovePopup.value = true;
|
||||
studyPlanIndex.value = index;
|
||||
showRemovePopup.value = true
|
||||
studyPlanIndex.value = index
|
||||
}
|
||||
// 日期确认
|
||||
function handleConfirm(row: any) {
|
||||
form.value.date = row.courseDate;
|
||||
form.value.courseId = row.courseId;
|
||||
form.value.date = row.courseDate
|
||||
form.value.courseId = row.courseId
|
||||
|
||||
//
|
||||
}
|
||||
// 时间确认
|
||||
function confirmDateTime(date: string) {
|
||||
let row = planList.value[studyPlanIndex.value];
|
||||
let row = planList.value[studyPlanIndex.value]
|
||||
if (rangeType.value === 'start') {
|
||||
row.inspectorTimeStart = date;
|
||||
row.inspectorTimeStart = date
|
||||
} else if (rangeType.value === 'end') {
|
||||
row.inspectorTimeEnd = date;
|
||||
row.inspectorTimeEnd = date
|
||||
}
|
||||
}
|
||||
function removeConfirm() {
|
||||
planList.value.splice(studyPlanIndex.value, 1);
|
||||
showRemovePopup.value = false;
|
||||
planList.value.splice(studyPlanIndex.value, 1)
|
||||
showRemovePopup.value = false
|
||||
}
|
||||
// 获取课表日历
|
||||
async function getDate() {
|
||||
const { code, data } = await getCourseData({ id: user.value.userId });
|
||||
const { code, data } = await getCourseData({ id: user.value.userId })
|
||||
if (code === 200) {
|
||||
canlenderList.value = data || [];
|
||||
canlenderList.value = data || []
|
||||
}
|
||||
}
|
||||
// 获取学科
|
||||
async function getSubjectList() {
|
||||
const { code, data } = await getSubject({ gradeId: user.value.gradeId });
|
||||
const { code, data } = await getSubject({ gradeId: user.value.gradeId })
|
||||
if (code === 200) {
|
||||
subjectData.value = data.map((item: any) => {
|
||||
return {
|
||||
name: item.subject,
|
||||
value: item.subjectId,
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 获取计划
|
||||
async function getStuPlanData() {
|
||||
try {
|
||||
uni.showLoading({ title: '加载中...' });
|
||||
uni.showLoading({ title: '加载中...' })
|
||||
const { code, data } = await getStuPlan({
|
||||
userId: user.value.userId,
|
||||
courseDate: user.value.courseDate ?? '',
|
||||
});
|
||||
uni.hideLoading();
|
||||
})
|
||||
uni.hideLoading()
|
||||
if (code === 200) {
|
||||
form.value.courseId = data.courseId ? data.courseId : plan.value.courseId;
|
||||
form.value.courseId = data.courseId ? data.courseId : plan.value.courseId
|
||||
form.value.date = data.courseDate
|
||||
? dayjs(data.courseDate).format('YYYY-MM-DD')
|
||||
: plan.value.date;
|
||||
: plan.value.date
|
||||
|
||||
if (data.tasks && Object.keys(plan.value).length === 0) {
|
||||
planList.value = data.tasks.map(item => {
|
||||
const taskInfo = JSON.parse(item.taskInfoJson);
|
||||
const taskInfo = JSON.parse(item.taskInfoJson)
|
||||
return {
|
||||
...taskInfo,
|
||||
...item,
|
||||
id: item.id,
|
||||
inspectorTimeStart: dayjs(item.inspectorTimeStart).format('HH:mm'),
|
||||
inspectorTimeEnd: dayjs(item.inspectorTimeEnd).format('HH:mm'),
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
const storegePlan = {
|
||||
index: 0,
|
||||
date: form.value.date,
|
||||
courseId: form.value.courseId,
|
||||
planList: planList.value,
|
||||
row: planList.value[0],
|
||||
};
|
||||
plan.value = storegePlan;
|
||||
uni.setStorageSync('plan', storegePlan);
|
||||
}
|
||||
plan.value = storegePlan
|
||||
uni.setStorageSync('plan', storegePlan)
|
||||
} else {
|
||||
uni.removeStorageSync('plan');
|
||||
uni.removeStorageSync('plan')
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
// 确认发布
|
||||
async function submitPublish() {
|
||||
const fields = ['chapterId', 'bookId', 'courseTimeId', 'inspectorTimeStart', 'inspectorTimeEnd'];
|
||||
let valid = true;
|
||||
const fields = ['chapterId', 'bookId', 'courseTimeId', 'inspectorTimeStart', 'inspectorTimeEnd']
|
||||
let valid = true
|
||||
const tasks = planList.value.map(item => {
|
||||
if (item.taskType >= 0) {
|
||||
if ([0, 1].includes(item.taskType)) {
|
||||
fields.forEach(field => {
|
||||
if (!item[field]) valid = false;
|
||||
});
|
||||
if (!item[field]) valid = false
|
||||
})
|
||||
}
|
||||
} else {
|
||||
valid = false;
|
||||
valid = false
|
||||
}
|
||||
|
||||
return {
|
||||
@ -389,70 +390,70 @@ async function submitPublish() {
|
||||
inspectorTimeStart: item.inspectorTimeStart
|
||||
? form.value.date + ' ' + item.inspectorTimeStart + ':00'
|
||||
: undefined,
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
if (!valid) {
|
||||
return uni.showToast({
|
||||
title: '请确认学习任务中的教材/章节/知识点/督学时段是否完整',
|
||||
icon: 'none',
|
||||
});
|
||||
})
|
||||
}
|
||||
try {
|
||||
uni.showLoading({ title: '发布中...' });
|
||||
uni.showLoading({ title: '发布中...' })
|
||||
const params = {
|
||||
courseId: form.value.courseId,
|
||||
tasks: tasks,
|
||||
};
|
||||
const { code } = await publishPlan(params);
|
||||
uni.hideLoading();
|
||||
}
|
||||
const { code } = await publishPlan(params)
|
||||
uni.hideLoading()
|
||||
if (code === 200) {
|
||||
uni.showToast({
|
||||
title: '发布成功',
|
||||
});
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: `/pages/inspector/student-detail/index?orderId=${user.value.orderId}&courseDate=${form.value.date}`,
|
||||
});
|
||||
}, 1500);
|
||||
reload();
|
||||
})
|
||||
}, 1500)
|
||||
reload()
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
function reload() {
|
||||
uni.removeStorageSync('plan');
|
||||
uni.removeStorageSync('user');
|
||||
uni.removeStorageSync('plan')
|
||||
uni.removeStorageSync('user')
|
||||
}
|
||||
const studentDetail = ref();
|
||||
const studentDetail = ref()
|
||||
const back = () => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/inspector/student-detail/index?orderId=${studentDetail.value.orderId}&courseDate=${studentDetail.value.courseDate}`,
|
||||
});
|
||||
reload();
|
||||
};
|
||||
})
|
||||
reload()
|
||||
}
|
||||
window.addEventListener('popstate', event => {
|
||||
reload();
|
||||
});
|
||||
reload()
|
||||
})
|
||||
onMounted(() => {
|
||||
user.value = uni.getStorageSync('user') || {};
|
||||
getStuPlanData();
|
||||
getSubjectList();
|
||||
getDate();
|
||||
});
|
||||
user.value = uni.getStorageSync('user') || {}
|
||||
getStuPlanData()
|
||||
getSubjectList()
|
||||
getDate()
|
||||
})
|
||||
onShow(() => {
|
||||
studentDetail.value = getCache('student_detail');
|
||||
plan.value = uni.getStorageSync('plan') || {};
|
||||
planList.value = plan.value.planList || [{}];
|
||||
plan.value.date && (form.value.date = plan.value.date);
|
||||
});
|
||||
studentDetail.value = db.get('student_detail')
|
||||
plan.value = uni.getStorageSync('plan') || {}
|
||||
planList.value = plan.value.planList || [{}]
|
||||
plan.value.date && (form.value.date = plan.value.date)
|
||||
})
|
||||
onLoad(option => {
|
||||
pageTitle.value = Number(option.type) === 1 ? '修改计划' : '发布计划';
|
||||
pageTitle.value = Number(option.type) === 1 ? '修改计划' : '发布计划'
|
||||
uni.setNavigationBarTitle({
|
||||
title: Number(option.type) === 1 ? '修改计划' : '发布计划',
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
|
@ -127,154 +127,155 @@
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import dayjs from 'dayjs';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { computed, onMounted, ref, watch, onUnmounted } from 'vue';
|
||||
import DuxueTipsModal from './components/duxueTipsModal.vue';
|
||||
import CusCalender from '@/components/customCalender/index.vue';
|
||||
import dayjs from 'dayjs'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { computed, onMounted, ref, watch, onUnmounted } from 'vue'
|
||||
import DuxueTipsModal from './components/duxueTipsModal.vue'
|
||||
import CusCalender from '@/components/customCalender/index.vue'
|
||||
|
||||
import { useSocket } from '@/hooks/useSocket';
|
||||
import { useSocket } from '@/hooks/useSocket'
|
||||
import {
|
||||
endInpector,
|
||||
getCourseDate,
|
||||
getScheduleList,
|
||||
getUnreadCount,
|
||||
startInpector,
|
||||
} from '@/api/modules/inspector';
|
||||
import { getAvatarUrl, setCache } from '@/utils';
|
||||
} from '@/api/modules/inspector'
|
||||
import { getAvatarUrl, setCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
|
||||
const { init: socketInit, sendMsg, inspectorMessage } = useSocket();
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const { init: socketInit, sendMsg, inspectorMessage } = useSocket()
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
|
||||
const showTipsModal = ref(false);
|
||||
const calendarData = ref<any[]>([]);
|
||||
const titleText = ref('');
|
||||
const unreadCount = ref(0);
|
||||
const modalContent = ref('');
|
||||
const courseData = ref<any>({}); // 课表学生列表
|
||||
const currentDate = ref(dayjs().format('YYYY-MM-DD'));
|
||||
const today = ref(dayjs().format('YYYY-MM-DD'));
|
||||
const currentDateIndex = ref(0); // 当前时间在日历表中的下标
|
||||
const inspectorTimeStart = ref<string>(); // 督学开始时间
|
||||
const time = ref<string>('');
|
||||
const studentList = ref<any[]>([]);
|
||||
const showTipsModal = ref(false)
|
||||
const calendarData = ref<any[]>([])
|
||||
const titleText = ref('')
|
||||
const unreadCount = ref(0)
|
||||
const modalContent = ref('')
|
||||
const courseData = ref<any>({}) // 课表学生列表
|
||||
const currentDate = ref(dayjs().format('YYYY-MM-DD'))
|
||||
const today = ref(dayjs().format('YYYY-MM-DD'))
|
||||
const currentDateIndex = ref(0) // 当前时间在日历表中的下标
|
||||
const inspectorTimeStart = ref<string>() // 督学开始时间
|
||||
const time = ref<string>('')
|
||||
const studentList = ref<any[]>([])
|
||||
const tagColor = {
|
||||
1: 'green',
|
||||
2: 'grey',
|
||||
};
|
||||
}
|
||||
const stateCorlo = {
|
||||
0: 'plan',
|
||||
1: 'green',
|
||||
2: 'grey',
|
||||
3: 'grey',
|
||||
};
|
||||
}
|
||||
const stateName = {
|
||||
'-1': '待发计划',
|
||||
0: '待开课',
|
||||
1: '督学中',
|
||||
2: '已督学',
|
||||
3: '已过期',
|
||||
};
|
||||
const currentType = ref('');
|
||||
const showList = ref(false);
|
||||
}
|
||||
const currentType = ref('')
|
||||
const showList = ref(false)
|
||||
// 日期判断是否可以开始督学
|
||||
const canStart = () => {
|
||||
return (
|
||||
today.value === currentDate.value &&
|
||||
new Date().getTime() >= new Date(courseData.value.courseStartDate).getTime() - 30 * 1000 * 60
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
// 是否可以结束督学
|
||||
const endDX = ref(false);
|
||||
let timer: any;
|
||||
const endDX = ref(false)
|
||||
let timer: any
|
||||
const endCount = () => {
|
||||
let duration = new Date().getTime() - new Date(inspectorTimeStart.value).getTime();
|
||||
const hours = Math.floor(duration / 3600000);
|
||||
const minutes = Math.floor((duration % 3600000) / 60000);
|
||||
const seconds = Math.floor((duration % 60000) / 1000);
|
||||
let duration = new Date().getTime() - new Date(inspectorTimeStart.value).getTime()
|
||||
const hours = Math.floor(duration / 3600000)
|
||||
const minutes = Math.floor((duration % 3600000) / 60000)
|
||||
const seconds = Math.floor((duration % 60000) / 1000)
|
||||
time.value = `${hours.toString().padStart(2, '0')}:${minutes
|
||||
.toString()
|
||||
.padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||||
};
|
||||
.padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
|
||||
}
|
||||
const canEnd = () => {
|
||||
endCount();
|
||||
clearInterval(timer);
|
||||
endCount()
|
||||
clearInterval(timer)
|
||||
if (inspectorTimeStart.value) {
|
||||
timer = setInterval(() => {
|
||||
endCount();
|
||||
endCount()
|
||||
endDX.value =
|
||||
today.value === currentDate.value &&
|
||||
new Date().getTime() > new Date(courseData.value.courseEndDate).getTime();
|
||||
}, 1000);
|
||||
new Date().getTime() > new Date(courseData.value.courseEndDate).getTime()
|
||||
}, 1000)
|
||||
}
|
||||
};
|
||||
}
|
||||
// 学员有无计划判断是否可以督学
|
||||
const noPlan = computed(() => {
|
||||
let flag = false;
|
||||
let flag = false
|
||||
studentList.value.forEach(e => {
|
||||
if (!e.planNum) {
|
||||
flag = true;
|
||||
flag = true
|
||||
}
|
||||
});
|
||||
return flag;
|
||||
});
|
||||
})
|
||||
return flag
|
||||
})
|
||||
// 开始督学
|
||||
function startSubmit() {
|
||||
if (noPlan.value) {
|
||||
titleText.value = '无法开始督学';
|
||||
modalContent.value = '存在学员没有学习计划,请发布学习计划后再开始督学!';
|
||||
currentType.value = 'none';
|
||||
titleText.value = '无法开始督学'
|
||||
modalContent.value = '存在学员没有学习计划,请发布学习计划后再开始督学!'
|
||||
currentType.value = 'none'
|
||||
} else {
|
||||
titleText.value = '温馨提示';
|
||||
modalContent.value = '确定开始督学?';
|
||||
currentType.value = 'start';
|
||||
titleText.value = '温馨提示'
|
||||
modalContent.value = '确定开始督学?'
|
||||
currentType.value = 'start'
|
||||
}
|
||||
showTipsModal.value = true;
|
||||
showTipsModal.value = true
|
||||
}
|
||||
// 结束督学
|
||||
function endSubmit() {
|
||||
titleText.value = '温馨提示';
|
||||
modalContent.value = '确认结束督学';
|
||||
currentType.value = 'end';
|
||||
showTipsModal.value = true;
|
||||
titleText.value = '温馨提示'
|
||||
modalContent.value = '确认结束督学'
|
||||
currentType.value = 'end'
|
||||
showTipsModal.value = true
|
||||
}
|
||||
// 结束确认
|
||||
const confirmEnd = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: '请稍后...' });
|
||||
const { code } = await endInpector({ courseDate: currentDate.value });
|
||||
uni.hideLoading();
|
||||
uni.showLoading({ title: '请稍后...' })
|
||||
const { code } = await endInpector({ courseDate: currentDate.value })
|
||||
uni.hideLoading()
|
||||
if (code === 200) {
|
||||
uni.showToast({
|
||||
title: '结束督学成功',
|
||||
});
|
||||
})
|
||||
sendMsg({
|
||||
type: 'inspectorEnd',
|
||||
msg: {
|
||||
receiverIds: studentList.value.map(item => item.id),
|
||||
},
|
||||
});
|
||||
showTipsModal.value = false;
|
||||
getDate(currentDate.value);
|
||||
})
|
||||
showTipsModal.value = false
|
||||
getDate(currentDate.value)
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
};
|
||||
}
|
||||
// 督学确认开始
|
||||
const confirmStart = async () => {
|
||||
showTipsModal.value = false;
|
||||
showTipsModal.value = false
|
||||
if (!canStart()) {
|
||||
uni.showToast({
|
||||
title: '最多提前30分钟开始督学',
|
||||
icon: 'none',
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
try {
|
||||
uni.showLoading({ title: '请稍后...' });
|
||||
const { code } = await startInpector({ courseDate: currentDate.value });
|
||||
uni.hideLoading();
|
||||
uni.showLoading({ title: '请稍后...' })
|
||||
const { code } = await startInpector({ courseDate: currentDate.value })
|
||||
uni.hideLoading()
|
||||
if (code === 200) {
|
||||
sendMsg({
|
||||
type: 'inspectorStart',
|
||||
@ -282,125 +283,123 @@ const confirmStart = async () => {
|
||||
receiverIds: studentList.value.map(item => item.id),
|
||||
courseDate: currentDate.value,
|
||||
},
|
||||
});
|
||||
})
|
||||
uni.showToast({
|
||||
title: '开始督学成功',
|
||||
});
|
||||
getDate(currentDate.value);
|
||||
})
|
||||
getDate(currentDate.value)
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
};
|
||||
}
|
||||
const confirmModal = () => {
|
||||
if (currentType.value === 'start') {
|
||||
confirmStart();
|
||||
confirmStart()
|
||||
} else if (currentType.value === 'end') {
|
||||
confirmEnd();
|
||||
confirmEnd()
|
||||
}
|
||||
};
|
||||
}
|
||||
// 选择的日期
|
||||
function selectedDay(date: any) {
|
||||
currentDate.value = date.courseDate;
|
||||
getDate(currentDate.value);
|
||||
showList.value = false;
|
||||
currentDate.value = date.courseDate
|
||||
getDate(currentDate.value)
|
||||
showList.value = false
|
||||
}
|
||||
// 学生详情
|
||||
const studentDetail = (_student: any) => {
|
||||
setCache('student_detail', {
|
||||
db.set('student_detail', {
|
||||
orderId: _student.orderId,
|
||||
courseDate: currentDate.value,
|
||||
backType: 1,
|
||||
});
|
||||
})
|
||||
uni.navigateTo({
|
||||
url: `/pages/inspector/student-detail/index?orderId=${_student.orderId}&courseDate=${currentDate.value}`,
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
// 跳转
|
||||
function jumpPage(path: string) {
|
||||
uni.setStorageSync('courseDate', currentDate.value);
|
||||
uni.setStorageSync('courseDate', currentDate.value)
|
||||
uni.navigateTo({
|
||||
url: path,
|
||||
});
|
||||
})
|
||||
}
|
||||
// 点击命中下一个日期
|
||||
function changeDay(type: string) {
|
||||
switch (type) {
|
||||
case 'prev':
|
||||
if (currentDateIndex.value > 0) {
|
||||
currentDate.value = calendarData.value[currentDateIndex.value - 1].courseDate;
|
||||
currentDate.value = calendarData.value[currentDateIndex.value - 1].courseDate
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'next':
|
||||
if (currentDateIndex.value < calendarData.value.length - 1)
|
||||
currentDate.value = calendarData.value[currentDateIndex.value + 1].courseDate;
|
||||
currentDate.value = calendarData.value[currentDateIndex.value + 1].courseDate
|
||||
|
||||
break;
|
||||
break
|
||||
}
|
||||
currentDateIndex.value = calendarData.value.findIndex(e => e.courseDate === currentDate.value);
|
||||
getDate(currentDate.value);
|
||||
currentDateIndex.value = calendarData.value.findIndex(e => e.courseDate === currentDate.value)
|
||||
getDate(currentDate.value)
|
||||
}
|
||||
// 获取课表时间
|
||||
async function getDate(date?: string) {
|
||||
uni.showLoading({ title: '加载中...' });
|
||||
uni.showLoading({ title: '加载中...' })
|
||||
try {
|
||||
const { code, data, message } = await getCourseDate({ date });
|
||||
const { code, data, message } = await getCourseDate({ date })
|
||||
if (code === 200) {
|
||||
currentDate.value =
|
||||
dayjs(data.courseDate).format('YYYY-MM-DD') || dayjs().format('YYYY-MM-DD');
|
||||
courseData.value = data || {};
|
||||
currentDateIndex.value = calendarData.value.findIndex(
|
||||
e => e.courseDate === currentDate.value,
|
||||
);
|
||||
inspectorTimeStart.value = data.inspectorTimeStart ? data.inspectorTimeStart : '';
|
||||
studentList.value = data.studentDetails || [];
|
||||
dayjs(data.courseDate).format('YYYY-MM-DD') || dayjs().format('YYYY-MM-DD')
|
||||
courseData.value = data || {}
|
||||
currentDateIndex.value = calendarData.value.findIndex(e => e.courseDate === currentDate.value)
|
||||
inspectorTimeStart.value = data.inspectorTimeStart ? data.inspectorTimeStart : ''
|
||||
studentList.value = data.studentDetails || []
|
||||
if (data.planState === 1) {
|
||||
canEnd();
|
||||
canEnd()
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
// 获取课表信息
|
||||
async function getList() {
|
||||
try {
|
||||
uni.showLoading({ title: '加载中...' });
|
||||
const { code, data, message } = await getScheduleList();
|
||||
uni.showLoading({ title: '加载中...' })
|
||||
const { code, data, message } = await getScheduleList()
|
||||
if (code === 200) {
|
||||
calendarData.value = data || [];
|
||||
calendarData.value = data || []
|
||||
} else {
|
||||
uni.showToast({ title: message, icon: 'none' });
|
||||
uni.showToast({ title: message, icon: 'none' })
|
||||
}
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
// 获取我的未读消息
|
||||
async function getMyUnreadCount() {
|
||||
const { code, data } = await getUnreadCount();
|
||||
const { code, data } = await getUnreadCount()
|
||||
if (code === 200) {
|
||||
unreadCount.value = data;
|
||||
unreadCount.value = data
|
||||
}
|
||||
}
|
||||
watch(inspectorMessage, msg => {
|
||||
if (!msg) return;
|
||||
unreadCount.value++;
|
||||
});
|
||||
if (!msg) return
|
||||
unreadCount.value++
|
||||
})
|
||||
onMounted(async () => {
|
||||
socketInit();
|
||||
socketInit()
|
||||
|
||||
await getList();
|
||||
getDate();
|
||||
});
|
||||
await getList()
|
||||
getDate()
|
||||
})
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer);
|
||||
});
|
||||
clearInterval(timer)
|
||||
})
|
||||
onShow(() => {
|
||||
getMyUnreadCount();
|
||||
});
|
||||
getMyUnreadCount()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
|
@ -16,33 +16,34 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onReachBottom } from '@dcloudio/uni-app';
|
||||
import DetailStudentInfo from '@/pages/inspector/student-detail/detail-student-info.vue';
|
||||
import StudentDetailData from '@/pages/inspector/student-detail/student-detail-data.vue';
|
||||
import { getCurrentInstance, onMounted, provide, ref } from 'vue';
|
||||
import { getStudentDetail } from '@/api/inspector/student-detail';
|
||||
import dayjs from '@/plugins/dayjs';
|
||||
import IspDataLoad from '@/components/inspector/isp-data-load.vue';
|
||||
import SvgsAddPlan from '@/components/svgs/svgs-add-plan.vue';
|
||||
import { removeCache, getCache } from '@/utils';
|
||||
const studentInfo = ref<any>({});
|
||||
const routeData = ref({});
|
||||
const loadingData = ref(true);
|
||||
import { onReachBottom } from '@dcloudio/uni-app'
|
||||
import DetailStudentInfo from '@/pages/inspector/student-detail/detail-student-info.vue'
|
||||
import StudentDetailData from '@/pages/inspector/student-detail/student-detail-data.vue'
|
||||
import { getCurrentInstance, onMounted, provide, ref } from 'vue'
|
||||
import { getStudentDetail } from '@/api/inspector/student-detail'
|
||||
import dayjs from '@/plugins/dayjs'
|
||||
import IspDataLoad from '@/components/inspector/isp-data-load.vue'
|
||||
import SvgsAddPlan from '@/components/svgs/svgs-add-plan.vue'
|
||||
import { removeCache, getCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
const studentInfo = ref<any>({})
|
||||
const routeData = ref({})
|
||||
const loadingData = ref(true)
|
||||
|
||||
provide('studentInfo', studentInfo);
|
||||
provide('routeData', routeData);
|
||||
provide('studentInfo', studentInfo)
|
||||
provide('routeData', routeData)
|
||||
|
||||
const queryData = async _params => {
|
||||
loadingData.value = true;
|
||||
loadingData.value = true
|
||||
try {
|
||||
const { data } = await getStudentDetail(_params);
|
||||
studentInfo.value = data;
|
||||
const { data } = await getStudentDetail(_params)
|
||||
studentInfo.value = data
|
||||
} finally {
|
||||
loadingData.value = false;
|
||||
loadingData.value = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const orderId = ref('');
|
||||
const orderId = ref('')
|
||||
|
||||
const toAddPlan = () => {
|
||||
uni.setStorageSync('user', {
|
||||
@ -51,32 +52,32 @@ const toAddPlan = () => {
|
||||
gradeId: studentInfo.value.gradeId,
|
||||
orderId: orderId.value,
|
||||
// courseDate: routeData.value.courseDate,
|
||||
});
|
||||
})
|
||||
uni.navigateTo({
|
||||
url: `/pages/inspector/releasePlan/index`,
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
const back = () => {
|
||||
let info = getCache('student_detail');
|
||||
let info = db.get('student_detail')
|
||||
uni.navigateTo({
|
||||
url: `${
|
||||
info.backType === 1 ? '/pages/inspector/schedule/index' : '/pages/inspector/student/index'
|
||||
}`,
|
||||
});
|
||||
removeCache('student_detail');
|
||||
};
|
||||
})
|
||||
removeCache('student_detail')
|
||||
}
|
||||
onReachBottom(() => {
|
||||
console.log('触底加载');
|
||||
});
|
||||
console.log('触底加载')
|
||||
})
|
||||
onMounted(() => {
|
||||
const data = getCurrentInstance().proxy.$page.options;
|
||||
routeData.value = data;
|
||||
orderId.value = data.orderId;
|
||||
const data = getCurrentInstance().proxy.$page.options
|
||||
routeData.value = data
|
||||
orderId.value = data.orderId
|
||||
queryData({
|
||||
orderId: data.orderId,
|
||||
courseDate: data.courseDate ? dayjs(data.courseDate).format('YYYY-MM-DD') : '',
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -33,15 +33,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { queryStudentList } from '@/api/inspector/student';
|
||||
import IspDataLoad from '@/components/inspector/isp-data-load.vue';
|
||||
import { getAvatarUrl, setCache } from '@/utils';
|
||||
import { computed, ref } from 'vue'
|
||||
import { queryStudentList } from '@/api/inspector/student'
|
||||
import IspDataLoad from '@/components/inspector/isp-data-load.vue'
|
||||
import { getAvatarUrl, setCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
|
||||
const currentTab = ref<string>('all');
|
||||
const queryResult = ref<any>({});
|
||||
const studentList = ref([]);
|
||||
const queryLoading = ref(true);
|
||||
const currentTab = ref<string>('all')
|
||||
const queryResult = ref<any>({})
|
||||
const studentList = ref([])
|
||||
const queryLoading = ref(true)
|
||||
|
||||
const stateObj = {
|
||||
true: {
|
||||
@ -52,33 +53,33 @@ const stateObj = {
|
||||
text: '离线',
|
||||
color: '#cccccc',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const queryList = async (courseDate: string) => {
|
||||
queryLoading.value = true;
|
||||
queryLoading.value = true
|
||||
try {
|
||||
const { data } = await queryStudentList({ courseDate });
|
||||
queryResult.value = data ?? {};
|
||||
studentList.value = data?.studentDetails ?? [];
|
||||
const { data } = await queryStudentList({ courseDate })
|
||||
queryResult.value = data ?? {}
|
||||
studentList.value = data?.studentDetails ?? []
|
||||
} finally {
|
||||
queryLoading.value = false;
|
||||
queryLoading.value = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const studentListShow = computed(() => {
|
||||
return studentList.value.filter(item => {
|
||||
if (currentTab.value === 'all') {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
return item.gradeName === currentTab.value;
|
||||
});
|
||||
});
|
||||
return item.gradeName === currentTab.value
|
||||
})
|
||||
})
|
||||
|
||||
const grades = computed(() => {
|
||||
let gradeList = studentList.value
|
||||
.filter(item => (item.gradeName ?? '') !== '')
|
||||
.map(item => item.gradeName);
|
||||
gradeList = [...new Set(gradeList)];
|
||||
.map(item => item.gradeName)
|
||||
gradeList = [...new Set(gradeList)]
|
||||
return [
|
||||
{
|
||||
title: '全部',
|
||||
@ -88,27 +89,27 @@ const grades = computed(() => {
|
||||
return {
|
||||
title: item,
|
||||
value: item,
|
||||
};
|
||||
}
|
||||
}),
|
||||
];
|
||||
});
|
||||
]
|
||||
})
|
||||
|
||||
const studentDetail = (_student: any) => {
|
||||
setCache('student_detail', {
|
||||
db.set('student_detail', {
|
||||
orderId: _student.orderId,
|
||||
courseDate: queryResult.value.courseDate ? queryResult.value.courseDate : '',
|
||||
backType: 2,
|
||||
});
|
||||
})
|
||||
uni.navigateTo({
|
||||
url: `/pages/inspector/student-detail/index?orderId=${_student.orderId}&courseDate=${
|
||||
queryResult.value.courseDate ? queryResult.value.courseDate : ''
|
||||
}`,
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
queryList,
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -69,7 +69,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { ref, computed, nextTick, onMounted } from 'vue';
|
||||
import { ref, computed, nextTick, onMounted } from 'vue'
|
||||
|
||||
import {
|
||||
getBindPhoneTypeApi,
|
||||
@ -78,78 +78,77 @@ import {
|
||||
smsLoginApi,
|
||||
getUserInfoApi,
|
||||
getAuthUrlApi,
|
||||
} from '@/api';
|
||||
import { setCache, getCache } from '@/utils';
|
||||
import { getUserInfo as dx_getUserInfoApi } from '@/api/inspector/mine';
|
||||
import { user } from '@/store';
|
||||
} from '@/api'
|
||||
import { setCache, getCache } from '@/utils'
|
||||
import { getUserInfo as dx_getUserInfoApi } from '@/api/inspector/mine'
|
||||
import { user } from '@/store'
|
||||
import db from '@/utils/db'
|
||||
import toast from '@/utils/toast'
|
||||
|
||||
const emits = defineEmits(['reloadFun']);
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const { getUserInfo, setToken } = user();
|
||||
const emits = defineEmits(['reloadFun'])
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const { getUserInfo, setToken } = user()
|
||||
|
||||
const formatPhone = ref('');
|
||||
const adminPopup = ref();
|
||||
const userAdmin = ref([]); // 用户身份列表
|
||||
const formatPhone = ref('')
|
||||
const adminPopup = ref()
|
||||
const userAdmin = ref([]) // 用户身份列表
|
||||
const loginForm = ref({
|
||||
adminType: 16, // 家长
|
||||
clientType: 'MOBILE',
|
||||
phone: '',
|
||||
verifyCode: '',
|
||||
});
|
||||
const codeTime = ref(0);
|
||||
})
|
||||
const codeTime = ref(0)
|
||||
const codeTimeContet = computed(() => {
|
||||
return codeTime.value;
|
||||
});
|
||||
return codeTime.value
|
||||
})
|
||||
|
||||
function validatePhone() {
|
||||
loginForm.value.phone = formatPhone.value.replace(/\s+/g, '');
|
||||
let reg = /^[1][0,1,2,3, 4, 5, 6, 7, 8, 9][0-9]{9}$/;
|
||||
return reg.test(loginForm.value.phone);
|
||||
loginForm.value.phone = formatPhone.value.replace(/\s+/g, '')
|
||||
let reg = /^[1][0,1,2,3, 4, 5, 6, 7, 8, 9][0-9]{9}$/
|
||||
return reg.test(loginForm.value.phone)
|
||||
}
|
||||
// 手机344分割
|
||||
function phoneDivision() {
|
||||
nextTick(() => {
|
||||
let value = formatPhone.value.replace(/\D/g, '').substr(0, 11);
|
||||
let len = value.length; // 获取长度判断
|
||||
let value = formatPhone.value.replace(/\D/g, '').substr(0, 11)
|
||||
let len = value.length // 获取长度判断
|
||||
if (len > 3 && len < 8) {
|
||||
value = value.replace(/^(\d{3})/g, '$1 ');
|
||||
value = value.replace(/^(\d{3})/g, '$1 ')
|
||||
} else if (len >= 8) {
|
||||
value = value.replace(/^(\d{3})(\d{4})/g, '$1 $2 ');
|
||||
value = value.replace(/^(\d{3})(\d{4})/g, '$1 $2 ')
|
||||
}
|
||||
formatPhone.value = value;
|
||||
});
|
||||
formatPhone.value = value
|
||||
})
|
||||
}
|
||||
// 督学师个人资料
|
||||
async function fetchDXUserInfo() {
|
||||
const { data } = await dx_getUserInfoApi();
|
||||
setCache('dxs_userInfo', data);
|
||||
const { data } = await dx_getUserInfoApi()
|
||||
db.set('dxs_userInfo', data)
|
||||
}
|
||||
// 获取验证码
|
||||
async function getCode() {
|
||||
loginForm.value.phone = formatPhone.value.replace(/\s+/g, '');
|
||||
loginForm.value.phone = formatPhone.value.replace(/\s+/g, '')
|
||||
if (!loginForm.value.phone) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '请输入手机号',
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
try {
|
||||
const res = await sendCodeMessageApi(loginForm.value.phone);
|
||||
uni.showToast({
|
||||
title: '发送成功!',
|
||||
icon: 'none',
|
||||
});
|
||||
codeTime.value = 60;
|
||||
await sendCodeMessageApi(loginForm.value.phone)
|
||||
toast.success('发送成功!')
|
||||
codeTime.value = 60
|
||||
let timer = setInterval(() => {
|
||||
codeTime.value--;
|
||||
codeTime.value--
|
||||
if (codeTime.value < 1) {
|
||||
clearInterval(timer);
|
||||
codeTime.value = 0;
|
||||
clearInterval(timer)
|
||||
codeTime.value = 0
|
||||
}
|
||||
}, 1000);
|
||||
}, 1000)
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
// 登录
|
||||
@ -158,73 +157,80 @@ async function handleLogin() {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '账号或验证码不正确',
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '登录中...',
|
||||
});
|
||||
getAdminTypeByPhone();
|
||||
})
|
||||
getAdminTypeByPhone()
|
||||
}
|
||||
// 用户身份
|
||||
async function getAdminTypeByPhone() {
|
||||
const res = await getAdminTypeByPhoneApi({
|
||||
phone: loginForm.value.phone,
|
||||
});
|
||||
userAdmin.value = res.data;
|
||||
})
|
||||
userAdmin.value = res.data
|
||||
if (userAdmin.value.length <= 1) {
|
||||
// 非多个身份
|
||||
loginForm.value.adminType = userAdmin.value[0].adminType;
|
||||
await smsLogin();
|
||||
if (loginForm.value.adminType === 6) return;
|
||||
loginForm.value.adminType = userAdmin.value[0].adminType
|
||||
await smsLogin()
|
||||
if (loginForm.value.adminType === 6) return
|
||||
} else {
|
||||
// 多个身份
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
|
||||
adminPopup.value = true;
|
||||
adminPopup.value = true
|
||||
}
|
||||
}
|
||||
async function smsLogin() {
|
||||
uni.showLoading({
|
||||
title: '登录中...',
|
||||
});
|
||||
const res = await smsLoginApi(loginForm.value);
|
||||
setToken(res.data);
|
||||
const data = await getUserInfo();
|
||||
})
|
||||
const res = await smsLoginApi(loginForm.value)
|
||||
setToken(res.data)
|
||||
const data = await getUserInfo()
|
||||
|
||||
if (!data.openid) {
|
||||
// 初次注册
|
||||
if (data.adminType === 16) {
|
||||
const authRes = await getAuthUrlApi();
|
||||
const authRes = await getAuthUrlApi()
|
||||
// #ifdef H5
|
||||
window.location.href = authRes.data;
|
||||
window.location.href = authRes.data
|
||||
// #endif
|
||||
// if (data.adminType === 16) {
|
||||
// const authRes = await getAuthUrlApi();
|
||||
// // #ifdef H5
|
||||
// window.location.href = authRes.data;
|
||||
// // #endif
|
||||
// } else {
|
||||
// fetchDXUserInfo();
|
||||
// uni.reLaunch({
|
||||
// url: '/pages/inspector/schedule/index',
|
||||
// });
|
||||
// }
|
||||
} else {
|
||||
fetchDXUserInfo();
|
||||
uni.reLaunch({
|
||||
url: '/pages/inspector/schedule/index',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let adminType = getCache('userInfo').adminType;
|
||||
if (adminType === 16) {
|
||||
uni.reLaunch({
|
||||
url: '/pages/home/index',
|
||||
});
|
||||
} else if (adminType === 6) {
|
||||
fetchDXUserInfo();
|
||||
uni.reLaunch({
|
||||
url: '/pages/inspector/schedule/index',
|
||||
});
|
||||
})
|
||||
// let adminType = getCache('userInfo').adminType;
|
||||
// if (adminType === 16) {
|
||||
// uni.reLaunch({
|
||||
// url: '/pages/home/index',
|
||||
// });
|
||||
// } else if (adminType === 6) {
|
||||
// fetchDXUserInfo();
|
||||
// uni.reLaunch({
|
||||
// url: '/pages/inspector/schedule/index',
|
||||
// });
|
||||
// }
|
||||
}
|
||||
}
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
async function chooseAdmin(i) {
|
||||
loginForm.value.adminType = i.adminType;
|
||||
adminPopup.value = false;
|
||||
await smsLogin();
|
||||
if (loginForm.value.adminType === 6) return;
|
||||
loginForm.value.adminType = i.adminType
|
||||
adminPopup.value = false
|
||||
await smsLogin()
|
||||
if (loginForm.value.adminType === 6) return
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
<z-paging
|
||||
ref="paging"
|
||||
v-model="dataList"
|
||||
:paging-style="{ margin: isAdmin ? '562rpx 30rpx 0 30rpx' : '386rpx 30rpx 0 30rpx' }"
|
||||
:paging-style="{ margin: isAdmin ? '402rpx 30rpx 0 30rpx' : '226rpx 30rpx 0 30rpx' }"
|
||||
:style="{
|
||||
height: isAdmin
|
||||
? `calc(100% - 532rpx - 120rpx - 52rpx)`
|
||||
@ -80,24 +80,25 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, onMounted, nextTick } from 'vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { getParentBindChildApi, getParentBindDeviceApi } from '@/api';
|
||||
import { user } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getCache } from '@/utils';
|
||||
import type { ChildrenType, DeviceType } from './interface';
|
||||
import dayjs from 'dayjs';
|
||||
const { userInfo } = storeToRefs(user());
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`;
|
||||
const empty = `${OSS_URL}/empty.png`;
|
||||
const isAdmin = ref(false);
|
||||
import { reactive, ref, onMounted, nextTick } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { getParentBindChildApi, getParentBindDeviceApi } from '@/api'
|
||||
import { user } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { getCache } from '@/utils'
|
||||
import type { ChildrenType, DeviceType } from './interface'
|
||||
import dayjs from 'dayjs'
|
||||
import db from '@/utils/db'
|
||||
const { userInfo } = storeToRefs(user())
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const empty = `${OSS_URL}/empty.png`
|
||||
const isAdmin = ref(false)
|
||||
// 导航
|
||||
const activeNav = ref({
|
||||
title: '我的孩子',
|
||||
type: 1,
|
||||
});
|
||||
})
|
||||
|
||||
const navList = reactive([
|
||||
{
|
||||
@ -108,67 +109,67 @@ const navList = reactive([
|
||||
title: '我的设备',
|
||||
type: 2,
|
||||
},
|
||||
]);
|
||||
const dataList = ref<any[]>([]);
|
||||
const paging = ref(null);
|
||||
])
|
||||
const dataList = ref<any[]>([])
|
||||
const paging = ref(null)
|
||||
|
||||
function swicthNav(i) {
|
||||
paging.value.reload(true);
|
||||
activeNav.value = i;
|
||||
paging.value.reload(true)
|
||||
activeNav.value = i
|
||||
}
|
||||
|
||||
const queryList = (pageNo: number, pageSize: number) => {
|
||||
if (activeNav.value.type === 1) {
|
||||
getParentBindChildApi({ parentId: userInfo.value.id, current: pageNo, size: pageSize })
|
||||
.then(res => {
|
||||
paging.value.complete(res.data.rows);
|
||||
paging.value.complete(res.data.rows)
|
||||
})
|
||||
.catch(res => {
|
||||
paging.value.complete(false);
|
||||
});
|
||||
paging.value.complete(false)
|
||||
})
|
||||
} else {
|
||||
getParentBindDeviceApi({ parentId: userInfo.value.id, current: pageNo, size: pageSize })
|
||||
.then(res => {
|
||||
paging.value.complete(res.data.rows);
|
||||
paging.value.complete(res.data.rows)
|
||||
})
|
||||
.catch(res => {
|
||||
paging.value.complete(false);
|
||||
});
|
||||
paging.value.complete(false)
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
// 进入详情
|
||||
function handleDetialPage(type: number, obj: any) {
|
||||
let details = encodeURIComponent(JSON.stringify(obj));
|
||||
let details = encodeURIComponent(JSON.stringify(obj))
|
||||
switch (type) {
|
||||
case 1:
|
||||
uni.navigateTo({ url: `/pages/mine/details/childrenDetails?details=${details}` });
|
||||
break;
|
||||
uni.navigateTo({ url: `/pages/mine/details/childrenDetails?details=${details}` })
|
||||
break
|
||||
case 2:
|
||||
uni.navigateTo({ url: `/pages/mine/details/deviceDetails?details=${details}` });
|
||||
break;
|
||||
uni.navigateTo({ url: `/pages/mine/details/deviceDetails?details=${details}` })
|
||||
break
|
||||
}
|
||||
}
|
||||
// 绑定
|
||||
function handleBindDevice() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/bindDevice/index',
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
const toMySupervisionService = child => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/parents/mySupervisionService/index?id=${child.childId}`,
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
if (paging.value) {
|
||||
paging.value.refresh();
|
||||
paging.value.refresh()
|
||||
}
|
||||
});
|
||||
})
|
||||
onMounted(() => {
|
||||
isAdmin.value = getCache('userAdmin');
|
||||
});
|
||||
isAdmin.value = db.get('userAdmin')
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<text class="name">{{ userInfo.nickName }}</text>
|
||||
<text class="identity">家长</text>
|
||||
</view>
|
||||
<view class="function">
|
||||
<!-- <view class="function">
|
||||
<template v-for="i in list" :key="i.title">
|
||||
<view v-if="i.show" class="function_item" @click="handleJump(i)">
|
||||
<view class="photo_box">
|
||||
@ -19,20 +19,21 @@
|
||||
<text class="title">{{ i.title }}</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { user } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getCache } from '@/utils';
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { user } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { getCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
|
||||
const { userInfo } = storeToRefs(user());
|
||||
const { userInfo } = storeToRefs(user())
|
||||
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`;
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const list = ref([
|
||||
{
|
||||
title: '扫码绑定',
|
||||
@ -70,22 +71,22 @@ const list = ref([
|
||||
show: true,
|
||||
url: '/pages/mine/awardManage/index',
|
||||
},
|
||||
]);
|
||||
])
|
||||
function handleJump(i: AnyObject) {
|
||||
uni.navigateTo({
|
||||
url: i.url,
|
||||
});
|
||||
})
|
||||
}
|
||||
// 完善信息
|
||||
function handlePrefectInfo() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/prefectInformation/index?type=1`,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
list.value[1].show = getCache('userAdmin');
|
||||
});
|
||||
list.value[1].show = db.get('userAdmin')
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
136
src/router/router.ts
Normal file
136
src/router/router.ts
Normal file
@ -0,0 +1,136 @@
|
||||
import db from '../utils/db'
|
||||
import dict from '../utils/dict'
|
||||
import page from '../utils/page'
|
||||
import qs from 'qs'
|
||||
|
||||
// 页面路径常量
|
||||
export const route_login = '/pages/login/index'
|
||||
export const route_home = '/pages/home/index'
|
||||
|
||||
// 免token的路由
|
||||
const noTokenRoutes = [route_login]
|
||||
|
||||
export type _RouterNoPathOptions = {
|
||||
query?: any
|
||||
}
|
||||
|
||||
export type _RouterOptions = {
|
||||
path: string
|
||||
} & _RouterNoPathOptions
|
||||
|
||||
export type RouterOptions = _RouterOptions | string
|
||||
|
||||
// 封装 navigateTo
|
||||
function navigateTo(options: RouterOptions) {
|
||||
const to = beforeEach(options)
|
||||
if (!to) return
|
||||
uni.navigateTo(to)
|
||||
}
|
||||
|
||||
// 封装 redirectTo
|
||||
function redirectTo(options: RouterOptions) {
|
||||
const to = beforeEach(options)
|
||||
if (!to) return
|
||||
uni.redirectTo(to)
|
||||
}
|
||||
|
||||
// 封装 switchTab
|
||||
function switchTab(options: RouterOptions) {
|
||||
const to = beforeEach(options)
|
||||
if (!to) return
|
||||
uni.switchTab(to)
|
||||
}
|
||||
|
||||
// 封装 reLaunch
|
||||
function reLaunch(options: RouterOptions) {
|
||||
const to = beforeEach(options)
|
||||
if (!to) return
|
||||
uni.reLaunch(to)
|
||||
}
|
||||
|
||||
// 封装 navigateBack
|
||||
function navigateBack(options: RouterOptions) {
|
||||
const to = beforeEach(options)
|
||||
if (!to) return
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
// 去登录页面
|
||||
function toLogin(options?: _RouterNoPathOptions) {
|
||||
// db.pop('token')
|
||||
reLaunch({
|
||||
...options,
|
||||
path: route_login,
|
||||
})
|
||||
}
|
||||
|
||||
// 去首页
|
||||
function toHome(options?: _RouterNoPathOptions) {
|
||||
reLaunch({
|
||||
...options,
|
||||
path: route_home,
|
||||
})
|
||||
}
|
||||
|
||||
interface RouterBeforeOptions {
|
||||
from: _RouterOptions
|
||||
to: _RouterOptions
|
||||
}
|
||||
|
||||
// 自定义路由守卫函数
|
||||
function beforeEach(options: RouterOptions) {
|
||||
const beforeOptions: RouterBeforeOptions = {} as any
|
||||
if (typeof options === 'string') {
|
||||
// 对字符串参数进行处理
|
||||
options = {
|
||||
path: options,
|
||||
}
|
||||
}
|
||||
if (options.path) {
|
||||
beforeOptions.to = options
|
||||
}
|
||||
// 对from进行处理
|
||||
beforeOptions.from = {
|
||||
path: page.getPagePath(),
|
||||
}
|
||||
|
||||
// 最终封装成options = {from:{url}, to:{url}}
|
||||
const { from, to } = beforeOptions
|
||||
|
||||
// 登录页面下跳转登录页面,跳转到首页
|
||||
if (from.path === to.path && to.path === route_login) {
|
||||
return false
|
||||
}
|
||||
|
||||
console.log('beforeEach', from, to)
|
||||
|
||||
// 执行跳转
|
||||
const token = db.get('token')
|
||||
if (!noTokenRoutes.includes(to.path) && !token) {
|
||||
console.log('token 过期')
|
||||
toLogin(to)
|
||||
return false
|
||||
}
|
||||
|
||||
let toUrl = to.path
|
||||
if (to.query) {
|
||||
toUrl += '?' + qs.stringify(to.query)
|
||||
}
|
||||
const pageObj = {
|
||||
...to,
|
||||
url: toUrl,
|
||||
}
|
||||
console.log('跳转', pageObj)
|
||||
return pageObj
|
||||
}
|
||||
|
||||
// 导出封装的方法
|
||||
export default {
|
||||
navigateTo,
|
||||
redirectTo,
|
||||
switchTab,
|
||||
reLaunch,
|
||||
navigateBack,
|
||||
toLogin,
|
||||
toHome,
|
||||
}
|
@ -1,24 +1,25 @@
|
||||
import { getCache, setCache } from '@/utils';
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
import { user } from '@/store';
|
||||
import { bindAuthInfoApi } from '@/api';
|
||||
const { afterLogin, getUserInfo } = user();
|
||||
import { getCache, setCache } from '@/utils'
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { user } from '@/store'
|
||||
import { bindAuthInfoApi } from '@/api'
|
||||
import db from '@/utils/db'
|
||||
const { afterLogin, getUserInfo } = user()
|
||||
// const { } = user();
|
||||
|
||||
export const h5Authorization = defineStore('h5Authorization', () => {
|
||||
const H5Openid = ref('');
|
||||
const H5Openid = ref('')
|
||||
|
||||
const authorizedLogin = async () => {
|
||||
// if (getCache('userInfo')) {
|
||||
// await getUserInfo();
|
||||
// }
|
||||
const code = getQueryString('code');
|
||||
const state = getQueryString('state');
|
||||
console.log('进入授权code和state', code, state);
|
||||
const code = getQueryString('code')
|
||||
const state = getQueryString('state')
|
||||
console.log('进入授权code和state', code, state)
|
||||
if (code) {
|
||||
const userInfo = getCache('userInfo');
|
||||
console.log('code----', code, state);
|
||||
const userInfo = db.get('userInfo')
|
||||
console.log('code----', code, state)
|
||||
bindAuthInfoApi({
|
||||
code: code,
|
||||
userId: state,
|
||||
@ -27,10 +28,10 @@ export const h5Authorization = defineStore('h5Authorization', () => {
|
||||
// setCache('H5_OPENID', res.data.openId);
|
||||
// setCache('H5_UNIONID', res.data.unionId);
|
||||
// setCache('token', res.data.token);
|
||||
await afterLogin();
|
||||
});
|
||||
await afterLogin()
|
||||
})
|
||||
} else {
|
||||
console.log('正常进入');
|
||||
console.log('正常进入')
|
||||
// setCache('H5_OPENID', 'oz5g76wH2PLF9_KcbU5ztfYp6ySI');
|
||||
// setCache('H5_UNIONID', 'oZnpF6aZjben0hSMvbYP4fVKyndc');
|
||||
// setCache('token', 'eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjE2ODA0MTU3NjUwOTA1OTQ4MTcsImFjY291bnQiOiIxNzY3MTYxNzkwOSIsInV1aWQiOiIzZWZhMThmMC1iOWYzLTQxYTctODkyZC1lNGY5ZDQ4MTVkYjMiLCJjbGllbnRUeXBlRW51bSI6Ik9GRklDSUFMIiwic3ViIjoiMTY4MDQxNTc2NTA5MDU5NDgxNyIsImlhdCI6MTcxNjE4ODU3NiwiZXhwIjoxNzE2NzkzMzc2fQ._1ijks84fNWBmBSPwpFwy8SR7-QOaOJRAO49H63awCxzwIB4kLhdsZPdR61h0PoF5vDzLjIV2CSw9faT0HVkGw');
|
||||
@ -41,16 +42,16 @@ export const h5Authorization = defineStore('h5Authorization', () => {
|
||||
// );
|
||||
// window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd13aabeb40898e1d&redirect_uri=${thisUrl}&response_type=code&scope=snsapi_userinfo&state=123&connect_redirect=1#wechat_redirect`;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const getQueryString = (name: string) => {
|
||||
const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i');
|
||||
const r = window.location.search.substring(1).match(reg);
|
||||
if (r !== null) return decodeURI(r[2]);
|
||||
return null;
|
||||
};
|
||||
const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i')
|
||||
const r = window.location.search.substring(1).match(reg)
|
||||
if (r !== null) return decodeURI(r[2])
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
authorizedLogin,
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -1,26 +1,27 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
import { setCache } from '@/utils';
|
||||
import { applyBindInfoListApi } from '@/api';
|
||||
import type { BindApplyItemType } from '@/pages/mine/interface';
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { setCache } from '@/utils'
|
||||
import { applyBindInfoListApi } from '@/api'
|
||||
import type { BindApplyItemType } from '@/pages/mine/interface'
|
||||
import db from '@/utils/db'
|
||||
export const bindApplyStore = defineStore('bindApplyStore', () => {
|
||||
const bindApplyList = ref<BindApplyItemType[]>();
|
||||
const bindApplyList = ref<BindApplyItemType[]>()
|
||||
// 未处理的绑定申请列表
|
||||
const getApplyBindInfoList = async () => {
|
||||
try {
|
||||
const { data } = await applyBindInfoListApi();
|
||||
bindApplyList.value = data;
|
||||
const { data } = await applyBindInfoListApi()
|
||||
bindApplyList.value = data
|
||||
if (bindApplyList.value.length === 0) {
|
||||
setCache('applyBindMsg', false);
|
||||
db.set('applyBindMsg', false)
|
||||
} else {
|
||||
setCache('applyBindMsg', true);
|
||||
db.set('applyBindMsg', true)
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
};
|
||||
return {
|
||||
bindApplyList,
|
||||
getApplyBindInfoList,
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -1,41 +1,42 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
import { getDict as getDictApi, getUnreadNum } from '@/api';
|
||||
import { setCache, getCache, removeCache, ArrToObj } from '@/utils';
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { getDict as getDictApi, getUnreadNum } from '@/api'
|
||||
import { setCache, getCache, removeCache, ArrToObj } from '@/utils'
|
||||
// import { SOCKET_STATUS } from '@/types';
|
||||
import { user } from '@/store';
|
||||
import { user } from '@/store'
|
||||
import db from '@/utils/db'
|
||||
|
||||
export const global = defineStore('global', () => {
|
||||
const dict = ref(getCache('dict') || {});
|
||||
const dict = ref(db.get('dict') || {})
|
||||
// 获取字典列表
|
||||
const getDicts = async () => {
|
||||
const res = await getDictApi();
|
||||
dict.value = res.data;
|
||||
setCache('dict', res.data);
|
||||
};
|
||||
const res = await getDictApi()
|
||||
dict.value = res.data
|
||||
db.set('dict', res.data)
|
||||
}
|
||||
|
||||
// 获取字典
|
||||
const getDict = (key: string, full = false) => {
|
||||
const d = dict.value.find((i: anyObj) => i.code === key);
|
||||
const child = d ? d.children : [];
|
||||
const d = dict.value.find((i: anyObj) => i.code === key)
|
||||
const child = d ? d.children : []
|
||||
if (full) {
|
||||
return {
|
||||
dict: child,
|
||||
dictObj: ArrToObj(child, 'value', 'code'),
|
||||
};
|
||||
}
|
||||
return child;
|
||||
};
|
||||
}
|
||||
return child
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
dict.value = {};
|
||||
removeCache('dict');
|
||||
};
|
||||
dict.value = {}
|
||||
removeCache('dict')
|
||||
}
|
||||
|
||||
return {
|
||||
dict,
|
||||
getDicts,
|
||||
getDict,
|
||||
clear,
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -1,97 +1,98 @@
|
||||
import { defineStore, storeToRefs } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { global } from './global';
|
||||
import { getCache, setCache } from '@/utils';
|
||||
import { global } from './global'
|
||||
import { getCache, setCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
export const socket = defineStore('socket', () => {
|
||||
const socket = ref();
|
||||
const status = ref(true); // true在线 false离线
|
||||
let hbTimer: any;
|
||||
const hbDelay = 25000;
|
||||
let rcTimer: any;
|
||||
let count = 0;
|
||||
let socketStatus = 0;
|
||||
const channelId = '';
|
||||
const rcDelay = 10000;
|
||||
const socket = ref()
|
||||
const status = ref(true) // true在线 false离线
|
||||
let hbTimer: any
|
||||
const hbDelay = 25000
|
||||
let rcTimer: any
|
||||
let count = 0
|
||||
let socketStatus = 0
|
||||
const channelId = ''
|
||||
const rcDelay = 10000
|
||||
|
||||
const callBackList = ref<((...args: []) => void)[]>([]);
|
||||
const callBackList = ref<((...args: []) => void)[]>([])
|
||||
|
||||
function beforeInit() {
|
||||
if (socketStatus > 0) return false;
|
||||
socket.value?.close(); // 关闭之前的socket
|
||||
return true;
|
||||
if (socketStatus > 0) return false
|
||||
socket.value?.close() // 关闭之前的socket
|
||||
return true
|
||||
}
|
||||
async function initSocket(simSerialNumber: string) {
|
||||
const token = getCache('token');
|
||||
init();
|
||||
const token = db.get('token')
|
||||
init()
|
||||
function init() {
|
||||
if (!beforeInit()) return;
|
||||
if (!beforeInit()) return
|
||||
socket.value = uni.connectSocket({
|
||||
url: `${process.env.VITE_WS_URL}?accessToken=${token}`,
|
||||
complete: () => {},
|
||||
});
|
||||
})
|
||||
|
||||
socket.value.onOpen(() => {
|
||||
console.log('Socket已打开!', simSerialNumber);
|
||||
count = 0;
|
||||
socketStatus = 10;
|
||||
clearInterval(hbTimer);
|
||||
clearInterval(rcTimer);
|
||||
heartBeat(); // 心跳
|
||||
socketSend({ type: 'desktopPreview', simSerialNumber: simSerialNumber });
|
||||
console.log('Socket已打开!', simSerialNumber)
|
||||
count = 0
|
||||
socketStatus = 10
|
||||
clearInterval(hbTimer)
|
||||
clearInterval(rcTimer)
|
||||
heartBeat() // 心跳
|
||||
socketSend({ type: 'desktopPreview', simSerialNumber: simSerialNumber })
|
||||
// status.value = SOCKET_STATUS.CONNECTED;
|
||||
});
|
||||
})
|
||||
socket.value.onError((err: any) => {
|
||||
// console.log('Socket打开失败!');
|
||||
console.error(err);
|
||||
socketStatus = 0;
|
||||
console.error(err)
|
||||
socketStatus = 0
|
||||
// status.value = SOCKET_STATUS.OFFLINE;
|
||||
reconnect();
|
||||
});
|
||||
reconnect()
|
||||
})
|
||||
socket.value.onClose((err: any) => {
|
||||
// console.log('Socket已断开!');
|
||||
console.error(err);
|
||||
socketStatus = 0;
|
||||
console.error(err)
|
||||
socketStatus = 0
|
||||
// status.value = SOCKET_STATUS.OFFLINE;
|
||||
reconnect();
|
||||
});
|
||||
reconnect()
|
||||
})
|
||||
socket.value.onMessage((res: anyObj) => {
|
||||
// 接收服务器返回信息
|
||||
const info = JSON.parse(res.data);
|
||||
console.log('socketMsg', info);
|
||||
uni.$emit('socketMsg', info);
|
||||
});
|
||||
const info = JSON.parse(res.data)
|
||||
console.log('socketMsg', info)
|
||||
uni.$emit('socketMsg', info)
|
||||
})
|
||||
}
|
||||
|
||||
// 心跳
|
||||
function _heartBeat() {
|
||||
// console.log('心跳')
|
||||
if (!getCache('token')) {
|
||||
socket.value?.close();
|
||||
clearInterval(hbTimer);
|
||||
return;
|
||||
if (!db.get('token')) {
|
||||
socket.value?.close()
|
||||
clearInterval(hbTimer)
|
||||
return
|
||||
}
|
||||
socketSend({
|
||||
message: 'ping',
|
||||
});
|
||||
})
|
||||
}
|
||||
function heartBeat() {
|
||||
_heartBeat(); // 首次连上必须ping才建立通道
|
||||
hbTimer = setInterval(() => _heartBeat(), hbDelay);
|
||||
_heartBeat() // 首次连上必须ping才建立通道
|
||||
hbTimer = setInterval(() => _heartBeat(), hbDelay)
|
||||
}
|
||||
|
||||
// 重连
|
||||
function reconnect(leading = false) {
|
||||
clearInterval(hbTimer);
|
||||
clearInterval(hbTimer)
|
||||
if (leading) {
|
||||
init();
|
||||
return;
|
||||
init()
|
||||
return
|
||||
}
|
||||
rcTimer = setTimeout(() => {
|
||||
count++;
|
||||
console.error(`Socket尝试重连(第${count}次)`);
|
||||
init();
|
||||
}, 10000);
|
||||
count++
|
||||
console.error(`Socket尝试重连(第${count}次)`)
|
||||
init()
|
||||
}, 10000)
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,31 +103,31 @@ export const socket = defineStore('socket', () => {
|
||||
|
||||
// 发送消息
|
||||
function socketSend(value: any) {
|
||||
console.log('send', value);
|
||||
console.log('send', value)
|
||||
socket.value.send({
|
||||
data: JSON.stringify(value),
|
||||
success: () => {
|
||||
console.log('发送成功');
|
||||
console.log('发送成功')
|
||||
},
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 增加回调
|
||||
function addCallBack(cb: any) {
|
||||
if (callBackList.value.some(i => i === cb)) return;
|
||||
callBackList.value.push(cb);
|
||||
if (callBackList.value.some(i => i === cb)) return
|
||||
callBackList.value.push(cb)
|
||||
}
|
||||
|
||||
// 删除回调
|
||||
function removeCallBack(cb: any) {
|
||||
const idx = callBackList.value.findIndex(i => i === cb);
|
||||
if (idx === -1) return;
|
||||
callBackList.value.splice(idx, 1);
|
||||
const idx = callBackList.value.findIndex(i => i === cb)
|
||||
if (idx === -1) return
|
||||
callBackList.value.splice(idx, 1)
|
||||
}
|
||||
|
||||
// 关闭socket
|
||||
function closeSocket() {
|
||||
socket.value?.close();
|
||||
socket.value?.close()
|
||||
}
|
||||
|
||||
return {
|
||||
@ -139,5 +140,5 @@ export const socket = defineStore('socket', () => {
|
||||
removeCallBack,
|
||||
closeSocket,
|
||||
callback,
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import {
|
||||
// phoneLogin as phoneLoginApi,
|
||||
getUserInfo as getUserInfoApi,
|
||||
@ -9,96 +9,71 @@ import {
|
||||
bindRegId,
|
||||
userInfoPermitApi,
|
||||
// updatePwdByPhone,
|
||||
} from '@/api';
|
||||
} from '@/api'
|
||||
// import type { smsLoginType, accountLoginType, updatePasswordType } from '@/api';
|
||||
// import defaultAvatar from "@/static/default_avatar.png";
|
||||
import { setCache, getCache } from '@/utils';
|
||||
import { global } from '@/store';
|
||||
import { setCache, getCache } from '@/utils'
|
||||
import { global } from '@/store'
|
||||
import db from '@/utils/db'
|
||||
|
||||
export const user = defineStore('user', () => {
|
||||
const userInfo = ref(getCache('userInfo') || {});
|
||||
const csInfo = ref(getCache('csInfo') || {});
|
||||
const token = ref(getCache('token') || '');
|
||||
// const { clear: chatClear } = chat();
|
||||
const { getDicts } = global();
|
||||
|
||||
// const phoneLogin = async (data: smsLoginType) => {
|
||||
// await beforeLogin();
|
||||
// const res = await phoneLoginApi(data);
|
||||
// token.value = res.data;
|
||||
// setCache('token', res.data);
|
||||
// await afterLogin();
|
||||
// };
|
||||
|
||||
// const accordLogin = async (data: accountLoginType) => {
|
||||
// await beforeLogin();
|
||||
// const res = await psdLoginApi(data);
|
||||
// token.value = res.data;
|
||||
// setCache('token', res.data);
|
||||
// await afterLogin();
|
||||
// };
|
||||
|
||||
// const updatePassword = async (data: updatePasswordType) => {
|
||||
// await updatePwdByPhone(data);
|
||||
// };
|
||||
|
||||
// const beforeLogin = async () => {
|
||||
// // chatClear();
|
||||
// await clear();
|
||||
// };
|
||||
const userInfo = ref(db.get('userInfo') || ({} as any))
|
||||
const csInfo = ref(db.get('csInfo') || {})
|
||||
const token = ref(db.get('token') || '')
|
||||
const { getDicts } = global()
|
||||
|
||||
const afterLogin = async () => {
|
||||
await Promise.allSettled([getUserInfo(), getDicts()]);
|
||||
await Promise.allSettled([getUserInfo(), getDicts()])
|
||||
// getCsInfo(); // 需等待用户信息加载完毕
|
||||
};
|
||||
}
|
||||
|
||||
const logout = async () => {
|
||||
// #ifdef APP-PLUS
|
||||
if (getCache('registerID')) {
|
||||
if (db.get('registerID')) {
|
||||
await bindRegId({
|
||||
registrationId: getCache('registerID'),
|
||||
registrationId: db.get('registerID'),
|
||||
type: 2,
|
||||
});
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
await logoutApi();
|
||||
clear();
|
||||
await logoutApi()
|
||||
clear()
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/index',
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
const getUserInfo = async () => {
|
||||
const res = await getUserInfoApi();
|
||||
console.log('userInfo', res.data);
|
||||
userInfo.value = res.data;
|
||||
setCache('userInfo', res.data);
|
||||
getUserInfoPermit();
|
||||
return res.data;
|
||||
};
|
||||
const res = await getUserInfoApi()
|
||||
console.log('userInfo', res.data)
|
||||
userInfo.value = res.data
|
||||
db.set('userInfo', res.data)
|
||||
getUserInfoPermit()
|
||||
return res.data
|
||||
}
|
||||
// 当前登录用户是否管理员身份
|
||||
async function getUserInfoPermit() {
|
||||
const { data } = await userInfoPermitApi();
|
||||
setCache('userAdmin', data);
|
||||
const { data } = await userInfoPermitApi()
|
||||
db.set('userAdmin', data)
|
||||
}
|
||||
const getCsInfo = async () => {
|
||||
const res = await getCsInfoApi(userInfo.value.id);
|
||||
csInfo.value = res.data;
|
||||
setCache('csInfo', res.data);
|
||||
return res.data;
|
||||
};
|
||||
const res = await getCsInfoApi(userInfo.value.id)
|
||||
csInfo.value = res.data
|
||||
db.set('csInfo', res.data)
|
||||
return res.data
|
||||
}
|
||||
|
||||
const clear = async () => {
|
||||
token.value = '';
|
||||
userInfo.value = {};
|
||||
csInfo.value = {};
|
||||
await uni.clearStorageSync();
|
||||
};
|
||||
token.value = ''
|
||||
userInfo.value = {}
|
||||
csInfo.value = {}
|
||||
await db.clear()
|
||||
}
|
||||
|
||||
const setToken = (data: string) => {
|
||||
token.value = data;
|
||||
setCache('token', data);
|
||||
};
|
||||
token.value = data
|
||||
db.set('token', data)
|
||||
}
|
||||
|
||||
return {
|
||||
userInfo,
|
||||
@ -115,5 +90,5 @@ export const user = defineStore('user', () => {
|
||||
clear,
|
||||
afterLogin,
|
||||
setToken,
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
|
37
src/utils/db.ts
Normal file
37
src/utils/db.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import page from './page'
|
||||
|
||||
// 可以在不同的地方共享数据、传参
|
||||
function get<T>(key?: string, defaultValue?: T): T {
|
||||
if (!key) {
|
||||
key = page.getPagePath()
|
||||
}
|
||||
const val = uni.getStorageSync(key)
|
||||
return (val === undefined ? defaultValue : val) as T
|
||||
}
|
||||
|
||||
// 设值
|
||||
function set(key: string, value: any) {
|
||||
uni.setStorageSync(key, value)
|
||||
}
|
||||
|
||||
// 弹出值
|
||||
function pop<T>(key?: string, defaultValue?: T): T {
|
||||
if (!key) {
|
||||
key = page.getPagePath()
|
||||
}
|
||||
const value = uni.getStorageSync(key)
|
||||
uni.removeStorageSync(key)
|
||||
return value || defaultValue
|
||||
}
|
||||
|
||||
// 清空
|
||||
function clear() {
|
||||
uni.clearStorageSync()
|
||||
}
|
||||
|
||||
export default {
|
||||
get,
|
||||
set,
|
||||
pop,
|
||||
clear,
|
||||
}
|
79
src/utils/dict.ts
Normal file
79
src/utils/dict.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import page from './page'
|
||||
|
||||
// 可以在不同的地方共享数据、传参
|
||||
let _DATA: { [key: string]: any } = {}
|
||||
|
||||
function get<T>(key?: string, defaultValue?: T): T {
|
||||
if (!key) {
|
||||
key = page.getPagePath()
|
||||
}
|
||||
const val = _DATA[key]
|
||||
return (val === undefined ? defaultValue : val) as T
|
||||
}
|
||||
|
||||
// 设值
|
||||
function set(key: string, value: any) {
|
||||
_DATA[key] = value
|
||||
}
|
||||
|
||||
// 弹出值
|
||||
function pop<T>(key?: string, defaultValue?: T): T {
|
||||
if (!key) {
|
||||
key = page.getPagePath()
|
||||
}
|
||||
const value = _DATA[key]
|
||||
delete _DATA[key]
|
||||
return value || defaultValue
|
||||
}
|
||||
|
||||
// 清空
|
||||
function clear() {
|
||||
_DATA = {}
|
||||
}
|
||||
|
||||
// 函数的key
|
||||
function _pageFnObjKey(pageUrl: string) {
|
||||
return pageUrl + '_mj_fn_obj'
|
||||
}
|
||||
|
||||
function _getPageFnObj(pageUrl: string) {
|
||||
const key = _pageFnObjKey(pageUrl)
|
||||
let fnObj = _DATA[key]
|
||||
if (!fnObj) {
|
||||
fnObj = {}
|
||||
_DATA[key] = fnObj
|
||||
}
|
||||
return fnObj
|
||||
}
|
||||
|
||||
// 调用函数
|
||||
function callFn(key: string, ...args: any) {
|
||||
// 函数对象
|
||||
const fn = _getPageFnObj(page.getPagePath())[key]
|
||||
if (fn) {
|
||||
// 直接调用
|
||||
return fn(...args)
|
||||
}
|
||||
// console.log('callFn', _DATA)
|
||||
}
|
||||
|
||||
// 存储函数
|
||||
function setFn(key: string, fn: any) {
|
||||
_getPageFnObj(page.getPagePath())[key] = fn
|
||||
// console.log('setFn', _DATA)
|
||||
}
|
||||
|
||||
function popPageFns(pageUrl: string) {
|
||||
delete _DATA[_pageFnObjKey(pageUrl)]
|
||||
// console.log('popPageFns', _DATA)
|
||||
}
|
||||
|
||||
export default {
|
||||
get,
|
||||
set,
|
||||
pop,
|
||||
clear,
|
||||
callFn,
|
||||
setFn,
|
||||
popPageFns,
|
||||
}
|
25
src/utils/obj.ts
Normal file
25
src/utils/obj.ts
Normal file
@ -0,0 +1,25 @@
|
||||
// 对象相关处理
|
||||
function clearNullProps(obj: any) {
|
||||
for (const key in obj) {
|
||||
if (obj[key] === null || obj[key] === undefined) {
|
||||
delete obj[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 计算父节点和子节点的总数
|
||||
function getNodesSize(nodes: any[], childrenKey = 'children') {
|
||||
let size = 0
|
||||
for (const node of nodes) {
|
||||
size += 1
|
||||
if (node[childrenKey]?.length > 0) {
|
||||
size += getNodesSize(node.children, childrenKey)
|
||||
}
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
export default {
|
||||
clearNullProps,
|
||||
getNodesSize,
|
||||
}
|
15
src/utils/page.ts
Normal file
15
src/utils/page.ts
Normal file
@ -0,0 +1,15 @@
|
||||
const DATA: { [key: string]: any } = {}
|
||||
|
||||
function getPage() {
|
||||
const pages = getCurrentPages()
|
||||
return pages[pages.length - 1]
|
||||
}
|
||||
|
||||
function getPagePath() {
|
||||
return '/' + getPage().route
|
||||
}
|
||||
|
||||
export default {
|
||||
getPage,
|
||||
getPagePath,
|
||||
}
|
51
src/utils/toast.ts
Normal file
51
src/utils/toast.ts
Normal file
@ -0,0 +1,51 @@
|
||||
export async function info(text: string, duration?: number) {}
|
||||
|
||||
export async function error(text: string, duration?: number) {
|
||||
uni.showToast({
|
||||
title: text,
|
||||
icon: 'none',
|
||||
duration,
|
||||
})
|
||||
}
|
||||
|
||||
export async function warn(text: string, duration?: number) {}
|
||||
|
||||
export async function success(text: string, duration?: number) {
|
||||
uni.showToast({
|
||||
title: text,
|
||||
icon: 'none',
|
||||
duration,
|
||||
})
|
||||
}
|
||||
|
||||
export async function primary(text: string, duration?: number) {}
|
||||
|
||||
export function loading(text: string = '加载中...') {
|
||||
uni.showLoading({
|
||||
title: text,
|
||||
mask: true,
|
||||
})
|
||||
}
|
||||
|
||||
export function dialog(text: string) {
|
||||
uni.showModal({
|
||||
content: text,
|
||||
confirmText: '知道了',
|
||||
showCancel: false,
|
||||
})
|
||||
}
|
||||
|
||||
export function hide() {
|
||||
uni.hideLoading()
|
||||
}
|
||||
|
||||
export default {
|
||||
info,
|
||||
success,
|
||||
error,
|
||||
loading,
|
||||
warn,
|
||||
primary,
|
||||
hide,
|
||||
dialog,
|
||||
}
|
@ -1,29 +1,30 @@
|
||||
import dayjs from 'dayjs';
|
||||
import isToday from 'dayjs/plugin/isToday';
|
||||
import isYesterday from 'dayjs/plugin/isYesterday';
|
||||
import dayjs from 'dayjs'
|
||||
import isToday from 'dayjs/plugin/isToday'
|
||||
import isYesterday from 'dayjs/plugin/isYesterday'
|
||||
import db from './db'
|
||||
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`;
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
|
||||
dayjs.extend(isToday);
|
||||
dayjs.extend(isYesterday);
|
||||
dayjs.extend(isToday)
|
||||
dayjs.extend(isYesterday)
|
||||
// store统一设置
|
||||
export const setCache = (key: string, value: any) => {
|
||||
if (!key) throw new Error('key is required');
|
||||
uni.setStorageSync(`QY_${key?.toUpperCase()}`, value);
|
||||
};
|
||||
if (!key) throw new Error('key is required')
|
||||
uni.setStorageSync(`QY_${key?.toUpperCase()}`, value)
|
||||
}
|
||||
export const getCache = (key: string) => {
|
||||
if (!key) throw new Error('key is required');
|
||||
return uni.getStorageSync(`QY_${key?.toUpperCase()}`);
|
||||
};
|
||||
if (!key) throw new Error('key is required')
|
||||
return uni.getStorageSync(`QY_${key?.toUpperCase()}`)
|
||||
}
|
||||
export const removeCache = (key: string) => {
|
||||
if (!key) throw new Error('key is required');
|
||||
uni.removeStorageSync(`QY_${key?.toUpperCase()}`);
|
||||
};
|
||||
if (!key) throw new Error('key is required')
|
||||
uni.removeStorageSync(`QY_${key?.toUpperCase()}`)
|
||||
}
|
||||
|
||||
// 随机ID
|
||||
export const genId = (prefix?: number | string) =>
|
||||
`${prefix || ''}${Math.random().toString(16).slice(2)}`;
|
||||
`${prefix || ''}${Math.random().toString(16).slice(2)}`
|
||||
|
||||
// 将数组映射为对象
|
||||
export const ArrToObj = (
|
||||
@ -31,61 +32,61 @@ export const ArrToObj = (
|
||||
key = 'code',
|
||||
value = 'value',
|
||||
): { [key: string]: string } => {
|
||||
const obj: anyObj = {};
|
||||
let i = 0;
|
||||
const obj: anyObj = {}
|
||||
let i = 0
|
||||
for (i; i < arr.length; i++) {
|
||||
obj[arr[i][key]] = arr[i][value];
|
||||
obj[arr[i][key]] = arr[i][value]
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
return obj
|
||||
}
|
||||
|
||||
// 延迟运行
|
||||
export const $sleep = (time: number) => {
|
||||
return new Promise(res => {
|
||||
const timeout = setTimeout(() => {
|
||||
res(0);
|
||||
clearTimeout(timeout);
|
||||
}, time);
|
||||
});
|
||||
};
|
||||
res(0)
|
||||
clearTimeout(timeout)
|
||||
}, time)
|
||||
})
|
||||
}
|
||||
|
||||
export function formCheck(rules: anyObj[], data: anyObj) {
|
||||
let res = true;
|
||||
let res = true
|
||||
for (const i of rules) {
|
||||
if (i instanceof Array) {
|
||||
for (const j of i) {
|
||||
if (j.required && !data[j.prop]) {
|
||||
res = false;
|
||||
res = false
|
||||
uni.showToast({
|
||||
title: j.message,
|
||||
icon: 'none',
|
||||
});
|
||||
break;
|
||||
})
|
||||
break
|
||||
}
|
||||
if (j.validator) {
|
||||
j.validator(data, data[j.prop], (result: any) => {
|
||||
if (result instanceof Error) {
|
||||
res = false;
|
||||
res = false
|
||||
uni.showToast({
|
||||
title: j.message,
|
||||
icon: 'none',
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (i.required && !data[i.prop]) {
|
||||
res = false;
|
||||
res = false
|
||||
uni.showToast({
|
||||
title: i.message,
|
||||
icon: 'none',
|
||||
});
|
||||
break;
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return res
|
||||
}
|
||||
|
||||
// // uniApi转换成同步
|
||||
@ -121,46 +122,77 @@ export const uploadFile = path =>
|
||||
filePath: path,
|
||||
name: 'file',
|
||||
header: {
|
||||
Authorization: `Bearer ${getCache('token')}`,
|
||||
Authorization: `Bearer ${db.get('token')}`,
|
||||
},
|
||||
success: uploadFileRes => {
|
||||
const data = JSON.parse(uploadFileRes.data);
|
||||
const data = JSON.parse(uploadFileRes.data)
|
||||
if (uploadFileRes.statusCode === 200) {
|
||||
resolve(data.data);
|
||||
resolve(data.data)
|
||||
} else {
|
||||
reject(data.message);
|
||||
reject(data.message)
|
||||
}
|
||||
},
|
||||
fail: error => {
|
||||
reject(error);
|
||||
reject(error)
|
||||
},
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* 分钟转小时与分钟
|
||||
*/
|
||||
export const minToHour = (min: number) => {
|
||||
const h = Math.floor(min / 60);
|
||||
const m = min % 60;
|
||||
return [h, m];
|
||||
};
|
||||
const h = Math.floor(min / 60)
|
||||
const m = min % 60
|
||||
return [h, m]
|
||||
}
|
||||
|
||||
export const formatDate = (time: string) => {
|
||||
const timestamp = new Date(time).getTime();
|
||||
const date = dayjs(timestamp);
|
||||
if (date.isToday()) return date.format('HH:mm');
|
||||
if (date.isYesterday()) return `昨天 ${date.format('HH:mm')}`;
|
||||
const timestamp = new Date(time).getTime()
|
||||
const date = dayjs(timestamp)
|
||||
if (date.isToday()) return date.format('HH:mm')
|
||||
if (date.isYesterday()) return `昨天 ${date.format('HH:mm')}`
|
||||
if (date.isSame(dayjs(), 'week') && (date.day() !== 0 || dayjs().day() === 0)) {
|
||||
const daysOfWeek = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
||||
return `${daysOfWeek[date.day()]} ${date.format('HH:mm')}`;
|
||||
const daysOfWeek = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
||||
return `${daysOfWeek[date.day()]} ${date.format('HH:mm')}`
|
||||
}
|
||||
return date.format('YYYY年M月D日 HH:mm');
|
||||
};
|
||||
return date.format('YYYY年M月D日 HH:mm')
|
||||
}
|
||||
|
||||
export const getAvatarUrl = (url: string) => {
|
||||
if (url && url.includes('http')) {
|
||||
return url;
|
||||
return url
|
||||
}
|
||||
return defaultAvatar;
|
||||
};
|
||||
return defaultAvatar
|
||||
}
|
||||
|
||||
/**
|
||||
* URL 参数解析工具函数
|
||||
*/
|
||||
// 手动解析 URL 参数 (兼容性更好)
|
||||
export const parseUrlParams = (url?: string): Record<string, string> => {
|
||||
const targetUrl = url || (typeof location !== 'undefined' ? location.href : '')
|
||||
const params: Record<string, string> = {}
|
||||
|
||||
if (!targetUrl) return params
|
||||
|
||||
try {
|
||||
// 获取查询字符串部分
|
||||
const queryString = targetUrl.split('?')[1]
|
||||
if (!queryString) return params
|
||||
|
||||
// 分割参数
|
||||
const pairs = queryString.split('&')
|
||||
pairs.forEach(pair => {
|
||||
const [key, value] = pair.split('=')
|
||||
if (key) {
|
||||
params[decodeURIComponent(key)] = decodeURIComponent(value || '')
|
||||
}
|
||||
})
|
||||
|
||||
return params
|
||||
} catch (error) {
|
||||
console.warn('URL 参数解析失败:', error)
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
@ -29,14 +29,18 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
server: {
|
||||
port: 5173,
|
||||
port: 1234,
|
||||
open: true,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:9053',
|
||||
// target: 'https://test.pi.xuexiaole.com',
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
// server: {
|
||||
// port: 5173,
|
||||
// open: true,
|
||||
// proxy: {
|
||||
// '/api': {
|
||||
// target: 'http://127.0.0.1:9053',
|
||||
// // target: 'https://test.pi.xuexiaole.com',
|
||||
// changeOrigin: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user