initStore
|
|
@ -0,0 +1 @@
|
|||
VITE_BASE_URL = '/AppPeaManager'
|
||||
|
|
@ -0,0 +1 @@
|
|||
VITE_BASE_URL = '/AppPeaManager'
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Vue 3 + TypeScript + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||
|
||||
## Type Support For `.vue` Imports in TS
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
||||
|
||||
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
||||
|
||||
1. Disable the built-in TypeScript Extension
|
||||
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
||||
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
||||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
import '@vue/runtime-core'
|
||||
|
||||
export {}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents {
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
TabBar: typeof import('./src/components/TabBar.vue')['default']
|
||||
VanButton: typeof import('vant/es')['Button']
|
||||
VanCascader: typeof import('vant/es')['Cascader']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
VanForm: typeof import('vant/es')['Form']
|
||||
VanIcon: typeof import('vant/es')['Icon']
|
||||
VanNavBar: typeof import('vant/es')['NavBar']
|
||||
VanPicker: typeof import('vant/es')['Picker']
|
||||
VanPopup: typeof import('vant/es')['Popup']
|
||||
VanSwipe: typeof import('vant/es')['Swipe']
|
||||
VanSwipeCell: typeof import('vant/es')['SwipeCell']
|
||||
VanSwipeItem: typeof import('vant/es')['SwipeItem']
|
||||
VanTabbar: typeof import('vant/es')['Tabbar']
|
||||
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
||||
VanUploader: typeof import('vant/es')['Uploader']
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
||||
<title>云送体检预约</title>
|
||||
<style>
|
||||
/* vant组件库样式 */
|
||||
.van-uploader__upload{
|
||||
border-radius: 50%;
|
||||
}
|
||||
.van-uploader__preview-image{
|
||||
border-radius: 50%;
|
||||
}
|
||||
.van-nav-bar__content{
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.van-hairline--bottom:after{
|
||||
border-bottom-width: 0 !important;
|
||||
}
|
||||
.van-field{
|
||||
border-radius: 0.8rem;
|
||||
height: 1.6rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
/* .calendar_item_disable{
|
||||
background-color: #c0c4cc !important;
|
||||
} */
|
||||
.van-cell__title{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.van-toast{
|
||||
background: rgba(0, 0, 0, 0.7) !important;
|
||||
}
|
||||
.van-field__error-message{
|
||||
font-size: 16px !important;
|
||||
}
|
||||
.van-cascader__options{
|
||||
height: auto !important;
|
||||
}
|
||||
.van-swipe-cell__right{
|
||||
right: 1px !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="background-color: #f8f8f8;">
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "y",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --open"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
"lib-flexible": "^0.3.2",
|
||||
"pinia": "^2.1.3",
|
||||
"pinia-plugin-persistedstate": "^3.1.0",
|
||||
"postcss-pxtorem": "^6.0.0",
|
||||
"qs": "^6.11.2",
|
||||
"sass": "^1.62.1",
|
||||
"scss": "^0.2.4",
|
||||
"vant": "^4.4.1",
|
||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||
"vue": "^3.2.47",
|
||||
"vue-router": "^4.2.2",
|
||||
"vue-template-compiler": "^2.7.14",
|
||||
"vue3-hash-calendar": "^1.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.2.5",
|
||||
"@vitejs/plugin-vue": "^4.1.0",
|
||||
"typescript": "^5.0.2",
|
||||
"unplugin-vue-components": "^0.25.0",
|
||||
"vite": "^4.3.9",
|
||||
"vue-tsc": "^1.4.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
import { RouterView } from 'vue-router'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RouterView />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import axios from "../utils/request";
|
||||
|
||||
//登录接口
|
||||
const login = (params = {}) => {
|
||||
return axios.post('/login', params)
|
||||
}
|
||||
|
||||
export {
|
||||
login
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import axios from '../utils/request'
|
||||
|
||||
// 获取医院信息
|
||||
const getHospitalInfo = (params = {}) => {
|
||||
return axios.post('/app/gethospital', params)
|
||||
}
|
||||
|
||||
// 获取套餐详情
|
||||
const getPackageDetail = (params = {}) => {
|
||||
return axios.post('/app/getexamination', params)
|
||||
}
|
||||
|
||||
// 提交体检信息表单
|
||||
const submitForm = (params = {}) => {
|
||||
return axios.post('/app/phyappoint', params)
|
||||
}
|
||||
|
||||
// 获取职工套餐
|
||||
const getCrewPackage = (params = {}) => {
|
||||
return axios.post('/app/getworkexamination', params)
|
||||
}
|
||||
|
||||
export {
|
||||
getHospitalInfo,
|
||||
getPackageDetail,
|
||||
submitForm,
|
||||
getCrewPackage
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import axios from "../utils/request";
|
||||
|
||||
// 获取医院信息接口
|
||||
const getActualHospital = (params = {}) => {
|
||||
return axios.post('/app/gethospital', params)
|
||||
}
|
||||
|
||||
// 获取套餐详情
|
||||
const getPackageDetail = (params = {}) => {
|
||||
return axios.post('/app/getexamination', params)
|
||||
}
|
||||
|
||||
// 提交体检预约表单
|
||||
const submitForm = (params = {}) => {
|
||||
return axios.post('/app/phyappoint', params)
|
||||
}
|
||||
|
||||
export {
|
||||
getActualHospital,
|
||||
getPackageDetail,
|
||||
submitForm
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import axios from '../utils/request'
|
||||
|
||||
// 发送验证码
|
||||
const sendVeriCode = (params = {}) => {
|
||||
return axios.post('/app/getUserByPhone', params)
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
const editNewPwd = (params = {}) => {
|
||||
return axios.post('/app/resetUserPwd', params)
|
||||
}
|
||||
|
||||
export {
|
||||
sendVeriCode,
|
||||
editNewPwd
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import axios from "../utils/request";
|
||||
|
||||
// 获取用户身份状态
|
||||
const getUserStatus = (params = {}) => {
|
||||
return axios.post('/app/getStatus', params)
|
||||
}
|
||||
|
||||
// 获取信息
|
||||
const fetchMsgs = (params = {}) => {
|
||||
return axios.post('/app/phyappoint', params)
|
||||
}
|
||||
|
||||
// 获取是否预约过的状态
|
||||
const isPreOrdered = (params = {}) => {
|
||||
return axios.post('/app/getphyappoint', params)
|
||||
}
|
||||
|
||||
export {
|
||||
getUserStatus,
|
||||
fetchMsgs,
|
||||
isPreOrdered
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import axios from "../utils/request";
|
||||
|
||||
// 发送手机验证码
|
||||
const sendPhoneVeri = (params = {}) => {
|
||||
return axios.post('/app/getUserByPhone', params)
|
||||
}
|
||||
|
||||
// 短信验证表单提交
|
||||
const logWithMsg = (params = {}) => {
|
||||
return axios.post('/app/loginNoPassword', params)
|
||||
}
|
||||
|
||||
export {
|
||||
sendPhoneVeri,
|
||||
logWithMsg
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import axios from "../utils/request";
|
||||
|
||||
// 获取体检单信息
|
||||
const getPreOrderInfo = (params = {}) => {
|
||||
return axios.post('/app/getpersonappointInfo', params)
|
||||
}
|
||||
|
||||
// 取消预约接口
|
||||
const cancelPort = (params = {}) => {
|
||||
return axios.post('/app/cancelpoint', params)
|
||||
}
|
||||
|
||||
export {
|
||||
getPreOrderInfo,
|
||||
cancelPort
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import axios from '../utils/request'
|
||||
|
||||
const seePackage = (params = {}) => {
|
||||
return axios.post('/app/getcontentByid', params)
|
||||
}
|
||||
|
||||
export {
|
||||
seePackage
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import axios from "../utils/request";
|
||||
|
||||
// 获取用户信息
|
||||
const getUserInfo = (params = {}) => {
|
||||
return axios.post('/app/getapplogininfo', params)
|
||||
}
|
||||
|
||||
export {
|
||||
getUserInfo
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/* color palette from <https://github.com/vuejs/theme> */
|
||||
:root {
|
||||
--vt-c-white: #ffffff;
|
||||
--vt-c-white-soft: #f8f8f8;
|
||||
--vt-c-white-mute: #f2f2f2;
|
||||
|
||||
--vt-c-black: #181818;
|
||||
--vt-c-black-soft: #222222;
|
||||
--vt-c-black-mute: #282828;
|
||||
|
||||
--vt-c-indigo: #2c3e50;
|
||||
|
||||
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
|
||||
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
|
||||
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
|
||||
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
|
||||
|
||||
--vt-c-text-light-1: var(--vt-c-indigo);
|
||||
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
|
||||
--vt-c-text-dark-1: var(--vt-c-white);
|
||||
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
|
||||
}
|
||||
|
||||
/* semantic color variables for this project */
|
||||
:root {
|
||||
--color-background: var(--vt-c-white);
|
||||
--color-background-soft: var(--vt-c-white-soft);
|
||||
--color-background-mute: var(--vt-c-white-mute);
|
||||
|
||||
--color-border: var(--vt-c-divider-light-2);
|
||||
--color-border-hover: var(--vt-c-divider-light-1);
|
||||
|
||||
--color-heading: var(--vt-c-text-light-1);
|
||||
--color-text: var(--vt-c-text-light-1);
|
||||
|
||||
--section-gap: 160px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-background: var(--vt-c-black);
|
||||
--color-background-soft: var(--vt-c-black-soft);
|
||||
--color-background-mute: var(--vt-c-black-mute);
|
||||
|
||||
--color-border: var(--vt-c-divider-dark-2);
|
||||
--color-border-hover: var(--vt-c-divider-dark-1);
|
||||
|
||||
--color-heading: var(--vt-c-text-dark-1);
|
||||
--color-text: var(--vt-c-text-dark-2);
|
||||
}
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
color: var(--color-text);
|
||||
background: var(--color-background);
|
||||
transition: color 0.5s, background-color 0.5s;
|
||||
line-height: 1.6;
|
||||
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
|
||||
Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
||||
font-size: 15px;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
* {
|
||||
/**
|
||||
* 简单粗暴, 一劳永逸的写法
|
||||
*/
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
* {
|
||||
/*
|
||||
* 这个属性只用于iOS, 当你点击一个链接或者通过Javascript定义的可点击元素的时候
|
||||
* 它就会出现一个半透明的灰色背景
|
||||
*/
|
||||
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||
}
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%; /* 禁止字体变化 */
|
||||
}
|
||||
body {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
font-family: Helvetica,Arial,sans-serif;
|
||||
line-height: 1;
|
||||
-webkit-overflow-scrolling: touch; /* 设置滚动容器的滚动效果 */
|
||||
-webkit-font-smoothing: antialiased; /* 字体抗锯齿渲染 */
|
||||
}
|
||||
a, a:active, a:hover {
|
||||
/**
|
||||
* 某些浏览器会给 a 设置默认颜色
|
||||
*/
|
||||
color: unset;
|
||||
text-decoration: none;
|
||||
}
|
||||
ol, ul, li {
|
||||
/**
|
||||
* 去掉列表样式
|
||||
*/
|
||||
list-style: none;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
vertical-align: middle
|
||||
}
|
||||
table {
|
||||
/**
|
||||
* 去掉 td 与 td 之间的空隙
|
||||
*/
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
input, textarea, select {
|
||||
outline: none; /*去掉fouce时边框高亮效果*/
|
||||
background: unset; /*去掉默认背景*/
|
||||
appearance: none;
|
||||
-webkit-appearance: none; /* 去除ios输入框阴影 */
|
||||
}
|
||||
/* 禁止选中文本内容 */
|
||||
*:not(input, select, textArea) {
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 496 B |
|
|
@ -0,0 +1,16 @@
|
|||
<template>
|
||||
<div>
|
||||
<van-tabbar style="width: 100%;" route active-color="#24acf2">
|
||||
<van-tabbar-item icon="wap-home-o" to="/home">首页</van-tabbar-item>
|
||||
<van-tabbar-item icon="user-o" to="/user">个人</van-tabbar-item>
|
||||
</van-tabbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import router from './router'
|
||||
import 'lib-flexible'
|
||||
import './assets/base.css'
|
||||
import 'vant/lib/index.css'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
import VueHashCalendar from 'vue3-hash-calendar'
|
||||
import 'vue3-hash-calendar/es/index.css'
|
||||
import {
|
||||
Tabbar,
|
||||
TabbarItem,
|
||||
Swipe,
|
||||
SwipeItem,
|
||||
NavBar,
|
||||
Form,
|
||||
Field,
|
||||
Cell,
|
||||
CellGroup,
|
||||
Popup,
|
||||
Picker,
|
||||
Calendar,
|
||||
Button,
|
||||
Toast,
|
||||
Uploader,
|
||||
Icon,
|
||||
Cascader,
|
||||
SwipeCell,
|
||||
Badge,
|
||||
NoticeBar,
|
||||
Collapse,
|
||||
CollapseItem
|
||||
} from 'vant'
|
||||
|
||||
const app = createApp(App)
|
||||
const pinia = createPinia()
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
|
||||
app.use(router)
|
||||
.use(pinia)
|
||||
.use(Tabbar)
|
||||
.use(TabbarItem)
|
||||
.use(Swipe)
|
||||
.use(SwipeItem)
|
||||
.use(NavBar)
|
||||
.use(Form)
|
||||
.use(Field)
|
||||
.use(Cell)
|
||||
.use(CellGroup)
|
||||
.use(Popup)
|
||||
.use(Picker)
|
||||
.use(Calendar)
|
||||
.use(Button)
|
||||
.use(Toast)
|
||||
.use(Uploader)
|
||||
.use(Icon)
|
||||
.use(VueHashCalendar)
|
||||
.use(Cascader)
|
||||
.use(SwipeCell)
|
||||
.use(Badge)
|
||||
.use(NoticeBar)
|
||||
.use(Collapse)
|
||||
.use(CollapseItem)
|
||||
|
||||
app.mount('#app')
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
|
||||
import Home from '../views/Home/Home.vue'
|
||||
import { isLogin } from '../utils/index'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/home'
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
name: 'user',
|
||||
component: () => import('../views/User/User.vue')
|
||||
},
|
||||
{
|
||||
path: '/examPreOrder',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
name: 'examPreOrder',
|
||||
component: () => import('../views/ExamPreOrder/ExamPreOrder.vue')
|
||||
},
|
||||
{
|
||||
path: '/examReport',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
name: 'examReport',
|
||||
component: () => import('../views/ExamReport/ExamReport.vue')
|
||||
},
|
||||
{
|
||||
path: '/myPreOrder',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
name: 'myPreOrder',
|
||||
component: () => import('../views/MyPreOrder/MyPreOrder.vue')
|
||||
},
|
||||
{
|
||||
path: '/careerExam',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
name: 'careerExam',
|
||||
component: () => import('../views/CareerExam/CareerExam.vue')
|
||||
},
|
||||
{
|
||||
path: '/preOrderSucceed',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
name: 'preOrderSucceed',
|
||||
component: () => import('../views/PreOrderSucceed/PreOrderSucceed.vue')
|
||||
},
|
||||
{
|
||||
path: '/personalInfo',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
name: 'personalInfo',
|
||||
component: () => import('../views/PersonalInfo/PersonalInfo.vue')
|
||||
},
|
||||
{
|
||||
path: '/msgNotice',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
name: 'msgNotice',
|
||||
component: () => import('../views/MsgNotice/MsgNotice.vue')
|
||||
},
|
||||
{
|
||||
path: '/accountLogin',
|
||||
name: 'accountLogin',
|
||||
component: () => import('../views/AccountLogin/AccountLogin.vue')
|
||||
},
|
||||
{
|
||||
path: '/forgetPassword',
|
||||
name: 'forgetPassword',
|
||||
component: () => import('../views/ForgetPassword/ForgetPassword.vue')
|
||||
},
|
||||
{
|
||||
path: '/msgLogin',
|
||||
name: 'msgLogin',
|
||||
component: () => import('../views/MsgLogin/MsgLogin.vue')
|
||||
},
|
||||
{
|
||||
path: '/preOrderReceipt',
|
||||
meta: {
|
||||
needAuth: true
|
||||
},
|
||||
name: 'preOrderReceipt',
|
||||
component: () => import('../views/PreOrderReceipt/PreOrderReceipt.vue')
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
/*
|
||||
路由前置守卫
|
||||
对于路由静态信息中设置needAuth的路由加以鉴权
|
||||
访问没有携带token的页面需要跳转到账号登录页面
|
||||
*/
|
||||
router.beforeEach((to: any) => {
|
||||
if (to.meta.needAuth) {
|
||||
if (!isLogin()) {
|
||||
return {
|
||||
path: '/accountLogin'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
||||
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 370 KiB |
|
After Width: | Height: | Size: 348 KiB |
|
After Width: | Height: | Size: 280 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 685 B |
|
|
@ -0,0 +1,38 @@
|
|||
import { defineStore } from 'pinia'
|
||||
import { getUserInfo } from '../api/user'
|
||||
|
||||
const userInformation = defineStore('user', {
|
||||
state: () => {
|
||||
return {
|
||||
phyName: '',
|
||||
idcard: '',
|
||||
age: '',
|
||||
sex: '',
|
||||
telepNumber: '',
|
||||
departName: ''
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
// 将请求过来的个人信息赋值
|
||||
initInfo (info: any) {
|
||||
this.phyName = info.phyName
|
||||
this.idcard = info.idcard
|
||||
this.age = info.age
|
||||
this.sex = info.sex
|
||||
this.telepNumber = info.telepNumber
|
||||
this.departName = info.departName
|
||||
},
|
||||
// 请求个人信息
|
||||
fetchUserInfo () {
|
||||
getUserInfo({
|
||||
token: localStorage.getItem('token')
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
this.initInfo(res.data.obj[0])
|
||||
})
|
||||
}
|
||||
},
|
||||
persist: true
|
||||
})
|
||||
|
||||
export default userInformation
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
const isLogin = () => !!localStorage.getItem('token')
|
||||
const getToken = () => localStorage.getItem('token')
|
||||
|
||||
export {
|
||||
isLogin,
|
||||
getToken
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import axios from 'axios'
|
||||
import qs from 'qs'
|
||||
// import router from '../router'
|
||||
|
||||
axios.defaults.baseURL = import.meta.env.VITE_BASE_URL;
|
||||
axios.defaults.timeout = 8000;
|
||||
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
axios.interceptors.request.use(function (config) {
|
||||
if(config.method === 'post' && config.data) {
|
||||
config.data = qs.stringify(config.data)
|
||||
}
|
||||
return config;
|
||||
}, function (error) {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
axios.interceptors.response.use(function (response) {
|
||||
return response;
|
||||
}, function (error) {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
export default axios
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="background">
|
||||
<div class="block_3 flex-col">
|
||||
<div class="section_1 flex-col"></div>
|
||||
<div class="section_2 flex-col"></div>
|
||||
<div class="section_3 flex-col"></div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="log-tit">云送体检预约</h2>
|
||||
<van-form @submit="logSub" class="log-form">
|
||||
<van-field
|
||||
v-model="username"
|
||||
name="account"
|
||||
:placeholder="accountPlaceHolder"
|
||||
@focus="focusAccount"
|
||||
@blur="blurAccount"
|
||||
:rules="[{ required: true, message: '请填写账号!' }]"
|
||||
autocomplete="off"
|
||||
clearable
|
||||
style="border: 1px solid #62b0b0; background-color: #f3f9f9; font-size: 16px; box-sizing: border-box;"
|
||||
/>
|
||||
<van-field
|
||||
v-model="password"
|
||||
name="password"
|
||||
:type="pwdType"
|
||||
:placeholder="pwdPlaceHolder"
|
||||
@focus="focusPwd"
|
||||
@blur="blurPwd"
|
||||
:rules="[{ required: true, message: '请填写密码!' }]"
|
||||
autocomplete="off"
|
||||
clearable
|
||||
style="margin-top: 0.5rem; border: 1px solid #62b0b0; background-color: #f3f9f9; font-size: 16px;"
|
||||
>
|
||||
<template #button>
|
||||
<van-button
|
||||
style="font-size: 16px; background-color: transparent; color: #1989fa; border: none;"
|
||||
size="small"
|
||||
type="primary"
|
||||
>
|
||||
<span v-if="pwdStatus === 0" @click="showPwd">查看</span>
|
||||
<span v-if="pwdStatus === 1" @click="hidePwd">隐藏</span>
|
||||
</van-button>
|
||||
</template>
|
||||
</van-field>
|
||||
<div class="user-taps">
|
||||
<span @click="jumpForget()">忘记密码</span>
|
||||
<span @click="jumpMsg()">短信安全登录</span>
|
||||
</div>
|
||||
<div class="btn-area">
|
||||
<van-button
|
||||
type="primary"
|
||||
native-type="submit"
|
||||
style="width: 70%; border-radius: 0.5rem; font-size: 18px;"
|
||||
@click="fetchLogin()"
|
||||
>
|
||||
登录
|
||||
</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useRouter } from 'vue-router'
|
||||
import { login } from '../../api/AccountLogin'
|
||||
import { showFailToast, showSuccessToast } from 'vant'
|
||||
import './scss/index.scss'
|
||||
|
||||
const username = ref<any>('')
|
||||
const password = ref<any>('')
|
||||
const router = useRouter()
|
||||
const accountPlaceHolder = ref<string>('账号')
|
||||
const pwdPlaceHolder = ref<string>('密码')
|
||||
const pwdType = ref<any>('password')
|
||||
const pwdStatus = ref<number>(0)
|
||||
|
||||
// 输入框显示密码
|
||||
const showPwd = () => {
|
||||
pwdType.value = 'input'
|
||||
pwdStatus.value = 1
|
||||
}
|
||||
|
||||
// 输入框隐藏密码
|
||||
const hidePwd = () => {
|
||||
pwdType.value = 'password'
|
||||
pwdStatus.value = 0
|
||||
}
|
||||
|
||||
// 输入框获得焦点
|
||||
const focusAccount = () => {
|
||||
accountPlaceHolder.value = ''
|
||||
}
|
||||
const focusPwd = () => {
|
||||
pwdPlaceHolder.value = ''
|
||||
}
|
||||
|
||||
// 输入框失去焦点
|
||||
const blurAccount = () => {
|
||||
accountPlaceHolder.value = '账号'
|
||||
}
|
||||
const blurPwd = () => {
|
||||
pwdPlaceHolder.value = '密码'
|
||||
}
|
||||
|
||||
// 表单提交事件
|
||||
const logSub = (val: any) => {
|
||||
console.log('submit', val)
|
||||
}
|
||||
|
||||
// 跳转到忘记密码
|
||||
const jumpForget = () => {
|
||||
router.push({
|
||||
path: '/forgetPassword'
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转到短信登录
|
||||
const jumpMsg = () => {
|
||||
router.push({
|
||||
path: '/msgLogin'
|
||||
})
|
||||
}
|
||||
|
||||
// 点击登录
|
||||
const fetchLogin = () => {
|
||||
login({
|
||||
username: username.value,
|
||||
password: password.value
|
||||
}).then((res: any) => {
|
||||
if (res.status === 200) {
|
||||
console.log(res.status)
|
||||
showSuccessToast('登录成功!')
|
||||
localStorage.setItem('token', res.data.token)
|
||||
localStorage.setItem('phoneNumber', username.value)
|
||||
localStorage.setItem('avatarUrl', 'https://img.zcool.cn/community/0104c958b69c23a801219c77ba5da2.png?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100')
|
||||
// 设置登录状态码持续时间为3h
|
||||
const overDate = new Date().getTime() - 8 * 60 * 60 * 1000 + 3 * 60 * 60 * 1000
|
||||
document.cookie = `loginStatus=0;expires=${new Date(overDate)}`
|
||||
router.replace({
|
||||
path: '/home',
|
||||
query: {
|
||||
pwd: password.value
|
||||
}
|
||||
})
|
||||
} else {
|
||||
showFailToast('用户名或密码错误!')
|
||||
}
|
||||
}).catch(() => {
|
||||
showFailToast('用户名或密码错误!')
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// fetchLogin()
|
||||
/* const ms = new Date().getTime() - 8 * 60 * 60 * 1000 + 10 * 1000
|
||||
document.cookie = `token=114514;expires=${new Date(ms)}` */
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.background {
|
||||
width: 10rem;
|
||||
height: 8rem;
|
||||
background: url('../../static/bg.jpg')
|
||||
100% no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
.section_1 {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.section_2 {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 0.1rem;
|
||||
top: 1.2rem;
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
}
|
||||
|
||||
.section_3 {
|
||||
background-color: rgba(255, 255, 255, 0.0624);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 6rem;
|
||||
top: 0.5rem;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
}
|
||||
.log-tit{
|
||||
width: 100%;
|
||||
padding-top: 4rem;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.log-form{
|
||||
width: 80%;
|
||||
height: 8rem;
|
||||
margin: 3.5rem auto;
|
||||
box-sizing: border-box;
|
||||
padding: 0.5rem;
|
||||
.user-taps{
|
||||
width: 100%;
|
||||
margin-top: 0.3rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 0 0.2rem;
|
||||
span{
|
||||
font-size: 14px;
|
||||
color: #49b3f2;
|
||||
}
|
||||
}
|
||||
.btn-area{
|
||||
width: 100%;
|
||||
margin-top: 0.6rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
:root:root{
|
||||
--van-field-placeholder-text-color: #000;
|
||||
}
|
||||
|
|
@ -0,0 +1,706 @@
|
|||
<template>
|
||||
<van-nav-bar
|
||||
title="职业健康体检预约"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
/>
|
||||
<van-form @submit="subForm" @failed="subFormFail" class="form-area">
|
||||
<div class="upper-info">
|
||||
<h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.3rem;">选择医院</h2>
|
||||
<van-field
|
||||
v-model="result1"
|
||||
is-link
|
||||
readonly
|
||||
name="hospitalId"
|
||||
placeholder="点击选择医院"
|
||||
@click="showHospitalPicker = true"
|
||||
style="margin-bottom: 0.3rem"
|
||||
autocomplete="off"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择一个医院!'
|
||||
}
|
||||
]"
|
||||
/>
|
||||
<van-popup v-model:show="showHospitalPicker" position="bottom">
|
||||
<van-picker
|
||||
:columns="hospitalColumns"
|
||||
@confirm="onHospitalConfirm"
|
||||
@cancel="showHospitalPicker = false"
|
||||
/>
|
||||
</van-popup>
|
||||
<!-- <h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.3rem;">检查类型</h2> -->
|
||||
<!-- <van-field
|
||||
v-model="result2"
|
||||
is-link
|
||||
name="checkId"
|
||||
readonly
|
||||
placeholder="点击选择套餐"
|
||||
@click="showTypePicker = true"
|
||||
style="margin-bottom: 0.3rem; border-radius: 0.1rem;"
|
||||
autocomplete="off"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择一个检查类型!'
|
||||
}
|
||||
]"
|
||||
/>
|
||||
<van-popup v-model:show="showTypePicker" position="bottom">
|
||||
<van-picker
|
||||
:columns="typeColumns"
|
||||
@confirm="onTypeConfirm"
|
||||
@cancel="showTypePicker = false"
|
||||
/>
|
||||
</van-popup> -->
|
||||
<h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.3rem; " class="personal-area">
|
||||
职工套餐
|
||||
</h2>
|
||||
<van-field
|
||||
v-model="result2"
|
||||
is-link
|
||||
readonly
|
||||
:label="personalPackageName"
|
||||
label-width="3rem"
|
||||
placeholder="请选择职工套餐"
|
||||
@click="showCrewPicker = true"
|
||||
style="margin-bottom: 0.3rem;"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择一个套餐!'
|
||||
}
|
||||
]"
|
||||
/>
|
||||
<van-popup
|
||||
v-model:show="showCrewPicker"
|
||||
position="bottom"
|
||||
>
|
||||
<!-- <van-picker
|
||||
:columns="crewColumns"
|
||||
@confirm="onCrewConfirm"
|
||||
@cancel="showCrewPicker = false"
|
||||
/> -->
|
||||
<van-cascader
|
||||
v-model="result3"
|
||||
title="请选择套餐"
|
||||
:options="crewColumns"
|
||||
@close="cascaderClose"
|
||||
@change="onChange"
|
||||
/>
|
||||
<div class="inner-content" v-if="showTotalTc">
|
||||
<div class="btn-upper" v-for="(item, index) in selectedPackage" :key="index">
|
||||
<h1 class="content-tit">
|
||||
{{ item.text }}
|
||||
<span style="display: flex; align-items: center;" v-if="pushBtn" @click="flodTc"> 展开 <van-icon name="arrow-down" size="26"/></span>
|
||||
<span style="display: flex; align-items: center;" v-if="!pushBtn" @click="blowTc"> 收起 <van-icon name="arrow-up" size="26"/></span>
|
||||
</h1>
|
||||
<div v-if="showTc">
|
||||
<h2>体检项目:
|
||||
<br>
|
||||
{{ item.combinName }}
|
||||
</h2>
|
||||
<h2>体检内容:
|
||||
<br>
|
||||
{{ item.combinContent }}
|
||||
</h2>
|
||||
<h2>体检总价:<span style="color: red;">{{ item.combinPrice }}元</span></h2>
|
||||
</div>
|
||||
<div class="cfm-btn">
|
||||
<van-button type="primary" @click="closePopup">确认套餐</van-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- <div style="text-align: center; font-size: 18px;" v-if="packageDetailStatus === 0">请选择检查类型以查看套餐</div>
|
||||
<div v-if="packageDetailStatus === 1">
|
||||
<h2 style="font-size: 20px; font-weight: bold; margin-bottom: 0.5rem;">{{ personalPackageName }}</h2>
|
||||
<div class="package-area" v-for="(item, index) in sonPackageDetails" :key="index">
|
||||
<div class="package-name">{{ item.combinName }}</div>
|
||||
<div class="package-price">{{ item.combinPrice }}元</div>
|
||||
</div>
|
||||
<div class="total-price">
|
||||
<span style="padding-right: 0.3rem;">合计</span>
|
||||
{{ totalPrice }}元
|
||||
</div>
|
||||
</div> -->
|
||||
</van-popup>
|
||||
<h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.3rem;">体检时间</h2>
|
||||
<h2 style="font-size: 14px; margin-bottom: 0.3rem; color: #9c9898">注意:一个自然周内,仅限预约一次</h2>
|
||||
<vue-hash-calendar
|
||||
@change="calendarChange"
|
||||
format="YY-MM-DD"
|
||||
:min-date="minDate"
|
||||
:max-date="new Date('2023/10/31')"
|
||||
ref="calendar"
|
||||
picker-type="date"
|
||||
:disabled-date="disabledDate"
|
||||
:disabled-week-view="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="hospital-info-area" v-for="(item, index) in selectedHospital" :key="index">
|
||||
<h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.4rem;">医院信息</h2>
|
||||
<div class="info">
|
||||
<h4 style="margin-bottom: 0.4rem; color: #2c97ef; font-size: 20px; font-weight: bold;">{{ item.text }}</h4>
|
||||
<h5>地址:{{ item.address }}</h5>
|
||||
<h5>营业时间:{{ item.businessStart }} -- {{ item.businessEnd }}</h5>
|
||||
<h5>负责人:{{ item.responsible }}</h5>
|
||||
<h5>联系方式:{{ item.telPhone }}</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<van-button
|
||||
type="primary"
|
||||
native-type="submit"
|
||||
:disabled="disBtn"
|
||||
style="width: 50%; border-radius: 0.1rem; font-size: 18px; font-weight: bold;"
|
||||
>
|
||||
确定预约
|
||||
</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { onMounted, ref, reactive } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showToast } from 'vant'
|
||||
import { getHospitalInfo, submitForm, getCrewPackage } from '../../api/CareerExam'
|
||||
|
||||
// 初始值定义
|
||||
const router = useRouter()
|
||||
const result1 = ref<any>('')
|
||||
const result2 = ref<any>('')
|
||||
const result3 = ref<any>('')
|
||||
// const date = ref<any>('')
|
||||
const showHospitalPicker = ref<boolean>(false)
|
||||
const showCrewPicker = ref<boolean>(false)
|
||||
// const showTypePicker = ref<boolean>(false)
|
||||
// const calendarShow = ref<boolean>(false)
|
||||
// 使用reactive定义响应式对象
|
||||
const selectedHospital = reactive<any>({})
|
||||
const selectedPackage = reactive<any>({})
|
||||
const hospitalName = ref<any>('')
|
||||
const examType = ref<any>('')
|
||||
const packageId = ref<any>('')
|
||||
const personalPackageName = ref<any>('')
|
||||
const mealId = ref<any>('')
|
||||
// const sonPackageDetails = ref<any[]>([])
|
||||
// const totalPrice = ref<number>(0)
|
||||
|
||||
// 套餐内容状态栏的状态
|
||||
// const packageDetailStatus = ref<number>(0)
|
||||
|
||||
// 级联选择器选项
|
||||
// const cascaderShow = ref<boolean>(false)
|
||||
|
||||
// 设置日历日期选择的范围,默认选择当天---当天+30天
|
||||
const minDate = ref<any>(new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()))
|
||||
// const maxDate = ref<any>(new Date(new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).getFullYear(), new Date(Date.now() + 30 * 24* 60 * 60 * 1000).getMonth(), new Date(Date.now() + 30 * 24* 60 * 60 * 1000).getDate()))
|
||||
|
||||
const selectedDate = ref<any>('')
|
||||
|
||||
const showTotalTc = ref<boolean>(false)
|
||||
const showTc = ref<boolean>(false)
|
||||
const pushBtn = ref<boolean>(true)
|
||||
const disBtn = ref<boolean>(false)
|
||||
const realToday = ref<any>('')
|
||||
|
||||
const flodTc = () => {
|
||||
showTc.value = true
|
||||
pushBtn.value = false
|
||||
}
|
||||
|
||||
const blowTc = () => {
|
||||
showTc.value = false
|
||||
pushBtn.value = true
|
||||
}
|
||||
|
||||
const onClickLeft = () => {
|
||||
history.back()
|
||||
}
|
||||
|
||||
// 获取今天
|
||||
const getJT = (date: any) => {
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth()+1);
|
||||
const day = date.getDate();
|
||||
const currDate = ref<any>(``)
|
||||
// 判断日期
|
||||
if (day < 10 && month < 10) {
|
||||
currDate.value = `${year}-0${month}-0${day}`;
|
||||
} else if (month >= 10 && day < 10) {
|
||||
currDate.value = `${year}-${month}-0${day}`;
|
||||
} else if (day >= 10 && month < 10) {
|
||||
currDate.value = `${year}-0${month}-${day}`;
|
||||
} else {
|
||||
currDate.value = `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
return currDate.value
|
||||
|
||||
}
|
||||
|
||||
// 获取下周第一天
|
||||
// type:日期类型,start:开始时间,end:结束时间
|
||||
// dates:日期方向,默认0:本周,-1:上周,1:下周
|
||||
const getNextWeekFirst = (type: any, dates = 0) => {
|
||||
let now = new Date();
|
||||
let nowTime = now.getTime();
|
||||
let day = now.getDay();
|
||||
let longTime = 24 * 60 * 60 * 1000;
|
||||
let n = longTime * 7 * (dates || 0);
|
||||
let dd
|
||||
if (type == "start") {
|
||||
dd = nowTime - (day - 1) * longTime + n;
|
||||
};
|
||||
if (type == "end") {
|
||||
dd = nowTime + (7 - day) * longTime + n;
|
||||
};
|
||||
let trueDD = new Date(dd);
|
||||
let y = trueDD.getFullYear();
|
||||
let m = trueDD.getMonth() + 1;
|
||||
let d = trueDD.getDate();
|
||||
let trueM = m < 10 ? "0" + m : m;
|
||||
let trueD = d < 10 ? "0" + d : d;
|
||||
let trueDay = y + "-" + trueM + "-" + trueD;
|
||||
return trueDay;
|
||||
};
|
||||
|
||||
const cascaderClose = () => {
|
||||
showCrewPicker.value = false
|
||||
result2.value = ''
|
||||
}
|
||||
|
||||
// 提交表单并跳转
|
||||
const subForm = (res: any) => {
|
||||
disBtn.value = true
|
||||
res.hospitalId = hospitalName.value
|
||||
res.setMealId = packageId.value
|
||||
res.checkId = examType.value
|
||||
res.phyAppontTime = String(selectedDate.value)
|
||||
res.setMealType = 3
|
||||
res.combName = result2.value
|
||||
console.log('提交表单', res)
|
||||
if (selectedDate.value == realToday.value) {
|
||||
showToast({
|
||||
message: '不可以预约今天!',
|
||||
icon: 'fail',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
disBtn.value = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
submitForm({
|
||||
hospitalId: res.hospitalId,
|
||||
setMealId: mealId.value,
|
||||
phyAppontTime: res.phyAppontTime,
|
||||
setMealType: res.setMealType,
|
||||
combName: res.combName,
|
||||
token: localStorage.getItem('token')
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
if (res.data.res == 0) {
|
||||
showToast({
|
||||
message: '今日可预约人数已满,请重新选择日期预约!',
|
||||
icon: 'fail',
|
||||
duration: 2500,
|
||||
onClose: () => {
|
||||
disBtn.value = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
showToast({
|
||||
message: '预约成功!',
|
||||
icon: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
router.replace({
|
||||
path: '/preOrderSucceed'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
showToast({
|
||||
message: '预约超时,请返回重新预约!',
|
||||
icon: 'fail',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
history.go(-1)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
// 提交失败
|
||||
const subFormFail = (err: any) => {
|
||||
console.log(err)
|
||||
}
|
||||
|
||||
// 定义两个下拉框的选项
|
||||
const hospitalColumns = ref<any[]>([])
|
||||
/* const typeColumns = ref<any[]>([
|
||||
{ text: '心血管', value: 1 },
|
||||
{ text: '肿瘤', value: 2 },
|
||||
{ text: '综合', value: 3 }
|
||||
]) */
|
||||
const crewColumns = ref<any[]>([])
|
||||
|
||||
// 获取医院信息
|
||||
const fetchHospitalInfo = () => {
|
||||
getHospitalInfo({
|
||||
token: localStorage.getItem('token')
|
||||
}).then((res: any) => {
|
||||
if (res.data.obj === 'isnull') {
|
||||
showToast({
|
||||
message: '请联系管理员添加医院!',
|
||||
icon: 'fail',
|
||||
duration: 1500
|
||||
})
|
||||
} else {
|
||||
const newHospitalInfo = res.data.obj.map((item: any) => {
|
||||
return {
|
||||
text: item['hospitalName'],
|
||||
value: item['id'],
|
||||
address: item['address'],
|
||||
businessStart: item['businessStart'],
|
||||
businessEnd: item['businessEnd'],
|
||||
responsible: item['responsible'],
|
||||
telPhone: item['telPhone']
|
||||
}
|
||||
})
|
||||
hospitalColumns.value = newHospitalInfo
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取职工套餐信息
|
||||
const fetchCrewPackage = () => {
|
||||
getCrewPackage({
|
||||
token: localStorage.getItem('token')
|
||||
}).then((res: any) => {
|
||||
const data = res.data.obj
|
||||
console.log(data)
|
||||
const newArr = Object.keys(data)
|
||||
const crewPackageNameArr = ref<any[]>([])
|
||||
const crewPackageIdArr = ref<any[]>([])
|
||||
const crewPackageContentArr = ref<any>('')
|
||||
const crewPackageCombinNameArr = ref<any>('')
|
||||
const crewPackagePriceArr = ref<any[]>([])
|
||||
const innerPrice = ref<number>(0)
|
||||
const totalData = ref<any[]>([])
|
||||
const nameTotal = ref<any[]>([])
|
||||
const contentTotal = ref<any[]>([])
|
||||
for (let i = 0; i < newArr.length; i++) {
|
||||
innerPrice.value = 0
|
||||
crewPackageContentArr.value = ''
|
||||
crewPackageCombinNameArr.value = ''
|
||||
for (let j = 0; j < data[i].length; j++) {
|
||||
innerPrice.value += Number(data[i][j].combinPrice)
|
||||
crewPackageContentArr.value += (data[i][j].combinContent + ' , ')
|
||||
crewPackageCombinNameArr.value += (data[i][j].combinName + ' , ')
|
||||
}
|
||||
crewPackageNameArr.value.push(data[i][i].combName)
|
||||
crewPackageIdArr.value.push(data[i][i].combId)
|
||||
crewPackagePriceArr.value.push(innerPrice.value)
|
||||
// 去除末尾逗号
|
||||
nameTotal.value.push(crewPackageCombinNameArr.value.slice(0, -2))
|
||||
contentTotal.value.push(crewPackageContentArr.value.slice(0, -2))
|
||||
}
|
||||
crewPackageNameArr.value.forEach((one: any, index: any) => {
|
||||
const item = ref<any>({})
|
||||
item.text = one
|
||||
item.value = crewPackageIdArr.value[index]
|
||||
item.combinContent = contentTotal.value[index]
|
||||
item.combinName = nameTotal.value[index]
|
||||
item.combinPrice = crewPackagePriceArr.value[index]
|
||||
totalData.value.push(item)
|
||||
const settleInfo = totalData.value.map((item: any) => {
|
||||
return {
|
||||
text: item['text'],
|
||||
value: item['value'],
|
||||
combinContent: item['combinContent'],
|
||||
combinName: item['combinName'],
|
||||
combinPrice: item['combinPrice']
|
||||
}
|
||||
})
|
||||
crewColumns.value = settleInfo
|
||||
})
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭级联框
|
||||
const closePopup = () => {
|
||||
if (result2.value === '') {
|
||||
showToast({
|
||||
message: '未选择职工套餐!',
|
||||
icon: 'fail',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
result2.value = ''
|
||||
}
|
||||
})
|
||||
} else {
|
||||
showCrewPicker.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 点击关闭两个弹出框popup,并监听选择医院的变化
|
||||
const onHospitalConfirm = (res: any) => {
|
||||
selectedHospital.value = {}
|
||||
result1.value = res.selectedOptions[0]?.text;
|
||||
showHospitalPicker.value = false;
|
||||
selectedHospital.value = res.selectedOptions[0]
|
||||
hospitalName.value = res.selectedOptions[0]?.value
|
||||
};
|
||||
|
||||
// 级联选择框确认
|
||||
const onChange = (res: any) => {
|
||||
showTotalTc.value = true
|
||||
selectedPackage.value = {}
|
||||
result2.value = res.selectedOptions[0].text
|
||||
mealId.value = res.selectedOptions[0].value
|
||||
selectedPackage.value = res.selectedOptions[0]
|
||||
};
|
||||
/* const onCrewConfirm = (res: any) => {
|
||||
console.log(res)
|
||||
result2.value = res.selectedOptions[0]?.text;
|
||||
showCrewPicker.value = false;
|
||||
}; */
|
||||
/* const onTypeConfirm = (res: any) => {
|
||||
result2.value = res.selectedOptions[0]?.text;
|
||||
examType.value = res.selectedOptions[0]?.value
|
||||
showTypePicker.value = false
|
||||
// 点击确认时发送请求,得到个性化套餐的内容渲染到dom中
|
||||
getPackageDetail({
|
||||
checkId: JSON.stringify(res.selectedOptions[0].value),
|
||||
token: localStorage.getItem('token'),
|
||||
combType: 3
|
||||
}).then((result: any) => {
|
||||
if (result.data.obj === null) {
|
||||
showToast({
|
||||
message: '体检套餐为空,请联系后台管理员发布体检套餐!',
|
||||
icon: 'warning-o'
|
||||
})
|
||||
personalPackageName.value = ''
|
||||
} else {
|
||||
console.log(result)
|
||||
personalPackageName.value = result.data.obj.tibean[0].combName
|
||||
packageId.value = result.data.obj.tibean[0].id
|
||||
sonPackageDetails.value = result.data.obj.tibeanson
|
||||
console.log(packageId.value)
|
||||
totalPrice.value = 0
|
||||
// 计算总价回显至弹出层
|
||||
for (let i = 0; i < sonPackageDetails.value.length; i++) {
|
||||
totalPrice.value += Number(sonPackageDetails.value[i].combinPrice)
|
||||
}
|
||||
packageDetailStatus.value = 1
|
||||
}
|
||||
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}; */
|
||||
|
||||
// 日历选择日期改变触发
|
||||
const calendarChange = (res: any) => {
|
||||
console.log(res, '日期改变')
|
||||
selectedDate.value = res
|
||||
}
|
||||
|
||||
// 设置日历禁用日期
|
||||
const disabledDate = (date: any) => {
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth()+1);
|
||||
const day = date.getDate();
|
||||
const currDate = ref<any>(``)
|
||||
// 判断日期
|
||||
if (day < 10 && month < 10) {
|
||||
currDate.value = `${year}-0${month}-0${day}`;
|
||||
} else if (month >= 10 && day < 10) {
|
||||
currDate.value = `${year}-${month}-0${day}`;
|
||||
} else if (day >= 10 && month < 10) {
|
||||
currDate.value = `${year}-0${month}-${day}`;
|
||||
} else {
|
||||
currDate.value = `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
// 生成禁用日期
|
||||
const disabledDateArr = [];
|
||||
|
||||
// 获取当天所处的一周
|
||||
let oneDayTime = 1000 * 60 * 60 * 24
|
||||
let today = new Date() // selectedDate.value
|
||||
// 若那一天是周末时,则强制赋值为7
|
||||
let todayDay = today.getDay() || 7
|
||||
let startDate = new Date(
|
||||
today.getTime() - oneDayTime * (todayDay - 1)
|
||||
)
|
||||
let dateList = new Array()
|
||||
|
||||
/* let dayCount = new Date().getDay()
|
||||
let todayTemp = new Date(startDate.getTime() + (dayCount - 1) * oneDayTime)
|
||||
let tempYear = todayTemp.getFullYear()
|
||||
let tempMonth = todayTemp.getMonth() + 1
|
||||
let tempDay = todayTemp.getDate()
|
||||
let trueToday = ref<any>('')
|
||||
if (tempDay < 10 && tempMonth < 10) {
|
||||
trueToday = `${tempYear}-0${tempMonth}-0${tempDay}`
|
||||
} else if (tempMonth >= 10 && tempDay < 10) {
|
||||
trueToday = `${tempYear}-${tempMonth}-0${tempDay}`
|
||||
} else if (tempDay >= 10 && tempMonth < 10) {
|
||||
trueToday = `${tempYear}-0${tempMonth}-${tempDay}`
|
||||
} else {
|
||||
trueToday = `${tempYear}-${tempMonth}-${tempDay}`
|
||||
}
|
||||
console.log(trueToday, 'sss') */
|
||||
|
||||
/* let trueToday = new Date()
|
||||
let trueTodayYear = trueToday.getFullYear()
|
||||
let trueTodayMonth = trueToday.getMonth() + 1
|
||||
let trueTodayDay = trueToday.getDate()
|
||||
let formatToady = ''
|
||||
if (trueTodayDay < 10 && trueTodayMonth < 10) {
|
||||
formatToady = `${trueTodayYear}-0${trueTodayMonth}-0${trueTodayDay}`
|
||||
} else if (trueTodayMonth >= 10 && trueTodayDay < 10) {
|
||||
formatToady = `${trueTodayYear}-${trueTodayMonth}-0${trueTodayDay}`
|
||||
} else if (trueTodayDay >= 10 && trueTodayMonth < 10) {
|
||||
formatToady = `${trueTodayYear}-0${trueTodayMonth}-${trueTodayDay}`
|
||||
} else {
|
||||
formatToady = `${trueTodayYear}-${trueTodayMonth}-${trueTodayDay}`
|
||||
} */
|
||||
|
||||
// 获取当天所处的一周
|
||||
for(let i = 0; i < 7; i++){
|
||||
let temp = new Date(startDate.getTime() + i * oneDayTime)
|
||||
let year = temp.getFullYear()
|
||||
let month = temp.getMonth() + 1
|
||||
let day = temp.getDate()
|
||||
if (day < 10 && month < 10) {
|
||||
dateList[i] = `${year}-0${month}-0${day}`
|
||||
} else if (month >= 10 && day < 10) {
|
||||
dateList[i] = `${year}-${month}-0${day}`
|
||||
} else if (day >= 10 && month < 10) {
|
||||
dateList[i] = `${year}-0${month}-${day}`
|
||||
} else {
|
||||
dateList[i] = `${year}-${month}-${day}`
|
||||
}
|
||||
disabledDateArr.push(dateList[i])
|
||||
}
|
||||
|
||||
// disabledDateArr.splice(disabledDateArr.indexOf(formatToady), 1)
|
||||
|
||||
if (disabledDateArr.includes(currDate.value)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchHospitalInfo()
|
||||
fetchCrewPackage()
|
||||
realToday.value = getJT(new Date())
|
||||
console.log(getNextWeekFirst('start', 1))
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form-area{
|
||||
width: 100%;
|
||||
margin: 0.2rem auto;
|
||||
.upper-info{
|
||||
width: 96%;
|
||||
margin: 0 auto;
|
||||
background-color: #f8f8f8;
|
||||
box-sizing: border-box;
|
||||
padding: 0.3rem;
|
||||
border-radius: 0.1rem;
|
||||
.inner-content{
|
||||
width: 100%;
|
||||
margin-top: 0.3rem;
|
||||
box-sizing: border-box;
|
||||
padding: 0.3rem;
|
||||
position: relative;
|
||||
.btn-upper{
|
||||
margin-bottom: 1.4rem;
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.content-tit{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
h1{
|
||||
font-size: 20px;
|
||||
color: #2c97ef;
|
||||
margin-bottom: 0.4rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
h2{
|
||||
margin-bottom: 0.4rem;
|
||||
line-height: 26px;
|
||||
}
|
||||
.cfm-btn{
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
left: 10px;
|
||||
bottom: 10px;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.hospital-info-area{
|
||||
width: 94%;
|
||||
margin: 0.5rem auto;
|
||||
background-color: #fff;
|
||||
border-radius: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
padding: 0.3rem;
|
||||
.info{
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0.1rem auto;
|
||||
h5{
|
||||
font-size: 16px;
|
||||
margin-bottom: 0.2rem;
|
||||
line-height: 20px;
|
||||
}
|
||||
h5:nth-child(5){
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn{
|
||||
width: 100%;
|
||||
margin: 0.5rem auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.package-area{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.package-name, .package-price{
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
}
|
||||
}
|
||||
.total-price{
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
margin-top: 1.5rem;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,731 @@
|
|||
<template>
|
||||
<van-nav-bar
|
||||
title="体检预约"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
/>
|
||||
<van-form @submit="subForm" @failed="subFormFail" class="form-area">
|
||||
<div class="upper-info">
|
||||
<h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.3rem;">选择医院</h2>
|
||||
<van-field
|
||||
v-model="result1"
|
||||
is-link
|
||||
readonly
|
||||
name="hospitalId"
|
||||
placeholder="点击选择医院"
|
||||
@click="showHospitalPicker = true"
|
||||
style="margin-bottom: 0.3rem"
|
||||
autocomplete="off"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择一个医院!'
|
||||
}
|
||||
]"
|
||||
/>
|
||||
<van-popup
|
||||
v-model:show="showHospitalPicker"
|
||||
position="bottom"
|
||||
>
|
||||
<van-picker
|
||||
:columns="hospitalColumns"
|
||||
@confirm="onHospitalConfirm"
|
||||
@cancel="showHospitalPicker = false"
|
||||
/>
|
||||
</van-popup>
|
||||
<h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.3rem;">检查类型</h2>
|
||||
<van-field
|
||||
v-model="result2"
|
||||
is-link
|
||||
readonly
|
||||
name="checkId"
|
||||
placeholder="点击选择检查类型"
|
||||
@click="showTypePicker = true"
|
||||
style="margin-bottom: 0.3rem"
|
||||
autocomplete="off"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择一个检查类型!'
|
||||
}
|
||||
]"
|
||||
/>
|
||||
<van-popup
|
||||
v-model:show="showTypePicker"
|
||||
position="bottom"
|
||||
>
|
||||
<!-- <van-picker
|
||||
:columns="typeColumns"
|
||||
@confirm="onTypeConfirm"
|
||||
@cancel="showTypePicker = false"
|
||||
ref="typePicker"
|
||||
/> -->
|
||||
<van-cascader
|
||||
v-model="result3"
|
||||
title="请选择套餐"
|
||||
:options="typeColumns"
|
||||
@close="cascaderClose"
|
||||
@change="onChange"
|
||||
/>
|
||||
<div class="inner-package" v-if="showTotalTc">
|
||||
<h2 class="inner-tit">
|
||||
{{ personalPackageName }}
|
||||
<span style="display: flex; align-items: center;" v-if="pushBtn" @click="flodTc"> 展开 <van-icon name="arrow-down" size="26"/></span>
|
||||
<span style="display: flex; align-items: center;" v-if="!pushBtn" @click="blowTc"> 收起 <van-icon name="arrow-up" size="26"/></span>
|
||||
</h2>
|
||||
<div style="height: 300px; overflow: auto;" v-if="showTc">
|
||||
<div class="package-area" v-for="(item, index) in sonPackageDetails" :key="index">
|
||||
<div class="package-name">{{ item.combinName }}</div>
|
||||
<div class="package-content">项目内容:{{ item.combinContent }}</div>
|
||||
<div class="package-price">项目价格:<span>{{ item.combinPrice }}元</span></div>
|
||||
</div>
|
||||
<div class="total-price">
|
||||
<span style="padding-right: 0.3rem;">合计</span>
|
||||
<span style="color: red;">{{ totalPrice }}元</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cfm-btn">
|
||||
<van-button class="confirm-package" type="primary" @click="closePopup">确认套餐</van-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</van-popup>
|
||||
<!-- <h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.3rem; " class="personal-area">
|
||||
个性化套餐
|
||||
</h2>
|
||||
<van-field
|
||||
v-model="cascaderValue"
|
||||
is-link
|
||||
readonly
|
||||
:label="personalPackageName"
|
||||
label-width="3.5rem"
|
||||
placeholder="点击查看个性化套餐内容"
|
||||
@click="cascaderShow = true"
|
||||
style="margin-bottom: 0.3rem;"
|
||||
/>
|
||||
<van-popup
|
||||
v-model:show="cascaderShow"
|
||||
round
|
||||
position="bottom"
|
||||
:style="{ padding: '1rem' }"
|
||||
closeable
|
||||
>
|
||||
<div style="text-align: center; font-size: 18px;" v-if="packageDetailStatus === 0">请选择检查类型以查看套餐</div>
|
||||
<div v-if="packageDetailStatus === 1">
|
||||
<h2 style="font-size: 24px; font-weight: bold; margin-bottom: 0.7rem;">{{ personalPackageName }}</h2>
|
||||
<h3 style="font-size: 20px; font-weight: bold; margin-bottom: 0.2rem; margin-top: 0.7rem;">个性化套餐内容</h3>
|
||||
<div class="package-area" v-for="(item, index) in sonPackageDetails" :key="index">
|
||||
<div class="package-name">{{ item.combinName }}</div>
|
||||
<div class="package-price">{{ item.combinPrice }}元</div>
|
||||
</div>
|
||||
<div class="total-price">
|
||||
<span style="padding-right: 0.3rem;">合计</span>
|
||||
<span style="color: red;">{{ totalPrice }}元</span>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup> -->
|
||||
<h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.3rem;">体检时间</h2>
|
||||
<h2 style="font-size: 14px; margin-bottom: 0.3rem; color: #9c9898">注意:一个自然周内,仅限预约一次</h2>
|
||||
<vue-hash-calendar
|
||||
@change="calendarChange"
|
||||
format="YY-MM-DD"
|
||||
:min-date="minDate"
|
||||
:max-date="new Date('2023/10/31')"
|
||||
ref="calendar"
|
||||
picker-type="date"
|
||||
:disabled-date="disabledDate"
|
||||
:disabled-week-view="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="hospital-info-area" v-for="(item, index) in selectedHospital" :key="index">
|
||||
<h2 style="font-size: 18px; font-weight: bold; margin-bottom: 0.4rem;">医院信息</h2>
|
||||
<div class="info">
|
||||
<h4 style="margin-bottom: 0.4rem; color: #2c97ef; font-size: 20px; font-weight: bold;">{{ item.text }}</h4>
|
||||
<h5>地址:{{ item.address }}</h5>
|
||||
<h5>营业时间:{{ item.businessStart }} -- {{ item.businessEnd }}</h5>
|
||||
<h5>负责人:{{ item.responsible }}</h5>
|
||||
<h5>联系方式:{{ item.telPhone }}</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<van-button
|
||||
type="primary"
|
||||
native-type="submit"
|
||||
:disabled="disBtn"
|
||||
style="width: 50%; border-radius: 0.1rem; font-size: 18px; font-weight: bold;">确定预约
|
||||
</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { onMounted, ref, reactive } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { showToast } from 'vant'
|
||||
import { getActualHospital, getPackageDetail, submitForm } from '../../api/ExamPreOrder';
|
||||
|
||||
// 初始值定义
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const result1 = ref<any>('')
|
||||
const result2 = ref<any>('')
|
||||
const result3 = ref<any>('')
|
||||
const showHospitalPicker = ref<boolean>(false)
|
||||
const showTypePicker = ref<boolean>(false)
|
||||
const personalPackageName = ref<any>('')
|
||||
const sonPackageDetails = ref<any[]>([])
|
||||
const basePackageDetails = ref<any[]>([])
|
||||
const totalPrice = ref<number>(0)
|
||||
const packageId = ref<any>('')
|
||||
const hospitalName = ref<any>('')
|
||||
const examType = ref<any>('')
|
||||
// 使用reactive定义响应式对象
|
||||
const selectedHospital = reactive<any>({})
|
||||
// 设置日历日期选择的范围,默认选择当天---当天+30天
|
||||
const minDate = ref<any>(new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()))
|
||||
// const maxDate = ref<any>(new Date(new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).getFullYear(), new Date(Date.now() + 30 * 24* 60 * 60 * 1000).getMonth(), new Date(Date.now() + 30 * 24* 60 * 60 * 1000).getDate()))
|
||||
|
||||
// const packageDetailStatus = ref<number>(0)
|
||||
|
||||
// 级联选择器选项
|
||||
// const cascaderValue = ref<any>('')
|
||||
// const cascaderShow = ref<boolean>(false)
|
||||
const selectedDate = ref<any>('')
|
||||
|
||||
const calendar = ref(null)
|
||||
|
||||
const showTotalTc = ref<boolean>(false)
|
||||
const showTc = ref<boolean>(false)
|
||||
const pushBtn = ref<boolean>(true)
|
||||
const disBtn = ref<boolean>(false)
|
||||
const realToday = ref<any>('')
|
||||
const cancelWeekList = ref<any[]>([])
|
||||
|
||||
const flodTc = () => {
|
||||
showTc.value = true
|
||||
pushBtn.value = false
|
||||
}
|
||||
|
||||
const blowTc = () => {
|
||||
showTc.value = false
|
||||
pushBtn.value = true
|
||||
}
|
||||
|
||||
// 返回上一页
|
||||
const onClickLeft = () => {
|
||||
history.back()
|
||||
}
|
||||
|
||||
// 获取今天
|
||||
const getJT = (date: any) => {
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth()+1);
|
||||
const day = date.getDate();
|
||||
const currDate = ref<any>(``)
|
||||
// 判断日期
|
||||
if (day < 10 && month < 10) {
|
||||
currDate.value = `${year}-0${month}-0${day}`;
|
||||
} else if (month >= 10 && day < 10) {
|
||||
currDate.value = `${year}-${month}-0${day}`;
|
||||
} else if (day >= 10 && month < 10) {
|
||||
currDate.value = `${year}-0${month}-${day}`;
|
||||
} else {
|
||||
currDate.value = `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
return currDate.value
|
||||
|
||||
}
|
||||
|
||||
// 获取下周第一天
|
||||
// type:日期类型,start:开始时间,end:结束时间
|
||||
// dates:日期方向,默认0:本周,-1:上周,1:下周,2:下下周,以此类推
|
||||
const getNextWeekFirst = (type: any, dates = 0) => {
|
||||
let now = new Date();
|
||||
let nowTime = now.getTime();
|
||||
let day = now.getDay();
|
||||
let longTime = 24 * 60 * 60 * 1000;
|
||||
let n = longTime * 7 * (dates || 0);
|
||||
let dd
|
||||
if (type == "start") {
|
||||
dd = nowTime - (day - 1) * longTime + n;
|
||||
};
|
||||
if (type == "end") {
|
||||
dd = nowTime + (7 - day) * longTime + n;
|
||||
};
|
||||
let trueDD = new Date(dd);
|
||||
let y = trueDD.getFullYear();
|
||||
let m = trueDD.getMonth() + 1;
|
||||
let d = trueDD.getDate();
|
||||
let trueM = m < 10 ? "0" + m : m;
|
||||
let trueD = d < 10 ? "0" + d : d;
|
||||
let trueDay = y + "-" + trueM + "-" + trueD;
|
||||
return trueDay;
|
||||
};
|
||||
|
||||
// 提交表单并跳转
|
||||
const subForm = (res: any) => {
|
||||
console.log(selectedDate.value)
|
||||
disBtn.value = true
|
||||
// 将获取的日历日期等数据添加到表单提交对象中
|
||||
res.hospitalId = hospitalName.value
|
||||
res.setMealId = packageId.value
|
||||
res.checkId = examType.value
|
||||
res.phyAppontTime = String(selectedDate.value)
|
||||
res.setMealType = 2
|
||||
res.combName = personalPackageName.value
|
||||
console.log('提交表单', res)
|
||||
if (selectedDate.value == realToday.value) {
|
||||
showToast({
|
||||
message: '不可以预约今天!',
|
||||
icon: 'fail',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
disBtn.value = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
submitForm({
|
||||
hospitalId: res.hospitalId,
|
||||
setMealId: res.setMealId,
|
||||
checkId: res.checkId,
|
||||
phyAppontTime: res.phyAppontTime,
|
||||
setMealType: res.setMealType,
|
||||
combName: res.combName,
|
||||
token: localStorage.getItem('token')
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
if (res.data.res == 0) {
|
||||
showToast({
|
||||
message: '今日可预约人数已满,请重新选择日期预约!',
|
||||
icon: 'fail',
|
||||
duration: 2500,
|
||||
onClose: () => {
|
||||
disBtn.value = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
showToast({
|
||||
message: '预约成功!',
|
||||
icon: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
router.replace({
|
||||
path: '/preOrderSucceed',
|
||||
query: {
|
||||
id: packageId.value
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
showToast({
|
||||
message: '预约超时,请返回重新预约!',
|
||||
icon: 'fail',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
history.go(-1)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 表单提交失败
|
||||
const subFormFail = (err: any) => {
|
||||
console.log(err)
|
||||
}
|
||||
|
||||
const cascaderClose = () => {
|
||||
showTypePicker.value = false
|
||||
result2.value = ''
|
||||
}
|
||||
|
||||
// 定义下拉框的选项
|
||||
const hospitalColumns = ref<any[]>([])
|
||||
const typeColumns = ref<any[]>([
|
||||
{ text: '心血管', value: 1 },
|
||||
{ text: '肿瘤', value: 2 },
|
||||
{ text: '综合', value: 3 }
|
||||
])
|
||||
|
||||
// 获取真实医院接口
|
||||
const fetchActualHospital = () => {
|
||||
getActualHospital({
|
||||
token: localStorage.getItem('token')
|
||||
}).then((res: any) => {
|
||||
if (res.data.obj === 'isnull') {
|
||||
showToast({
|
||||
message: '请联系后台管理员添加医院!',
|
||||
icon: 'fail',
|
||||
duration: 1500
|
||||
})
|
||||
} else {
|
||||
// 设置选择医院单选框的内容
|
||||
const newHospitalObj = res.data.obj.map((item: any) => {
|
||||
return {
|
||||
text: item['hospitalName'],
|
||||
value: item['id'],
|
||||
address: item['address'],
|
||||
businessStart: item['businessStart'],
|
||||
businessEnd: item['businessEnd'],
|
||||
responsible: item['responsible'],
|
||||
telPhone: item['telPhone']
|
||||
}
|
||||
})
|
||||
hospitalColumns.value = newHospitalObj
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 点击关闭弹出框popup,并监听选择医院的变化
|
||||
const onHospitalConfirm = (res: any) => {
|
||||
selectedHospital.value = {}
|
||||
result1.value = res.selectedOptions[0]?.text;
|
||||
showHospitalPicker.value = false;
|
||||
selectedHospital.value = res.selectedOptions[0]
|
||||
hospitalName.value = res.selectedOptions[0]?.value
|
||||
};
|
||||
/* const onTypeConfirm = (res: any) => {
|
||||
result2.value = res.selectedOptions[0]?.text;
|
||||
examType.value = res.selectedOptions[0]?.value
|
||||
showTypePicker.value = false
|
||||
// 点击确认时发送请求,得到个性化套餐的内容渲染到dom中
|
||||
getPackageDetail({
|
||||
checkId: JSON.stringify(res.selectedOptions[0].value),
|
||||
token: localStorage.getItem('token'),
|
||||
combType: 2
|
||||
}).then((result: any) => {
|
||||
console.log(result)
|
||||
if (result.data.obj.tibean.length === 0) {
|
||||
showToast({
|
||||
message: '体检套餐为空,请联系后台管理员发布体检套餐!',
|
||||
icon: 'warning-o'
|
||||
})
|
||||
personalPackageName.value = ''
|
||||
result2.value = ''
|
||||
} else {
|
||||
console.log(result)
|
||||
personalPackageName.value = result.data.obj.tibean[0].combName
|
||||
packageId.value = result.data.obj.tibean[0].id
|
||||
sonPackageDetails.value = result.data.obj.tibeanson
|
||||
basePackageDetails.value = result.data.obj.basebean
|
||||
console.log(packageId.value)
|
||||
totalPrice.value = 0
|
||||
// 计算总价回显至弹出层
|
||||
for (let i = 0; i < sonPackageDetails.value.length; i++) {
|
||||
totalPrice.value += Number(sonPackageDetails.value[i].combinPrice)
|
||||
}
|
||||
for (let j = 0; j < basePackageDetails.value.length; j++) {
|
||||
totalPrice.value += Number(basePackageDetails.value[j].combinPrice)
|
||||
}
|
||||
packageDetailStatus.value = 1
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
} */
|
||||
|
||||
// 日历选择日期改变触发
|
||||
const calendarChange = (res: any) => {
|
||||
console.log(res, '日期改变')
|
||||
selectedDate.value = res
|
||||
}
|
||||
|
||||
// 级联选择器变化
|
||||
const onChange = (res: any) => {
|
||||
console.log(res)
|
||||
result2.value = res.selectedOptions[0]?.text;
|
||||
examType.value = res.selectedOptions[0]?.value
|
||||
getPackageDetail({
|
||||
checkId: JSON.stringify(res.selectedOptions[0].value),
|
||||
token: localStorage.getItem('token'),
|
||||
combType: 2
|
||||
}).then((result: any) => {
|
||||
console.log(result)
|
||||
if (result.data.obj.tibean.length === 0) {
|
||||
showToast({
|
||||
message: '体检套餐为空,请联系后台管理员发布体检套餐!',
|
||||
icon: 'fail',
|
||||
duration: 2000
|
||||
})
|
||||
result2.value = ''
|
||||
} else {
|
||||
showTotalTc.value = true
|
||||
personalPackageName.value = result.data.obj.tibean[0].combName
|
||||
packageId.value = result.data.obj.tibean[0].id
|
||||
sonPackageDetails.value = result.data.obj.tibeanson
|
||||
basePackageDetails.value = result.data.obj.basebean
|
||||
console.log(packageId.value)
|
||||
totalPrice.value = 0
|
||||
// 计算总价回显至弹出层
|
||||
for (let i = 0; i < sonPackageDetails.value.length; i++) {
|
||||
totalPrice.value += Number(sonPackageDetails.value[i].combinPrice)
|
||||
}
|
||||
for (let j = 0; j < basePackageDetails.value.length; j++) {
|
||||
totalPrice.value += Number(basePackageDetails.value[j].combinPrice)
|
||||
}
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 级联选择器点击关闭按钮
|
||||
const closePopup = () =>{
|
||||
if (result2.value === '') {
|
||||
showToast({
|
||||
message: '未选择职工套餐!',
|
||||
icon: 'fail',
|
||||
duration: 1500
|
||||
})
|
||||
} else {
|
||||
showTypePicker.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取某天所处的一周
|
||||
const fetchDayWeek = (chosenDay: any) => {
|
||||
let oneDayTime = 1000 * 60 * 60 * 24
|
||||
let today = new Date(chosenDay)
|
||||
// 若那一天是周末时,则强制赋值为7
|
||||
let todayDay = today.getDay() || 7
|
||||
let startDate = new Date(
|
||||
today.getTime() - oneDayTime * (todayDay - 1)
|
||||
)
|
||||
let dateList = new Array()
|
||||
// 获取当天所处的一周
|
||||
for(let i = 0; i < 7; i++){
|
||||
let temp = new Date(startDate.getTime() + i * oneDayTime)
|
||||
let year = temp.getFullYear()
|
||||
let month = temp.getMonth() + 1
|
||||
let day = temp.getDate()
|
||||
if (day < 10 && month < 10) {
|
||||
dateList[i] = `${year}-0${month}-0${day}`
|
||||
} else if (month >= 10 && day < 10) {
|
||||
dateList[i] = `${year}-${month}-0${day}`
|
||||
} else if (day >= 10 && month < 10) {
|
||||
dateList[i] = `${year}-0${month}-${day}`
|
||||
} else {
|
||||
dateList[i] = `${year}-${month}-${day}`
|
||||
}
|
||||
}
|
||||
return dateList
|
||||
}
|
||||
|
||||
// 设置日历禁用日期
|
||||
const disabledDate = (date: any) => {
|
||||
const year = date.getFullYear();
|
||||
// 月份需要+1
|
||||
const month = (date.getMonth()+1);
|
||||
const day = date.getDate();
|
||||
const currDate = ref<any>(``)
|
||||
// 判断日期
|
||||
if (day < 10 && month < 10) {
|
||||
currDate.value = `${year}-0${month}-0${day}`;
|
||||
} else if (month >= 10 && day < 10) {
|
||||
currDate.value = `${year}-${month}-0${day}`;
|
||||
} else if (day >= 10 && month < 10) {
|
||||
currDate.value = `${year}-0${month}-${day}`;
|
||||
} else {
|
||||
currDate.value = `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
// 生成禁用日期
|
||||
const disabledDateArr = [];
|
||||
|
||||
// 获取当天所处的一周
|
||||
let oneDayTime = 1000 * 60 * 60 * 24
|
||||
let today = new Date() // selectedDate.value
|
||||
// 若那一天是周末时,则强制赋值为7
|
||||
let todayDay = today.getDay() || 7
|
||||
let startDate = new Date(
|
||||
today.getTime() - oneDayTime * (todayDay - 1)
|
||||
)
|
||||
let dateList = new Array()
|
||||
|
||||
/* let dayCount = new Date().getDay()
|
||||
let todayTemp = new Date(startDate.getTime() + (dayCount - 1) * oneDayTime)
|
||||
let tempYear = todayTemp.getFullYear()
|
||||
let tempMonth = todayTemp.getMonth() + 1
|
||||
let tempDay = todayTemp.getDate()
|
||||
let trueToday = ref<any>('')
|
||||
if (tempDay < 10 && tempMonth < 10) {
|
||||
trueToday = `${tempYear}-0${tempMonth}-0${tempDay}`
|
||||
} else if (tempMonth >= 10 && tempDay < 10) {
|
||||
trueToday = `${tempYear}-${tempMonth}-0${tempDay}`
|
||||
} else if (tempDay >= 10 && tempMonth < 10) {
|
||||
trueToday = `${tempYear}-0${tempMonth}-${tempDay}`
|
||||
} else {
|
||||
trueToday = `${tempYear}-${tempMonth}-${tempDay}`
|
||||
}
|
||||
console.log(trueToday, 'sss') */
|
||||
|
||||
/* let trueToday = new Date()
|
||||
let trueTodayYear = trueToday.getFullYear()
|
||||
let trueTodayMonth = trueToday.getMonth() + 1
|
||||
let trueTodayDay = trueToday.getDate()
|
||||
let formatToady = ''
|
||||
if (trueTodayDay < 10 && trueTodayMonth < 10) {
|
||||
formatToady = `${trueTodayYear}-0${trueTodayMonth}-0${trueTodayDay}`
|
||||
} else if (trueTodayMonth >= 10 && trueTodayDay < 10) {
|
||||
formatToady = `${trueTodayYear}-${trueTodayMonth}-0${trueTodayDay}`
|
||||
} else if (trueTodayDay >= 10 && trueTodayMonth < 10) {
|
||||
formatToady = `${trueTodayYear}-0${trueTodayMonth}-${trueTodayDay}`
|
||||
} else {
|
||||
formatToady = `${trueTodayYear}-${trueTodayMonth}-${trueTodayDay}`
|
||||
} */
|
||||
|
||||
// 获取当天所处的一周
|
||||
for(let i = 0; i < 7; i++){
|
||||
let temp = new Date(startDate.getTime() + i * oneDayTime)
|
||||
let year = temp.getFullYear()
|
||||
let month = temp.getMonth() + 1
|
||||
let day = temp.getDate()
|
||||
if (day < 10 && month < 10) {
|
||||
dateList[i] = `${year}-0${month}-0${day}`
|
||||
} else if (month >= 10 && day < 10) {
|
||||
dateList[i] = `${year}-${month}-0${day}`
|
||||
} else if (day >= 10 && month < 10) {
|
||||
dateList[i] = `${year}-0${month}-${day}`
|
||||
} else {
|
||||
dateList[i] = `${year}-${month}-${day}`
|
||||
}
|
||||
disabledDateArr.push(dateList[i])
|
||||
}
|
||||
|
||||
/* for (let j = 0; j < cancelWeekList.value.length; j++) {
|
||||
disabledDateArr.push(cancelWeekList.value[j])
|
||||
} */
|
||||
|
||||
if (disabledDateArr.includes(currDate.value)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchActualHospital()
|
||||
realToday.value = getJT(new Date())
|
||||
console.log(route.query.cancelDate, '取消日时间戳')
|
||||
console.log(fetchDayWeek(Number(route.query.cancelDate)), '取消日所处的星期')
|
||||
cancelWeekList.value = fetchDayWeek(Number(route.query.cancelDate))
|
||||
console.log(getNextWeekFirst('start', 1)) // 下周第一天
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form-area{
|
||||
width: 100%;
|
||||
margin: 0.2rem auto;
|
||||
.upper-info{
|
||||
width: 96%;
|
||||
margin: 0 auto;
|
||||
background-color: #f8f8f8;
|
||||
box-sizing: border-box;
|
||||
padding: 0.3rem;
|
||||
border-radius: 0.1rem;
|
||||
position: relative;
|
||||
.inner-package{
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0.2rem;
|
||||
height: 10.5rem;
|
||||
.inner-tit{
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #2c97ef;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding: 0.2rem 0;
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
}
|
||||
h1{
|
||||
font-size: 20px;
|
||||
color: #2c97ef;
|
||||
margin-bottom: 0.4rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
h2{
|
||||
margin-bottom: 0.4rem;
|
||||
line-height: 26px;
|
||||
}
|
||||
.cfm-btn{
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
left: 10px;
|
||||
bottom: 10px;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.personal-area{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.hospital-info-area{
|
||||
width: 94%;
|
||||
margin: 0.5rem auto;
|
||||
background-color: #fff;
|
||||
border-radius: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
padding: 0.3rem;
|
||||
.info{
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0.1rem auto;
|
||||
h5{
|
||||
font-size: 16px;
|
||||
margin-bottom: 0.2rem;
|
||||
line-height: 20px;
|
||||
}
|
||||
h5:nth-child(5){
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn{
|
||||
width: 100%;
|
||||
margin: 0.5rem auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.package-area{
|
||||
.package-name{
|
||||
font-size: 20px;
|
||||
margin-bottom: 0.15rem;
|
||||
font-weight: bold;
|
||||
color: #2c97ef;
|
||||
}
|
||||
.package-price, .package-content{
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
}
|
||||
.package-price{
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.package-price{
|
||||
span{
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
.total-price{
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
margin-top: 1rem;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<van-nav-bar
|
||||
title="体检报告"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
/>
|
||||
<van-field
|
||||
v-model="value1"
|
||||
left-icon="search"
|
||||
placeholder="查找报告"
|
||||
style="width: 95%; margin: 0.2rem auto;"
|
||||
/>
|
||||
<van-field
|
||||
v-model="fieldValue"
|
||||
is-link
|
||||
readonly
|
||||
label="年份"
|
||||
placeholder="请选择年份"
|
||||
@click="showPicker = true"
|
||||
style="width: 95%; margin: 0.2rem auto;"
|
||||
/>
|
||||
<van-popup v-model:show="showPicker" round position="bottom">
|
||||
<van-picker
|
||||
:columns="columns"
|
||||
@cancel="showPicker = false"
|
||||
@confirm="onConfirm"
|
||||
/>
|
||||
</van-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const value1 = ref<any>('')
|
||||
const fieldValue = ref<any>('')
|
||||
const showPicker = ref<boolean>(false)
|
||||
const columns = ref<any[]>([
|
||||
{ text: '2023年', value: 0 },
|
||||
{ text: '2022年', value: 1 },
|
||||
{ text: '2021年', value: 2 },
|
||||
])
|
||||
|
||||
const onClickLeft = () => {
|
||||
history.back()
|
||||
}
|
||||
|
||||
const onConfirm = (res: any) => {
|
||||
showPicker.value = false
|
||||
fieldValue.value = res.selectedOptions[0].text
|
||||
console.log(res.selectedOptions[0].value)
|
||||
}
|
||||
|
||||
// 监听输入框内容变化
|
||||
/* const iptChange = (res: any) => {
|
||||
console.log(res)
|
||||
} */
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,403 @@
|
|||
<template>
|
||||
<van-nav-bar
|
||||
title="重置密码"
|
||||
/>
|
||||
<div class="background">
|
||||
<div class="block_3 flex-col">
|
||||
<div class="section_1 flex-col"></div>
|
||||
<div class="section_2 flex-col"></div>
|
||||
<div class="section_3 flex-col"></div>
|
||||
</div>
|
||||
</div>
|
||||
<van-form
|
||||
@submit="subNewPwd"
|
||||
class="forget-area"
|
||||
>
|
||||
<van-field
|
||||
v-model="phoneNumber"
|
||||
name="phoneNumber"
|
||||
:placeholder="phoneNumPlaceHolder"
|
||||
@focus="focusPhoneNum"
|
||||
@blur="blurPhoneNum"
|
||||
:rules="[{ required: true, message: '请填写手机号!' }]"
|
||||
autocomplete="off"
|
||||
clearable
|
||||
style="border: 1px solid #62b0b0; background-color: #f3f9f9; font-size: 16px;"
|
||||
/>
|
||||
<van-field
|
||||
v-model="newPwd"
|
||||
name="newPwd"
|
||||
:type="newPwdType"
|
||||
:placeholder="pwdPlaceHolder"
|
||||
@focus="focusPwd"
|
||||
@blur="blurPwd"
|
||||
:rules="[{
|
||||
required: true,
|
||||
message: '请输入新密码!',
|
||||
validator: iptPwd
|
||||
}]"
|
||||
autocomplete="off"
|
||||
clearable
|
||||
style="margin-top: 0.5rem; border: 1px solid #62b0b0; background-color: #f3f9f9; font-size: 16px;"
|
||||
>
|
||||
<template #button>
|
||||
<van-button
|
||||
style="font-size: 16px; background-color: transparent; color: #1989fa; border: none;"
|
||||
size="small"
|
||||
type="primary"
|
||||
>
|
||||
<span v-if="newPwdStatus === 0" @click="showNewPwd">查看</span>
|
||||
<span v-if="newPwdStatus === 1" @click="hideNewPwd">隐藏</span>
|
||||
</van-button>
|
||||
</template>
|
||||
</van-field>
|
||||
<van-field
|
||||
v-model="confirmNewPwd"
|
||||
name="confirmNewPwd"
|
||||
type="password"
|
||||
:placeholder="confirmPwdPlaceHolder"
|
||||
@focus="focusConfirmPwd"
|
||||
@blur="blurConfirmPwd"
|
||||
:rules="[{
|
||||
required: true,
|
||||
message: '请确认新密码!' ,
|
||||
validator: confirmPwd
|
||||
}]"
|
||||
autocomplete="off"
|
||||
style="margin-top: 0.5rem; border: 1px solid #62b0b0; background-color: #f3f9f9; font-size: 16px;"
|
||||
>
|
||||
<!-- <template #button>
|
||||
<van-button
|
||||
style="font-size: 16px; background-color: transparent; color: #1989fa; border: none;"
|
||||
size="small"
|
||||
type="primary"
|
||||
>
|
||||
<span v-if="confirmPwdStatus === 0" @click="showConfirmPwd">查看</span>
|
||||
<span v-if="confirmPwdStatus === 1" @click="hideConfirmPwd">隐藏</span>
|
||||
</van-button>
|
||||
</template> -->
|
||||
</van-field>
|
||||
<van-field
|
||||
v-model="verifyNum"
|
||||
name="verifyNum"
|
||||
:placeholder="veriPlaceHolder"
|
||||
@focus="focusVeri"
|
||||
@blur="blurVeri"
|
||||
:rules="[{ required: true }]"
|
||||
autocomplete="off"
|
||||
style="margin-top: 0.5rem; border: 1px solid #62b0b0; background-color: #f3f9f9; font-size: 16px; display: flex; align-items: center;"
|
||||
>
|
||||
<template #button>
|
||||
<van-button
|
||||
style="border-radius: 0.8rem;"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="sendCode"
|
||||
:disabled="veriBtnDisable"
|
||||
>
|
||||
<span v-if="countStatus === 0">{{ time }}</span>
|
||||
<span v-if="countStatus === 1">
|
||||
<span>{{ countSecond }}</span>
|
||||
s
|
||||
</span>
|
||||
</van-button>
|
||||
</template>
|
||||
</van-field>
|
||||
<div class="btn-area">
|
||||
<van-button
|
||||
type="primary"
|
||||
native-type="submit"
|
||||
style="width: 70%; border-radius: 0.5rem; font-size: 18px;"
|
||||
>
|
||||
确认修改
|
||||
</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { showToast } from 'vant';
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { editNewPwd, sendVeriCode } from '../../api/ForgetPassword'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import './scss/index.scss'
|
||||
|
||||
const phoneNumPlaceHolder = ref<string>('请输入手机号')
|
||||
const pwdPlaceHolder = ref<string>('请输入新密码')
|
||||
const confirmPwdPlaceHolder = ref<string>('请确认新密码')
|
||||
const veriPlaceHolder = ref<string>('验证码')
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const phoneNumber = ref<any>('')
|
||||
const newPwd = ref<any>('')
|
||||
const confirmNewPwd = ref<any>('')
|
||||
const verifyNum = ref<any>('')
|
||||
const countStatus = ref<number>(0)
|
||||
const countSecond = ref<number>(60)
|
||||
const veriBtnDisable = ref<boolean>(false)
|
||||
const sendData = ref<any>({})
|
||||
const time = ref<any>('发送验证码')
|
||||
const pwdPattern = /^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&*]+$)(?![\d!@#$%^&*]+$)[a-zA-Z\d!@#$%^&*]+$/
|
||||
|
||||
const newPwdType = ref<any>('password')
|
||||
const newPwdStatus = ref<number>(0)
|
||||
// const confirmPwdType = ref<any>('password')
|
||||
// const confirmPwdStatus = ref<number>(0)
|
||||
|
||||
// 新密码框显示密码
|
||||
const showNewPwd = () => {
|
||||
newPwdType.value = 'input'
|
||||
newPwdStatus.value = 1
|
||||
}
|
||||
|
||||
// 新密码框隐藏密码
|
||||
const hideNewPwd = () => {
|
||||
newPwdType.value = 'password'
|
||||
newPwdStatus.value = 0
|
||||
}
|
||||
|
||||
// 确认密码框显示密码
|
||||
/* const showConfirmPwd = () => {
|
||||
confirmPwdType.value = 'input'
|
||||
confirmPwdStatus.value = 1
|
||||
} */
|
||||
|
||||
// 确认密码框隐藏密码
|
||||
/* const hideConfirmPwd = () => {
|
||||
confirmPwdType.value = 'password'
|
||||
confirmPwdStatus.value = 0
|
||||
} */
|
||||
|
||||
// 输入框获取焦点
|
||||
const focusPhoneNum = () => {
|
||||
phoneNumPlaceHolder.value = ''
|
||||
}
|
||||
const focusPwd = () => {
|
||||
pwdPlaceHolder.value = ''
|
||||
}
|
||||
const focusConfirmPwd = () => {
|
||||
confirmPwdPlaceHolder.value = ''
|
||||
}
|
||||
const focusVeri = () => {
|
||||
veriPlaceHolder.value = ''
|
||||
}
|
||||
|
||||
// 输入框失去焦点
|
||||
const blurPhoneNum = () => {
|
||||
phoneNumPlaceHolder.value = '请输入手机号'
|
||||
}
|
||||
const blurPwd = () => {
|
||||
pwdPlaceHolder.value = '请输入新密码'
|
||||
}
|
||||
const blurConfirmPwd = () => {
|
||||
confirmPwdPlaceHolder.value = '请确认新密码'
|
||||
}
|
||||
const blurVeri = () => {
|
||||
veriPlaceHolder.value = '验证码'
|
||||
}
|
||||
|
||||
/* const onClickLeft = () => {
|
||||
history.back()
|
||||
} */
|
||||
|
||||
// 提交表单
|
||||
const subNewPwd = (val: any) => {
|
||||
if (Number(verifyNum.value) !== Number(localStorage.getItem('veriCode')) // 验证码输入错误
|
||||
|| phoneNumber.value === null // 手机号不能为空
|
||||
|| !localStorage.getItem('veriCode') // 本地存储为空
|
||||
|| newPwd.value !== confirmNewPwd.value // 两个密码不相符
|
||||
|| phoneNumber.value.length !== 11 // 手机号长度不符
|
||||
) {
|
||||
showToast({
|
||||
message: '手机号或验证码不正确!',
|
||||
icon: 'fail',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
verifyNum.value = ''
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('修改成功', val.newPwd)
|
||||
sendData.password = val.newPwd
|
||||
sendData.telephone = val.phoneNumber
|
||||
console.log(sendData.password, sendData.telephone)
|
||||
editNewPwd({
|
||||
password: sendData.password,
|
||||
telephone: sendData.telephone
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
if (res.data.obj.num === 1) {
|
||||
showToast({
|
||||
message: res.data.resMsg,
|
||||
icon: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
localStorage.removeItem('veriCode')
|
||||
router.push('/accountLogin')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
showToast({
|
||||
message: '修改密码失败!',
|
||||
icon: 'fail',
|
||||
duration: 1500
|
||||
})
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 输入密码校验
|
||||
const iptPwd = (val: any) => {
|
||||
if (!pwdPattern.test(val)) {
|
||||
showToast({
|
||||
message: '密码必须包含大小写字母、特殊字符和数字!',
|
||||
icon: 'fail',
|
||||
duration: 3000,
|
||||
onClose: () => {
|
||||
newPwd.value = ''
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 确认密码校验
|
||||
const confirmPwd = (val: any) => {
|
||||
if (val !== newPwd.value) {
|
||||
showToast({
|
||||
message: '请确认密码保持一致!',
|
||||
icon: 'fail',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
confirmNewPwd.value = ''
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 发送验证码
|
||||
const sendCode = () => {
|
||||
console.log(phoneNumber.value.length)
|
||||
if (phoneNumber.value.length !== 11) {
|
||||
showToast({
|
||||
message: '请输入正确格式的手机号!',
|
||||
icon: 'fail',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
phoneNumber.value = ''
|
||||
}
|
||||
})
|
||||
} else {
|
||||
sendVeriCode({
|
||||
telephone: phoneNumber.value
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
// 后台返回data为空时,说明数据库中不存在此号码,给出提示
|
||||
if (res.data === '') {
|
||||
showToast({
|
||||
message: '此人员不在系统中,请联系后台管理员添加账号!',
|
||||
icon: 'fail',
|
||||
duration: 3000,
|
||||
onClose: () => {
|
||||
phoneNumber.value = ''
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 设置验证码60s倒计时
|
||||
localStorage.setItem('veriCode', res.data)
|
||||
countStatus.value = 1
|
||||
veriBtnDisable.value = true
|
||||
const timeOut = setTimeout(() => {
|
||||
localStorage.removeItem('veriCode')
|
||||
countStatus.value = 0
|
||||
countSecond.value = 60
|
||||
veriBtnDisable.value = false
|
||||
clearInterval(interval)
|
||||
clearTimeout(timeOut)
|
||||
}, 60 * 1000)
|
||||
const interval = setInterval(() => {
|
||||
countSecond.value -= 1
|
||||
}, 1000)
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 确认修改密码
|
||||
/* const editPwd = (value: any) => {
|
||||
} */
|
||||
|
||||
onMounted(() => {
|
||||
console.log(route.query.phoneNum)
|
||||
if (route.query) {
|
||||
phoneNumber.value = route.query.phoneNum
|
||||
} else {
|
||||
phoneNumber.value = ''
|
||||
}
|
||||
})
|
||||
|
||||
/* onBeforeUnmount(() => {
|
||||
localStorage.removeItem('veriCode')
|
||||
}) */
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.background {
|
||||
width: 10rem;
|
||||
height: 8rem;
|
||||
background: url('../../static/bg.jpg')
|
||||
100% no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
margin-bottom: 7rem;
|
||||
left: 0;
|
||||
top: 0;
|
||||
.section_1 {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.section_2 {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 0.1rem;
|
||||
top: 1.2rem;
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
}
|
||||
|
||||
.section_3 {
|
||||
background-color: rgba(255, 255, 255, 0.0624);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 6rem;
|
||||
top: 0.5rem;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
}
|
||||
.forget-area{
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
padding: 7rem 0.5rem;
|
||||
}
|
||||
.btn-area{
|
||||
width: 100%;
|
||||
margin-top: 1rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
:root:root{
|
||||
--van-field-placeholder-text-color: #000;
|
||||
}
|
||||
|
|
@ -0,0 +1,349 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="swipe-area">
|
||||
<van-swipe :autoplay="3000">
|
||||
<van-swipe-item>
|
||||
<img src="../../static/post1.png" alt="">
|
||||
</van-swipe-item>
|
||||
<van-swipe-item>
|
||||
<img src="../../static/post2.png" alt="">
|
||||
</van-swipe-item>
|
||||
<van-swipe-item>
|
||||
<img src="../../static/post3.png" alt="">
|
||||
</van-swipe-item>
|
||||
</van-swipe>
|
||||
</div>
|
||||
<h2 class="tit">体检服务</h2>
|
||||
<div class="services">
|
||||
<div class="services-item" @click="judgePreOrdered()">
|
||||
<img :src="preOrderImg" alt=""/>
|
||||
<span>体检预约</span>
|
||||
</div>
|
||||
<div v-if="userStatus !== 0" class="services-item" @click="judgeCareerPre()">
|
||||
<img :src="careerExamImg" alt=""/>
|
||||
<span>职业体检</span>
|
||||
</div>
|
||||
<div class="services-item" @click="jumpReport()">
|
||||
<img :src="reportImg" alt=""/>
|
||||
<span>体检报告</span>
|
||||
</div>
|
||||
<div class="services-item" @click="jumpMyPre()">
|
||||
<img :src="myPreImg" alt=""/>
|
||||
<span>我的预约</span>
|
||||
</div>
|
||||
</div>
|
||||
<TabBar/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Home">
|
||||
|
||||
import TabBar from '../../components/TabBar.vue';
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { getUserStatus, isPreOrdered } from '../../api/Home'
|
||||
// 引入图片
|
||||
import preOrderImg from '../../static/preOrder.png'
|
||||
import careerExamImg from '../../static/careerExam.png'
|
||||
import reportImg from '../../static/report.png'
|
||||
import myPreImg from '../../static/myPreOrder.png'
|
||||
import { showToast } from 'vant';
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const userStatus = ref<number>(0)
|
||||
const appoint1 = ref<number>(3)
|
||||
const appoint2 = ref<number>(2)
|
||||
// const currentTime = ref<number>(new Date().getTime())
|
||||
const originCancel = ref<any>()
|
||||
const cancelTime = ref<any>()
|
||||
const cancelWeekStart = ref<any>()
|
||||
const cancelWeekEnd = ref<any>()
|
||||
|
||||
// 获取取消日期所处一周的时间范围
|
||||
// type:日期类型,start:开始时间,end:结束时间
|
||||
// dates:日期方向,默认0:本周,-1:上周,1:下周,2:下下周,以此类推
|
||||
// cancelDay:传入的日期
|
||||
const getCancelWeek = (type: string, dates = 0, cancelDay: string | number | Date) => {
|
||||
let now = new Date(cancelDay);
|
||||
let nowTime = now.getTime();
|
||||
let day = now.getDay();
|
||||
if (day == 0) {
|
||||
nowTime = nowTime - 7 * 24 * 60 * 60 * 1000
|
||||
}
|
||||
let longTime = 24 * 60 * 60 * 1000;
|
||||
let n = longTime * 7 * (dates || 0);
|
||||
let dd
|
||||
if (type == "start") {
|
||||
dd = nowTime - (day - 1) * longTime + n;
|
||||
};
|
||||
if (type == "end") {
|
||||
if (day == 0) {
|
||||
dd = nowTime + (7 - day) * longTime + n + longTime;
|
||||
} else {
|
||||
dd = nowTime + (7 - day) * longTime + n;
|
||||
}
|
||||
};
|
||||
let trueDD = new Date(dd);
|
||||
let y = trueDD.getFullYear();
|
||||
let m = trueDD.getMonth() + 1;
|
||||
let d = trueDD.getDate();
|
||||
let trueM = m < 10 ? "0" + m : m;
|
||||
let trueD = d < 10 ? "0" + d : d;
|
||||
let trueDay = y + "-" + trueM + "-" + trueD;
|
||||
return trueDay;
|
||||
};
|
||||
|
||||
// 初始化时获取用户状态
|
||||
const fetchUserStatus = () => {
|
||||
getUserStatus({
|
||||
token: localStorage.getItem('token'),
|
||||
telephone: localStorage.getItem('phoneNumber')
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
originCancel.value = res.data.obj.cancelTime
|
||||
// console.log(originCancel.value)
|
||||
userStatus.value = Number(res.data.obj.status)
|
||||
cancelTime.value = Date.parse(res.data.obj.cancelTime)
|
||||
/* console.log(getCancelWeek('start', 0, cancelTime.value), getCancelWeek('end', 0, cancelTime.value))
|
||||
console.log(Date.parse(res.data.obj.cancelTime), '7.1')
|
||||
console.log(Date.parse(getCancelWeek('end', 0, cancelTime.value)), '7.2') */
|
||||
cancelWeekStart.value = Date.parse(getCancelWeek('start', 0, cancelTime.value))
|
||||
cancelWeekEnd.value = Date.parse(getCancelWeek('end', 0, cancelTime.value))
|
||||
/* console.log(cancelTime.value, '取消日期时间戳')
|
||||
console.log(cancelWeekStart.value, '取消周首日时间戳')
|
||||
console.log(cancelWeekEnd.value, '取消周最后一日时间戳') */
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 判断体检预约是否已经预约和已经取消
|
||||
const judgePreOrdered = () => {
|
||||
isPreOrdered({
|
||||
token: localStorage.getItem('token'),
|
||||
appoint: appoint2.value
|
||||
}).then((res: any) => {
|
||||
console.log(res, '收到')
|
||||
if (res.data.obj === 1) {
|
||||
router.push({
|
||||
path: '/examPreOrder',
|
||||
query: {
|
||||
cancelDate: cancelTime.value + 7 * 24 * 60 * 60 * 1000
|
||||
}
|
||||
})
|
||||
} else {
|
||||
showToast({
|
||||
message: '您已经预约过,无法再次预约!',
|
||||
icon: 'fail',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err, '错误')
|
||||
})
|
||||
}
|
||||
|
||||
// 判断职业体检预约是否已经预约和已经取消
|
||||
const judgeCareerPre = () => {
|
||||
isPreOrdered({
|
||||
token: localStorage.getItem('token'),
|
||||
appoint: appoint1.value
|
||||
}).then((res: any) => {
|
||||
console.log(res, '收到')
|
||||
if (res.data.obj === 1) {
|
||||
router.push({
|
||||
path: '/careerExam'
|
||||
})
|
||||
} else {
|
||||
showToast({
|
||||
message: '您已经预约过,无法再次预约!',
|
||||
icon: 'fail',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err, '错误')
|
||||
})
|
||||
}
|
||||
|
||||
// 体检预约
|
||||
/* const jumpExam = () => {
|
||||
if (originCancel.value == null) {
|
||||
judgePreOrdered()
|
||||
} else if (cancelTime.value > cancelWeekStart.value && cancelTime.value < cancelWeekEnd.value) {
|
||||
if (currentTime.value < Date.parse(getCancelWeek('start', 1, cancelTime.value))) {
|
||||
showToast({
|
||||
message: '本周已取消预约,请下周再次预约!',
|
||||
icon: 'fail',
|
||||
duration: 2000
|
||||
})
|
||||
} else {
|
||||
judgePreOrdered()
|
||||
}
|
||||
} else {
|
||||
console.log('日期异常')
|
||||
}
|
||||
} */
|
||||
|
||||
// 体检报告
|
||||
const jumpReport = () => {
|
||||
router.push({
|
||||
path: '/examReport'
|
||||
})
|
||||
}
|
||||
|
||||
// 我的预约
|
||||
const jumpMyPre = () => {
|
||||
router.push({
|
||||
path: '/myPreOrder'
|
||||
})
|
||||
}
|
||||
|
||||
// 职业体检
|
||||
/* const jumpCareer = () => {
|
||||
if (originCancel.value == null) {
|
||||
judgeCareerPre()
|
||||
} else if (cancelTime.value > cancelWeekStart.value && cancelTime.value < cancelWeekEnd.value) {
|
||||
if (currentTime.value < Date.parse(getCancelWeek('start', 1, cancelTime.value))) {
|
||||
showToast({
|
||||
message: '本周已取消预约,请下周再次预约!',
|
||||
icon: 'fail',
|
||||
duration: 2000
|
||||
})
|
||||
} else {
|
||||
judgeCareerPre()
|
||||
}
|
||||
} else {
|
||||
console.log('日期异常')
|
||||
}
|
||||
} */
|
||||
|
||||
onMounted(() => {
|
||||
/* console.log(currentTime.value, '当天时间戳')
|
||||
console.log(Date.parse(getCancelWeek('start', 1, currentTime.value)), '下周一时间戳') */
|
||||
if (route.query.pwd === 'YNsbd@123456') {
|
||||
showToast({
|
||||
message: '首次登录,请您重置密码!',
|
||||
icon: 'fail',
|
||||
duration: 3000,
|
||||
onClose: () => {
|
||||
router.replace({
|
||||
path: '/forgetPassword',
|
||||
query: {
|
||||
phoneNum: localStorage.getItem('phoneNumber')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 如果取不到cookie,清除登录状态
|
||||
if (!document.cookie) {
|
||||
showToast({
|
||||
message: '登录状态已过期,请重新登录!',
|
||||
icon: 'fail',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('phoneNumber')
|
||||
localStorage.removeItem('phyName')
|
||||
localStorage.removeItem('idcard')
|
||||
localStorage.removeItem('sex')
|
||||
localStorage.removeItem('age')
|
||||
localStorage.removeItem('telepNumber')
|
||||
localStorage.removeItem('departName')
|
||||
history.go(0)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
fetchUserStatus()
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.background {
|
||||
width: 10rem;
|
||||
height: 8rem;
|
||||
background: url('../../static/bg.jpg');
|
||||
background-size: 100% 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
.section_1 {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.section_2 {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 0.1rem;
|
||||
top: 1.2rem;
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
}
|
||||
|
||||
.section_3 {
|
||||
background-color: rgba(255, 255, 255, 0.0624);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 6rem;
|
||||
top: 0.5rem;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
}
|
||||
.swipe-area{
|
||||
width: 95%;
|
||||
height: 70%;
|
||||
margin: 0 auto;
|
||||
padding-top: 0.8rem;
|
||||
img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.tit{
|
||||
margin: 0.6rem 0 0 0;
|
||||
padding-left: 0.2rem;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.services{
|
||||
width: 95%;
|
||||
margin: 0.3rem auto;
|
||||
height: 7rem;
|
||||
border-radius: 0.2rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem 0 0 1.2rem;
|
||||
background-color: #fff;
|
||||
.services-item{
|
||||
width: 20%;
|
||||
height: 30%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
margin-right: 1rem;
|
||||
margin-bottom: 0.1rem;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
span{
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
padding-top: 0.3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="background">
|
||||
<div class="block_3 flex-col">
|
||||
<div class="section_1 flex-col"></div>
|
||||
<div class="section_2 flex-col"></div>
|
||||
<div class="section_3 flex-col"></div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="log-tit">云送体检预约</h2>
|
||||
<van-form @submit="logPhoneSub" class="log-form">
|
||||
<van-field
|
||||
v-model="phoneNumber"
|
||||
name="phoneNumber"
|
||||
:placeholder="phoneNumPlaceHolder"
|
||||
@focus="focusPhoneNum"
|
||||
@blur="blurPhoneNum"
|
||||
:rules="[{ required: true, message: '请填写手机号!' }]"
|
||||
autocomplete="off"
|
||||
clearable
|
||||
style="border: 1px solid #62b0b0; background-color: #f3f9f9; font-size: 16px;"
|
||||
/>
|
||||
<van-field
|
||||
v-model="verifyNum"
|
||||
name="verifyNum"
|
||||
:placeholder="veriPlaceHolder"
|
||||
@focus="focusVeri"
|
||||
@blur="blurVeri"
|
||||
:rules="[{ required: true }]"
|
||||
autocomplete="off"
|
||||
style="margin-top: 0.5rem; border: 1px solid #62b0b0; background-color: #f3f9f9; font-size: 16px; display: flex; align-items: center;"
|
||||
>
|
||||
<template #button>
|
||||
<van-button
|
||||
style="border-radius: 0.8rem"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="sendVeriCode"
|
||||
:disabled="veriBtnDisable"
|
||||
>
|
||||
<span v-if="countStatus === 0">{{ time }}</span>
|
||||
<span v-if="countStatus === 1">
|
||||
<span>{{ countSecond }}</span>
|
||||
s
|
||||
</span>
|
||||
</van-button>
|
||||
</template>
|
||||
</van-field>
|
||||
<div class="user-taps">
|
||||
<span @click="jumpForget()">忘记密码</span>
|
||||
<span @click="jumpAccount()">账号密码登录</span>
|
||||
</div>
|
||||
<div class="btn-area">
|
||||
<van-button
|
||||
type="primary"
|
||||
native-type="submit"
|
||||
style="width: 70%; border-radius: 0.5rem; font-size: 18px;"
|
||||
>
|
||||
登录
|
||||
</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { sendPhoneVeri, logWithMsg } from '../../api/MsgLogin'
|
||||
import { showToast, showFailToast } from 'vant';
|
||||
import './scss/index.scss'
|
||||
|
||||
const phoneNumPlaceHolder = ref<string>('手机号')
|
||||
const veriPlaceHolder = ref<string>('验证码')
|
||||
const phoneNumber = ref<any>('')
|
||||
const verifyNum = ref<any>('')
|
||||
const router = useRouter()
|
||||
const time = ref<any>('发送验证码')
|
||||
const countStatus = ref<number>(0)
|
||||
const countSecond = ref<number>(60)
|
||||
const veriBtnDisable = ref<boolean>(false)
|
||||
const msgInfo = ref<any>({})
|
||||
|
||||
// 输入框获得焦点
|
||||
const focusPhoneNum = () => {
|
||||
phoneNumPlaceHolder.value = ''
|
||||
}
|
||||
const focusVeri = () => {
|
||||
veriPlaceHolder.value = ''
|
||||
}
|
||||
|
||||
// 输入框失去焦点
|
||||
const blurPhoneNum = () => {
|
||||
phoneNumPlaceHolder.value = '手机号'
|
||||
}
|
||||
const blurVeri = () => {
|
||||
veriPlaceHolder.value = '验证码'
|
||||
}
|
||||
|
||||
// 跳转到忘记密码
|
||||
const jumpForget = () => {
|
||||
router.push({
|
||||
path: '/forgetPassword'
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转到账号密码登录
|
||||
const jumpAccount = () => {
|
||||
router.push({
|
||||
path: '/accountLogin'
|
||||
})
|
||||
}
|
||||
|
||||
// 点击发送验证码
|
||||
const sendVeriCode = () => {
|
||||
if (phoneNumber.value.length !== 11) {
|
||||
showToast({
|
||||
message: '请输入正确格式的手机号!',
|
||||
icon: 'fail',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
phoneNumber.value = ''
|
||||
}
|
||||
})
|
||||
} else {
|
||||
sendPhoneVeri({
|
||||
telephone: phoneNumber.value
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
if (res.data === '') {
|
||||
showToast({
|
||||
message: '此人员不在系统中,请联系后台管理员添加账号!',
|
||||
icon: 'fail',
|
||||
duration: 3000,
|
||||
onClose: () => {
|
||||
phoneNumber.value = ''
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 设置验证码60s倒计时
|
||||
localStorage.setItem('veriPhoneCode', res.data)
|
||||
countStatus.value = 1
|
||||
veriBtnDisable.value = true
|
||||
const phoneTimeOut = setTimeout(() => {
|
||||
localStorage.removeItem('veriPhoneCode')
|
||||
countStatus.value = 0
|
||||
countSecond.value = 60
|
||||
veriBtnDisable.value = false
|
||||
clearInterval(phoneInterval)
|
||||
clearTimeout(phoneTimeOut)
|
||||
}, 60 * 1000)
|
||||
const phoneInterval = setInterval(() => {
|
||||
countSecond.value -= 1
|
||||
}, 1000)
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const logPhoneSub = (val: any) => {
|
||||
// 条件判断
|
||||
if (Number(verifyNum.value) !== Number(localStorage.getItem('veriPhoneCode'))
|
||||
|| phoneNumber.value === null // 手机号不能为空
|
||||
|| !localStorage.getItem('veriPhoneCode') // 本地存储为空
|
||||
|| phoneNumber.value.length !== 11 // 手机号长度不符
|
||||
) {
|
||||
showToast({
|
||||
message: '手机号或验证码不正确!',
|
||||
icon: 'fail',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
verifyNum.value = ''
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('修改成功!', val)
|
||||
msgInfo.telephone = val.phoneNumber
|
||||
// 短信登录接口
|
||||
logWithMsg({
|
||||
telephone: msgInfo.telephone
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
if (res.data.resMsg === 'success') {
|
||||
showToast({
|
||||
message: '登录成功!',
|
||||
icon: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
localStorage.setItem('token', res.data.obj)
|
||||
localStorage.setItem('avatarUrl', 'https://img.zcool.cn/community/0104c958b69c23a801219c77ba5da2.png?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100')
|
||||
localStorage.setItem('phoneNumber', msgInfo.telephone)
|
||||
localStorage.removeItem('veriPhoneCode')
|
||||
// 设置登录状态码持续时间为3h
|
||||
const overDate = new Date().getTime() - 8 * 60 * 60 * 1000 + 3 * 60 * 60 * 1000
|
||||
document.cookie = `loginStatus=0;expires=${new Date(overDate)}`
|
||||
router.replace({
|
||||
path: '/home'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
showFailToast('登录失败!')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.background {
|
||||
width: 10rem;
|
||||
height: 8rem;
|
||||
background: url('../../static/bg.jpg')
|
||||
100% no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
.section_1 {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.section_2 {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 0.1rem;
|
||||
top: 1.2rem;
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
}
|
||||
|
||||
.section_3 {
|
||||
background-color: rgba(255, 255, 255, 0.0624);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 6rem;
|
||||
top: 0.5rem;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
}
|
||||
.log-tit{
|
||||
width: 100%;
|
||||
padding-top: 4rem;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.log-form{
|
||||
width: 80%;
|
||||
height: 8rem;
|
||||
margin: 3.5rem auto;
|
||||
box-sizing: border-box;
|
||||
padding: 0.5rem;
|
||||
.user-taps{
|
||||
width: 100%;
|
||||
margin-top: 0.3rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 0 0.2rem;
|
||||
span{
|
||||
font-size: 14px;
|
||||
color: #49b3f2;
|
||||
}
|
||||
}
|
||||
.btn-area{
|
||||
width: 100%;
|
||||
margin-top: 0.6rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
:root:root{
|
||||
--van-field-placeholder-text-color: #000;
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<van-nav-bar
|
||||
title="消息通知"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
/>
|
||||
<!-- <div class="msgs-block" v-for="(item, index) in reportList" :key="index">
|
||||
<van-swipe-cell :before-close="onDelete" :name="item.name" @close="onClose">
|
||||
<van-cell :border="false" :title="item.title" value="内容">
|
||||
<van-badge dot position="left"></van-badge>
|
||||
</van-cell>
|
||||
<template #right>
|
||||
<van-button square type="danger" @click="toggleDelete" text="删除" />
|
||||
</template>
|
||||
</van-swipe-cell>
|
||||
</div> -->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
/* import { ref, onMounted } from 'vue'
|
||||
import { showConfirmDialog } from 'vant'; */
|
||||
|
||||
// 模拟数据
|
||||
/* const reportList = ref<any[]>([
|
||||
{
|
||||
name: 'report1',
|
||||
title: '体检报告已更新',
|
||||
},
|
||||
{
|
||||
name: 'report2',
|
||||
title: '职业健康待体检',
|
||||
},
|
||||
{
|
||||
name: 'report3',
|
||||
title: '这条是多余的',
|
||||
}
|
||||
]) */
|
||||
|
||||
const onClickLeft = () => {
|
||||
history.back()
|
||||
}
|
||||
|
||||
/* const toggleDelete = () => {
|
||||
} */
|
||||
|
||||
// 点击删除单个报告
|
||||
/* const onDelete = (e: any) => {
|
||||
const { position } = e
|
||||
// console.log(name)
|
||||
if (position === 'right') {
|
||||
showConfirmDialog({
|
||||
title: '确认删除吗?'
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const onClose = (e: any) => {
|
||||
console.log(e)
|
||||
} */
|
||||
|
||||
/* onMounted(() => {
|
||||
|
||||
}) */
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.msgs-block{
|
||||
width: 100%;
|
||||
margin: 0.05rem auto;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,365 @@
|
|||
<template>
|
||||
<van-nav-bar
|
||||
title="我的预约"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
/>
|
||||
<van-form @submit="myPreForm">
|
||||
<div class="my-form">
|
||||
<van-field
|
||||
v-model="examStatus"
|
||||
name="examStatus"
|
||||
is-link
|
||||
readonly
|
||||
placeholder="请选择体检状态"
|
||||
@click="showPicker = true"
|
||||
style="width: 80%;"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<van-popup v-model:show="showPicker" round position="bottom">
|
||||
<van-picker
|
||||
:columns="columns"
|
||||
@cancel="showPicker = false"
|
||||
@confirm="onConfirm"
|
||||
/>
|
||||
</van-popup>
|
||||
<van-button
|
||||
type="primary"
|
||||
native-type="submit"
|
||||
style="font-size: 16px;"
|
||||
>
|
||||
查询
|
||||
</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
<div class="tip">提示:向左滑动,取消预约</div>
|
||||
<!-- 待体检模块 -->
|
||||
<div
|
||||
class="my-pre-area"
|
||||
v-for="(item, index) in readyExamedList"
|
||||
:key="index"
|
||||
v-if="upperStatus === 4 || upperStatus === 2"
|
||||
@click="seeReport(item.id, item.combName)"
|
||||
>
|
||||
<van-swipe-cell style="width: 100%; height: 100%">
|
||||
<div class="swipe-container">
|
||||
<div class="lef">
|
||||
<img :src="readyExamImg" alt="">
|
||||
</div>
|
||||
<div class="rig">
|
||||
<h1>{{ item.hospitalName }}</h1>
|
||||
<h2>
|
||||
{{ item.combName }}
|
||||
<span v-if="readyExamedList[index].setMealPrice !== null">
|
||||
¥{{ readyExamedList[index].setMealPrice }}
|
||||
</span>
|
||||
</h2>
|
||||
<h3>预约时间:{{ item.phyAppontTime }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<template #right>
|
||||
<van-button
|
||||
style="height: 100%;"
|
||||
square
|
||||
type="danger"
|
||||
text="取消"
|
||||
@click="cancel"
|
||||
/>
|
||||
</template>
|
||||
</van-swipe-cell>
|
||||
</div>
|
||||
<!-- 已取消模块 -->
|
||||
<div
|
||||
class="my-pre-area"
|
||||
v-for="(item, index) in isCanceledList"
|
||||
:key="index"
|
||||
v-if="upperStatus === 4 || upperStatus === 1"
|
||||
@click="seeReport(item.id, item.combName)"
|
||||
>
|
||||
<div class="swipe-container">
|
||||
<div class="lef">
|
||||
<img :src="isCanceledImg" alt="">
|
||||
</div>
|
||||
<div class="rig">
|
||||
<h1>{{ item.hospitalName }}</h1>
|
||||
<h2>
|
||||
{{ item.combName }}
|
||||
<span v-if="isCanceledList[index].setMealPrice !== null">
|
||||
¥{{ isCanceledList[index].setMealPrice }}
|
||||
</span>
|
||||
</h2>
|
||||
<h3>预约时间:{{ item.phyAppontTime }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 已体检模块 -->
|
||||
<div
|
||||
class="my-pre-area"
|
||||
v-for="(item, index) in isExamedList"
|
||||
:key="index"
|
||||
v-if="upperStatus === 4 || upperStatus === 3"
|
||||
@click="seeReport(item.id, item.combName)"
|
||||
>
|
||||
<van-swipe-cell style="width: 100%; height: 100%">
|
||||
<div class="swipe-container">
|
||||
<div class="lef">
|
||||
<img :src="isExamedImg" alt="">
|
||||
</div>
|
||||
<div class="rig">
|
||||
<h1>{{ item.hospitalName }}</h1>
|
||||
<h2>
|
||||
{{ item.combName }}
|
||||
<span v-if="isExamedList[index].setMealPrice !== null">
|
||||
¥{{ isExamedList[index].setMealPrice }}
|
||||
</span>
|
||||
</h2>
|
||||
<h3>预约时间:{{ item.phyAppontTime }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</van-swipe-cell>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getPreOrderInfo, cancelPort } from '../../api/MyPreOrder'
|
||||
import { showConfirmDialog, showToast } from 'vant'
|
||||
import { useRouter } from 'vue-router'
|
||||
import isCanceledImg from '../../static/isCanceled.png'
|
||||
import readyExamImg from '../../static/readyExam.png'
|
||||
import isExamedImg from '../../static/isExamed.png'
|
||||
|
||||
const router = useRouter()
|
||||
const examStatus = ref<any>('')
|
||||
const showPicker = ref<boolean>(false)
|
||||
const examStatusNum = ref<number>(0)
|
||||
const orderList = ref<any[]>([])
|
||||
|
||||
// 定义列表的三种状态
|
||||
const isExamedList = ref<any[]>([])
|
||||
const readyExamedList = ref<any[]>([])
|
||||
const isCanceledList = ref<any[]>([])
|
||||
|
||||
// 定义三种套餐状态的id值
|
||||
const readyExamId = ref<any>('')
|
||||
const isExamedId = ref<any>('')
|
||||
const isCanceledId = ref<any>('')
|
||||
|
||||
// 定义显示状态码
|
||||
const upperStatus = ref<number>(4)
|
||||
|
||||
// 下拉框字段
|
||||
const columns = ref<any[]>([
|
||||
{ text: '全部', value: 4 },
|
||||
{ text: '已取消', value: 1 },
|
||||
{ text: '待体检', value: 2 },
|
||||
{ text: '已体检', value: 3 },
|
||||
])
|
||||
|
||||
// 点击返回上一页
|
||||
const onClickLeft = () => {
|
||||
history.back()
|
||||
}
|
||||
|
||||
// 表单详细信息,通过改变状态码控制各个模块的显示
|
||||
const myPreForm = (res: any) => {
|
||||
res.examStatus = examStatusNum.value
|
||||
if (res.examStatus === 1) {
|
||||
upperStatus.value = 1
|
||||
} else if (res.examStatus === 2) {
|
||||
upperStatus.value = 2
|
||||
} else if (res.examStatus === 3) {
|
||||
upperStatus.value = 3
|
||||
} else if (res.examStatus === 4) {
|
||||
upperStatus.value = 4
|
||||
}
|
||||
}
|
||||
|
||||
// 获取下周第一天
|
||||
// type:日期类型,start:开始时间,end:结束时间
|
||||
// dates:日期方向,默认0:本周,-1:上周,1:下周,2:下下周,以此类推
|
||||
/* const getNextWeekFirst = (type: any, dates = 0) => {
|
||||
let now = new Date();
|
||||
let nowTime = now.getTime();
|
||||
let day = now.getDay();
|
||||
let longTime = 24 * 60 * 60 * 1000;
|
||||
let n = longTime * 7 * (dates || 0);
|
||||
let dd
|
||||
if (type == "start") {
|
||||
dd = nowTime - (day - 1) * longTime + n;
|
||||
};
|
||||
if (type == "end") {
|
||||
dd = nowTime + (7 - day) * longTime + n;
|
||||
};
|
||||
let trueDD = new Date(dd);
|
||||
let y = trueDD.getFullYear();
|
||||
let m = trueDD.getMonth() + 1;
|
||||
let d = trueDD.getDate();
|
||||
let trueM = m < 10 ? "0" + m : m;
|
||||
let trueD = d < 10 ? "0" + d : d;
|
||||
let trueDay = y + "-" + trueM + "-" + trueD;
|
||||
return trueDay;
|
||||
}; */
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
showConfirmDialog({
|
||||
title: '确认取消体检吗?',
|
||||
width: '7rem'
|
||||
}).then(() => {
|
||||
cancelPort({
|
||||
token: localStorage.getItem('token'),
|
||||
cancelId: readyExamId.value
|
||||
}).then((res: any) => {
|
||||
console.log(res, '取消预约')
|
||||
showToast({
|
||||
message: '取消成功!',
|
||||
icon: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
history.go(0)
|
||||
}
|
||||
})
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}).catch(() => {
|
||||
// 取消确认框
|
||||
})
|
||||
}
|
||||
|
||||
// 查看不同预约单的内容,跳转页面
|
||||
const seeReport = (
|
||||
packageId: any,
|
||||
packageName: any
|
||||
) => {
|
||||
router.push({
|
||||
path: '/preOrderReceipt',
|
||||
query: {
|
||||
id: packageId,
|
||||
combName: packageName
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 弹出框确认
|
||||
const onConfirm = (res: any) => {
|
||||
showPicker.value = false
|
||||
examStatus.value = res.selectedOptions[0].text
|
||||
examStatusNum.value = res.selectedOptions[0].value
|
||||
}
|
||||
|
||||
// 请求体检预约信息,1取消 2待体检 3已体检
|
||||
const fetchPreOrderInfo = () => {
|
||||
getPreOrderInfo({
|
||||
token: localStorage.getItem('token')
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
if (res.data.obj === 'isnull') {
|
||||
showToast({
|
||||
message: '未找到预约记录!',
|
||||
icon: 'fail',
|
||||
duration: 1500
|
||||
})
|
||||
} else {
|
||||
console.log(res)
|
||||
orderList.value = res.data.obj
|
||||
for (let i = 0; i < res.data.obj.length; i++) {
|
||||
if (Number(res.data.obj[i].ifCancel) === 1) {
|
||||
isCanceledList.value.push(res.data.obj[i])
|
||||
isCanceledId.value = res.data.obj[i].id
|
||||
} else if (Number(res.data.obj[i].ifCancel) === 2) {
|
||||
readyExamedList.value.push(res.data.obj[i])
|
||||
readyExamId.value = res.data.obj[i].id
|
||||
} else if (Number(res.data.obj[i].ifCancel) === 3) {
|
||||
isExamedList.value.push(res.data.obj[i])
|
||||
isExamedId.value = res.data.obj[i].id
|
||||
}
|
||||
}
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchPreOrderInfo()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.my-form{
|
||||
width: 96%;
|
||||
height: 1rem;
|
||||
margin: 0.2rem auto;
|
||||
margin-bottom: 0.5rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.tip{
|
||||
width: 92%;
|
||||
font-size: 16px;
|
||||
box-sizing: border-box;
|
||||
padding: 0.1rem;
|
||||
margin: 0.3rem auto;
|
||||
color: #9c9898;
|
||||
}
|
||||
.my-pre-area{
|
||||
width: 94%;
|
||||
margin: 0.1rem auto;
|
||||
border-radius: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.swipe-container{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.lef{
|
||||
width: 24%;
|
||||
height: 2.4rem;
|
||||
img{
|
||||
position: absolute;
|
||||
top: -51%;
|
||||
left: -43%;
|
||||
width: 150%;
|
||||
height: 150%;
|
||||
}
|
||||
}
|
||||
.rig{
|
||||
width: 76%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding: 0.3rem 0.3rem 0.3rem 0;
|
||||
margin-right: 0;
|
||||
h1{
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
h2{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.3rem;
|
||||
span{
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
h3{
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/* :root:root{
|
||||
--van-dialog-width: 500px
|
||||
} */
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<van-nav-bar
|
||||
title="个人信息"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
/>
|
||||
<div class="info-area">
|
||||
<div class="name">
|
||||
姓名
|
||||
<span>{{ phyName }}</span>
|
||||
</div>
|
||||
<div>
|
||||
身份证号
|
||||
<span>{{ idcard }}</span>
|
||||
</div>
|
||||
<div>
|
||||
年龄
|
||||
<span>{{ age }}</span>
|
||||
</div>
|
||||
<div>
|
||||
性别
|
||||
<span>{{ sex }}</span>
|
||||
</div>
|
||||
<div>
|
||||
联系方式
|
||||
<span>{{ telepNumber }}</span>
|
||||
</div>
|
||||
<div>
|
||||
部门
|
||||
<span>{{ departName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { onMounted } from 'vue';
|
||||
import './scss/index.scss'
|
||||
|
||||
// 设置用户信息
|
||||
const phyName = localStorage.getItem('phyName')
|
||||
const idcard = localStorage.getItem('idcard')
|
||||
const age = localStorage.getItem('age')
|
||||
const sex = localStorage.getItem('sex')
|
||||
const telepNumber = localStorage.getItem('telepNumber')
|
||||
const departName = localStorage.getItem('departName')
|
||||
|
||||
const onClickLeft = () => {
|
||||
history.back()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.status-bar{
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
}
|
||||
.info-area{
|
||||
width: 96%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 1.5rem auto;
|
||||
font-size: 16px;
|
||||
div{
|
||||
width: 100%;
|
||||
height: 2rem;
|
||||
font-size: 20px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 0.08rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding: 0.1rem 0.4rem;
|
||||
}
|
||||
/* .avatar{
|
||||
height: 1.5rem;
|
||||
margin-bottom: 0.05rem;
|
||||
}
|
||||
.rig-area{
|
||||
width: 20%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-right: 0;
|
||||
div{
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.rig-area2{
|
||||
width: 18%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-right: 0;
|
||||
} */
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
:root:root{
|
||||
--van-nav-bar-background: #f8f8f8;
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<van-nav-bar
|
||||
title="体检预约单"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
/>
|
||||
<div class="warn" v-if="showStatus === 1">暂无体检的相关信息</div>
|
||||
<div class="receipt-area" v-if="showStatus === 0">
|
||||
<h1>体检单据</h1>
|
||||
<h2>套餐名称:</h2>
|
||||
<span>{{ packageName }}</span>
|
||||
<h2>体检项目:</h2>
|
||||
<span v-for="(item, index) in receiptInfo" :key="index">
|
||||
{{ item.mealName + ' ' }}
|
||||
</span>
|
||||
<h2>体检内容:</h2>
|
||||
<div class="meal-content" v-for="(item, index) in receiptInfo" :key="index">
|
||||
<!-- <span>{{ item.mealContent }}</span>
|
||||
<span>{{ item.mealPrice }}元</span> -->
|
||||
<div class="content">{{ item.mealName }}:{{ item.mealContent }}</div>
|
||||
<div class="meal-price">{{ item.mealPrice }}元</div>
|
||||
</div>
|
||||
<h2 style="color: red;">体检总价:{{ totalPrice }}元</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { seePackage } from '../../api/PreOrderReceipt'
|
||||
|
||||
const route = useRoute()
|
||||
const packageId = ref<any>('')
|
||||
const packageName = ref<any>('')
|
||||
const receiptInfo = ref<any[]>([])
|
||||
const totalPrice = ref<number>(0)
|
||||
const showStatus = ref<number>(0)
|
||||
|
||||
// 返回上一页
|
||||
const onClickLeft = () => {
|
||||
history.back()
|
||||
}
|
||||
|
||||
// 体检单据详情
|
||||
const checkPackage = () => {
|
||||
seePackage({
|
||||
cancelId: packageId.value,
|
||||
token: localStorage.getItem('token')
|
||||
}).then((res: any) => {
|
||||
console.log(res)
|
||||
if (res.data.obj.length === 0) {
|
||||
showStatus.value === 1
|
||||
} else {
|
||||
receiptInfo.value = res.data.obj
|
||||
for (let i = 0; i < res.data.obj.length; i++) {
|
||||
totalPrice.value += Number(res.data.obj[i].mealPrice)
|
||||
}
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log(route.query.id, route.query.combName)
|
||||
packageId.value = route.query.id
|
||||
packageName.value = route.query.combName
|
||||
checkPackage()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.warn{
|
||||
width: 85%;
|
||||
margin: 1rem auto;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 0.4rem;
|
||||
border-radius: 0.2rem;
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
.receipt-area{
|
||||
width: 85%;
|
||||
margin: 1.5rem auto;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 0.4rem;
|
||||
border-radius: 0.2rem;
|
||||
.meal-content{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
border-bottom: 1px dashed black;
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
h1{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 26px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
h2{
|
||||
font-size: 20px;
|
||||
margin: 0.4rem 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
.content{
|
||||
width: 80%;
|
||||
font-size: 18px;
|
||||
line-height: 26px;
|
||||
}
|
||||
span{
|
||||
font-size: 18px;
|
||||
line-height: 26px;
|
||||
}
|
||||
.meal-price{
|
||||
font-size: 18px;
|
||||
text-align: right;
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<van-nav-bar
|
||||
title="体检预约"
|
||||
/>
|
||||
<div class="succeedImg">
|
||||
<img :src="succeedImg" alt="">
|
||||
</div>
|
||||
<h2 class="tit">恭喜您,预约成功!</h2>
|
||||
<div class="btns-area">
|
||||
<van-button
|
||||
type="primary"
|
||||
style="width: 45%; margin-bottom: 0.3rem; border-radius: 1rem; font-size: 18px; background-color: #fff; border-color: #1989fa; color: #1989fa;"
|
||||
@click="jumpHome"
|
||||
>返回首页
|
||||
</van-button>
|
||||
<van-button
|
||||
type="primary"
|
||||
style="width: 45%; border-radius: 1rem; font-size: 18px;"
|
||||
@click="jumpReceipt"
|
||||
>查看预约
|
||||
</van-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import succeedImg from '../../static/preOrderSucceed.png'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const packageId = ref<any>('')
|
||||
|
||||
// 返回首页
|
||||
const jumpHome = () => {
|
||||
router.replace({
|
||||
path: '/home'
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转体检预约单页面
|
||||
const jumpReceipt = () => {
|
||||
router.push({
|
||||
path: '/myPreOrder',
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log(route.query.id)
|
||||
packageId.value = route.query.id
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.succeedImg{
|
||||
width: 80%;
|
||||
margin: 5rem auto;
|
||||
margin-bottom: 0.5rem;
|
||||
img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.tit{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.btns-area{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 3rem auto;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="bg"></div>
|
||||
<div class="avatar-area">
|
||||
<!-- 选择头像 -->
|
||||
<van-uploader
|
||||
:after-read="afterRead"
|
||||
:max-count="1"
|
||||
v-model="fileList"
|
||||
:reupload="true"
|
||||
:deletable="false"
|
||||
readonly
|
||||
/>
|
||||
</div>
|
||||
<h2 class="user-name">{{ userInfo.phyName }}</h2>
|
||||
<div class="user-tap">
|
||||
<!-- <div class="warn-area">
|
||||
<van-notice-bar
|
||||
style="width: 100%; border-radius: 0.1rem;"
|
||||
left-icon="volume-o"
|
||||
scrollable
|
||||
speed="100"
|
||||
text="您好,您在2023年5月1日的体检中有异常项,具体请查看体检报告..."
|
||||
/>
|
||||
</div> -->
|
||||
<div class="taps">
|
||||
<div @click="jumpPersonInfo()">
|
||||
<div>
|
||||
<img src="../../static/perInfo.png" alt="">
|
||||
</div>
|
||||
<span>个人信息</span>
|
||||
</div>
|
||||
<div @click="jumpMsgNotice()">
|
||||
<div>
|
||||
<img src="../../static/notice.png" alt="">
|
||||
</div>
|
||||
<span>消息通知</span>
|
||||
</div>
|
||||
<div @click="exitLogin()">
|
||||
<div>
|
||||
<img src="../../static/exit.png" alt="">
|
||||
</div>
|
||||
<span>退出登录</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<TabBar/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import './scss/index.scss'
|
||||
import TabBar from '../../components/TabBar.vue';
|
||||
import { getUserInfo } from '../../api/user.js'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showConfirmDialog } from 'vant';
|
||||
|
||||
const router = useRouter()
|
||||
const userInfo = ref<any>({})
|
||||
// 设置默认头像
|
||||
const fileList = ref<any[]>([
|
||||
{ url: localStorage.getItem('avatarUrl') }
|
||||
])
|
||||
const afterRead = (file: any) => {
|
||||
console.log(file)
|
||||
}
|
||||
|
||||
// 跳转到个人信息
|
||||
const jumpPersonInfo = () => {
|
||||
router.push({
|
||||
path: '/personalInfo'
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转到消息通知
|
||||
const jumpMsgNotice = () => {
|
||||
router.push({
|
||||
path: '/msgNotice'
|
||||
})
|
||||
}
|
||||
|
||||
// 退出登录
|
||||
const exitLogin = () => {
|
||||
showConfirmDialog({
|
||||
title: '确认退出登录吗?',
|
||||
width: '7rem'
|
||||
}).then(() => {
|
||||
// confirm
|
||||
localStorage.removeItem('token')
|
||||
// 退出登录时销毁cookie并刷新页面
|
||||
const delCookie = new Date().getTime() - 8 * 60 * 60 * 1000
|
||||
document.cookie = `loginStatus=0;expires=${new Date(delCookie)}`
|
||||
history.go(0)
|
||||
}).catch(() => {
|
||||
// cancel
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getUserInfo({
|
||||
token: localStorage.getItem('token')
|
||||
}).then((res: any) => {
|
||||
userInfo.value = res.data.obj[0]
|
||||
const data = res.data.obj[0]
|
||||
localStorage.setItem('phyName', data.phyName)
|
||||
localStorage.setItem('idcard', data.idcard)
|
||||
localStorage.setItem('age', data.age)
|
||||
localStorage.setItem('telepNumber', data.telepNumber)
|
||||
localStorage.setItem('departName', data.departName)
|
||||
if (Number(data.sex) === 1) {
|
||||
localStorage.setItem('sex', '女')
|
||||
} else if (Number(data.sex) === 0) {
|
||||
localStorage.setItem('sex', '男')
|
||||
}
|
||||
console.log(userInfo.value)
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.bg{
|
||||
width: 10rem;
|
||||
height: 8rem;
|
||||
background-color: #008080;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.avatar-area{
|
||||
width: 100%;
|
||||
height: 6rem;
|
||||
padding-top: 2rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
.user-name{
|
||||
width: 100%;
|
||||
margin-top: 0.6rem;
|
||||
height: 0.5rem;
|
||||
display: flex;
|
||||
color: #fff;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
.user-tap{
|
||||
width: 96%;
|
||||
background-color: #fff;
|
||||
margin: 0.4rem auto;
|
||||
box-sizing: border-box;
|
||||
padding: 0.2rem;
|
||||
border-radius: 0.1rem;
|
||||
.warn-area{
|
||||
width: 100%;
|
||||
height: 1rem;
|
||||
line-height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.img-area{
|
||||
width: 12%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
img{
|
||||
margin: auto;
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
}
|
||||
}
|
||||
span{
|
||||
padding-left: 0.15rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
.taps{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 0.1rem;
|
||||
div{
|
||||
width: 100%;
|
||||
height: 1rem;
|
||||
margin: 0.1rem;
|
||||
border-bottom: 1px solid #f2f2f2;
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
div{
|
||||
width: 12%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
border: none;
|
||||
img{
|
||||
margin: auto;
|
||||
width: 50%;
|
||||
height: 60%;
|
||||
}
|
||||
}
|
||||
span{
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
div:nth-child(3){
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
:root:root{
|
||||
--van-uploader-size: 4rem;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
/// <reference types="vite/client" />
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "preserve",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/plugins/mitt.js", "src/plugins/mitt.js", "src/plugins/mitt.js", "src/plugins/mitt.js"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import postCssPxToRem from 'postcss-pxtorem'
|
||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { VantResolver } from 'unplugin-vue-components/resolvers'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
base: './',
|
||||
publicDir: 'assets',
|
||||
plugins: [vue(), vueSetupExtend(), Components({
|
||||
resolvers: [VantResolver()],
|
||||
})],
|
||||
css: {
|
||||
postcss: {
|
||||
plugins: [
|
||||
postCssPxToRem({
|
||||
rootValue: 40,
|
||||
propList: ['*']
|
||||
})
|
||||
]
|
||||
}
|
||||
},
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 1234,
|
||||
open: true,
|
||||
proxy: {
|
||||
'/AppPeaManager': {
|
||||
target: 'http://192.168.0.14:18087',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/AppPeaManager/, '/AppPeaManager')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||