fix(mobile): 修复移动端API对接 - 使用现有护士站接口+登录获取用户信息
This commit is contained in:
@@ -19,6 +19,7 @@ service.interceptors.response.use(
|
||||
const res = response.data
|
||||
if (res.code === 401) {
|
||||
localStorage.removeItem('Admin-Token')
|
||||
localStorage.removeItem('userInfo')
|
||||
window.location.href = '/login'
|
||||
return Promise.reject(new Error('登录已过期'))
|
||||
}
|
||||
@@ -27,28 +28,29 @@ service.interceptors.response.use(
|
||||
error => {
|
||||
if (error.response?.status === 401) {
|
||||
localStorage.removeItem('Admin-Token')
|
||||
localStorage.removeItem('userInfo')
|
||||
window.location.href = '/login'
|
||||
}
|
||||
ElMessage.error(error.response?.data?.msg || '请求失败')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export const authApi = {
|
||||
login: (data) => service.post('/login', data, { headers: { isToken: false } }),
|
||||
getTenants: (username) => service.get('/system/tenant/user-bind/' + username, { headers: { isToken: false } })
|
||||
getTenants: (username) => service.get('/system/tenant/user-bind/' + username, { headers: { isToken: false } }),
|
||||
getInfo: () => service.get('/getInfo')
|
||||
}
|
||||
|
||||
export const nursingApi = {
|
||||
getTasks: (params) => service.get('/mp/nursing/tasks', { params }),
|
||||
completeTask: (id, data) => service.post(`/mp/nursing/tasks/${id}/complete`, data),
|
||||
getPatientInfo: (id) => service.get(`/mp/nursing/patient/${id}`),
|
||||
getPatientList: (params) => service.get('/mp/nursing/patient/list', { params }),
|
||||
getOrders: (patientId) => service.get(`/mp/nursing/orders/${patientId}`),
|
||||
getVitalSigns: (patientId) => service.get(`/mp/nursing/vital-signs/${patientId}`),
|
||||
submitVitalSign: (data) => service.post('/mp/nursing/vital-sign', data),
|
||||
getAssessments: (patientId) => service.get(`/mp/nursing/assessments/${patientId}`),
|
||||
submitAssessment: (data) => service.post('/mp/nursing/assessment', data)
|
||||
getTasks: (params) => service.get('/nurse-station/advice-process/page', { params }),
|
||||
completeTask: (id, data) => service.post(`/nurse-station/advice-process/execute`, data),
|
||||
getPatientInfo: (id) => service.get('/inpatientmanage/inhospitalregister/' + id),
|
||||
getPatientList: (params) => service.get('/inpatientmanage/inhospitalregister/list', { params }),
|
||||
getOrders: (encounterId) => service.get('/nurse-station/advice-process/page', { params: { encounterId } }),
|
||||
getVitalSigns: (patientId) => service.get('/nursing/vital-signs/' + patientId),
|
||||
submitVitalSign: (data) => service.post('/nursing/vital-sign', data),
|
||||
getAssessments: (encounterId) => service.get('/nursing/assessment/encounter/' + encounterId),
|
||||
submitAssessment: (data) => service.post('/nursing/assessment', data)
|
||||
}
|
||||
|
||||
export default service
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="welcome">
|
||||
<div class="user-info">
|
||||
<div class="avatar">{{ userInfo?.userName?.charAt(0) || '护' }}</div>
|
||||
<div><div class="name">{{ userInfo?.userName || '护士' }}</div><div class="dept">{{ userInfo?.deptName || '护理部' }}</div></div>
|
||||
<div><div class="name">{{ userInfo?.nickName || userInfo?.userName || '护士' }}</div><div class="dept">{{ userInfo?.orgName || '' }}</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats-grid">
|
||||
@@ -24,8 +24,8 @@
|
||||
<div class="recent-tasks">
|
||||
<div class="section-header"><span>待办任务</span><span class="more" @click="$router.push('/mobile/tasks')">查看全部</span></div>
|
||||
<div v-for="task in recentTasks" :key="task.id" class="task-item">
|
||||
<div class="task-dot" :class="task.taskStatus"></div>
|
||||
<div class="task-info"><div class="task-name">{{ task.patientName }} - {{ task.taskContent }}</div><div class="task-time">{{ task.dueTime }}</div></div>
|
||||
<div class="task-dot"></div>
|
||||
<div class="task-info"><div class="task-name">{{ task.adviceName || task.taskContent || '医嘱任务' }}</div><div class="task-time">{{ task.createTime || '' }}</div></div>
|
||||
</div>
|
||||
<div v-if="recentTasks.length === 0" class="empty">暂无待办任务</div>
|
||||
</div>
|
||||
@@ -37,7 +37,7 @@ import { ref, onMounted } from 'vue'
|
||||
import { nursingApi } from '../api'
|
||||
|
||||
const userInfo = ref({})
|
||||
const stats = ref([{ label: '待执行医嘱', value: 0 }, { label: '待测体征', value: 0 }, { label: '待评估', value: 0 }, { label: '高风险患者', value: 0 }])
|
||||
const stats = ref([{ label: '待执行医嘱', value: 0 }, { label: '今日体征', value: 0 }, { label: '待评估', value: 0 }, { label: '高风险', value: 0 }])
|
||||
const recentTasks = ref([])
|
||||
const actions = [
|
||||
{ icon: '📋', label: '任务列表', path: '/mobile/tasks', color: '#1890ff' },
|
||||
@@ -51,10 +51,13 @@ const actions = [
|
||||
onMounted(async () => {
|
||||
try { const info = localStorage.getItem('userInfo'); if (info) userInfo.value = JSON.parse(info) } catch {}
|
||||
try {
|
||||
const res = await nursingApi.getTasks({ status: 'PENDING' })
|
||||
if (res.code === 200) {
|
||||
recentTasks.value = (res.data?.tasks || []).slice(0, 5)
|
||||
stats.value[0].value = res.data?.summary?.pending || 0
|
||||
const nurseId = userInfo.value.practitionerId || userInfo.value.userId
|
||||
if (nurseId) {
|
||||
const res = await nursingApi.getTasks({ nurseId: nurseId })
|
||||
if (res.code === 200) {
|
||||
recentTasks.value = (res.data?.records || res.data?.rows || res.data || []).slice(0, 5)
|
||||
stats.value[0].value = res.data?.total || recentTasks.value.length
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
})
|
||||
@@ -82,7 +85,6 @@ onMounted(async () => {
|
||||
.more { color: #1890ff; font-size: 13px; }
|
||||
.task-item { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid #f5f5f5; }
|
||||
.task-dot { width: 8px; height: 8px; border-radius: 50%; background: #fa8c16; }
|
||||
.task-dot.COMPLETED { background: #52c41a; }
|
||||
.task-name { font-size: 14px; }
|
||||
.task-time { font-size: 12px; color: #999; }
|
||||
.empty { text-align: center; padding: 20px; color: #999; }
|
||||
|
||||
@@ -61,10 +61,33 @@ const handleLogin = async () => {
|
||||
if (!form.value.password) { errorMsg.value = '请输入密码'; return }
|
||||
loading.value = true; errorMsg.value = ''
|
||||
try {
|
||||
const res = await authApi.login({ username: form.value.username, password: form.value.password, tenantId: form.value.tenantId, code: '', uuid: '' })
|
||||
if (res.code === 200 && res.token) { localStorage.setItem('Admin-Token', res.token); ElMessage.success('登录成功'); router.push('/mobile/home') }
|
||||
else { errorMsg.value = res.msg || '登录失败' }
|
||||
} catch (e) { errorMsg.value = e.response?.data?.msg || '登录失败' } finally { loading.value = false }
|
||||
const loginRes = await authApi.login({ username: form.value.username, password: form.value.password, tenantId: form.value.tenantId, code: '', uuid: '' })
|
||||
if (loginRes.code === 200 && loginRes.token) {
|
||||
localStorage.setItem('Admin-Token', loginRes.token)
|
||||
const infoRes = await authApi.getInfo()
|
||||
if (infoRes.code === 200) {
|
||||
const user = infoRes.user || {}
|
||||
localStorage.setItem('userInfo', JSON.stringify({
|
||||
userId: user.userId,
|
||||
userName: user.userName,
|
||||
nickName: user.nickName,
|
||||
practitionerId: user.practitionerId,
|
||||
orgId: user.orgId,
|
||||
orgName: user.orgName,
|
||||
roles: user.roles,
|
||||
permissions: user.permissions
|
||||
}))
|
||||
}
|
||||
ElMessage.success('登录成功')
|
||||
router.push('/mobile/home')
|
||||
} else {
|
||||
errorMsg.value = loginRes.msg || '登录失败'
|
||||
}
|
||||
} catch (e) {
|
||||
errorMsg.value = e.response?.data?.msg || '登录失败,请检查网络'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
<template>
|
||||
<div class="task-list">
|
||||
<div class="filter-bar">
|
||||
<select v-model="filterType" class="filter-select" @change="loadTasks"><option value="">全部</option><option value="医嘱执行">医嘱执行</option><option value="生命体征">生命体征</option><option value="护理评估">护理评估</option></select>
|
||||
<select v-model="filterType" class="filter-select" @change="loadTasks"><option value="">全部</option><option value="医嘱执行">医嘱执行</option><option value="生命体征">生命体征</option></select>
|
||||
<button class="refresh-btn" @click="loadTasks">刷新</button>
|
||||
</div>
|
||||
<div v-if="loading" class="loading">加载中...</div>
|
||||
<div v-for="task in filteredTasks" :key="task.id" class="task-card" @touchstart="swipeStart" @touchend="swipeEnd($event, task)">
|
||||
<div class="task-info">
|
||||
<div class="task-header"><span class="task-patient">{{ task.patientName }}</span><span class="bed">{{ task.bedNo }}床</span></div>
|
||||
<div class="task-content">{{ task.taskContent }}</div>
|
||||
<div class="task-meta"><span class="task-type">{{ task.taskType }}</span><span class="task-time">{{ task.dueTime }}</span></div>
|
||||
<div class="task-header"><span class="task-patient">{{ task.patientName || '患者' }}</span><span class="bed">{{ task.bedNo || '' }}</span></div>
|
||||
<div class="task-content">{{ task.adviceName || task.orderName || '医嘱任务' }}</div>
|
||||
<div class="task-meta"><span class="task-type">{{ task.adviceType || task.orderType || '医嘱' }}</span><span class="task-time">{{ task.createTime || '' }}</span></div>
|
||||
</div>
|
||||
<div class="task-status" :class="task.taskStatus">{{ statusText(task.taskStatus) }}</div>
|
||||
</div>
|
||||
<div v-if="!loading && filteredTasks.length === 0" class="empty">暂无任务</div>
|
||||
</div>
|
||||
@@ -25,23 +24,29 @@ import { nursingApi } from '../api'
|
||||
const tasks = ref([])
|
||||
const loading = ref(false)
|
||||
const filterType = ref('')
|
||||
const filteredTasks = computed(() => filterType.value ? tasks.value.filter(t => t.taskType === filterType.value) : tasks.value)
|
||||
const statusText = (s) => ({ PENDING: '待完成', IN_PROGRESS: '进行中', COMPLETED: '已完成' }[s] || s)
|
||||
const filteredTasks = computed(() => filterType.value ? tasks.value.filter(t => (t.adviceType || '').includes(filterType.value)) : tasks.value)
|
||||
|
||||
const loadTasks = async () => {
|
||||
loading.value = true
|
||||
try { const res = await nursingApi.getTasks({ status: 'PENDING' }); tasks.value = res.data?.tasks || [] } catch (e) { ElMessage.error('加载失败') } finally { loading.value = false }
|
||||
try {
|
||||
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
|
||||
const nurseId = userInfo.practitionerId || userInfo.userId
|
||||
if (!nurseId) { ElMessage.warning('未获取到用户信息'); return }
|
||||
const res = await nursingApi.getTasks({ nurseId: nurseId, pageNum: 1, pageSize: 50 })
|
||||
if (res.code === 200) { tasks.value = res.data?.records || res.data?.rows || [] }
|
||||
} catch (e) { ElMessage.error('加载失败') } finally { loading.value = false }
|
||||
}
|
||||
|
||||
let startX = 0
|
||||
const swipeStart = (e) => { startX = e.touches[0].clientX }
|
||||
const swipeEnd = async (e, task) => {
|
||||
const diff = startX - e.changedTouches[0].clientX
|
||||
if (diff > 80 && task.taskStatus === 'PENDING') {
|
||||
if (diff > 80) {
|
||||
try {
|
||||
await ElMessageBox.confirm('确认完成此任务?', '提示')
|
||||
await nursingApi.completeTask(task.id, { result: '完成' })
|
||||
task.taskStatus = 'COMPLETED'; ElMessage.success('任务已完成')
|
||||
ElMessage.success('任务已完成')
|
||||
loadTasks()
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
@@ -61,8 +66,5 @@ onMounted(loadTasks)
|
||||
.task-content { color: #666; font-size: 13px; margin: 4px 0; }
|
||||
.task-meta { display: flex; gap: 12px; font-size: 12px; color: #999; }
|
||||
.task-type { background: #e6f7ff; color: #1890ff; padding: 2px 8px; border-radius: 4px; }
|
||||
.task-status { font-size: 12px; padding: 4px 10px; border-radius: 12px; white-space: nowrap; }
|
||||
.task-status.PENDING { background: #fff7e6; color: #fa8c16; }
|
||||
.task-status.COMPLETED { background: #f6ffed; color: #52c41a; }
|
||||
.empty { text-align: center; padding: 40px; color: #999; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user