1
0
Selaa lähdekoodia

feat:新增小程序医生端

lsw 8 kuukautta sitten
vanhempi
commit
d251e989ef

+ 1 - 1
app/App.vue

@@ -30,7 +30,7 @@ button::after {
 /**挂载iconfont字体图标*/
 @font-face {
 	font-family: 'iconfont';
-	src: url('https://at.alicdn.com/t/c/font_4620946_77k3uh0ak7p.ttf?t=1722848437021') format('truetype');
+	src: url('https://at.alicdn.com/t/c/font_4620946_dx1v5gcq327.ttf?t=1723528417636') format('truetype');
 	/* src: url('~@/static/font/iconfont.ttf') format('truetype'); */
 }
 .icon {

+ 0 - 7
app/common/common.scss

@@ -1,10 +1,3 @@
-.bg {
-	margin-top: -46px;
-	margin-left: -10px;
-	image {
-		width: 110%;
-	}
-}
 .main {
 	padding: 15px;
 	.form {

+ 7 - 0
app/pages.json

@@ -137,6 +137,13 @@
 			{
 				"navigationBarTitleText" : "复诊提醒"
 			}
+		},
+		{
+			"path" : "pages/user/loginDoctor",
+			"style" : 
+			{
+				"navigationBarTitleText" : "医生登录"
+			}
 		}
 	],
 	"tabBar": {

+ 1 - 1
app/pages/other/setting.vue

@@ -17,7 +17,7 @@ export default {
 				success: (res) => {
 					if (res.confirm) {
 						this.http.request({
-							url: '/app/user/exit',
+							url: this.getUser().doctor ? '/logout' : '/app/user/exit',
 							success: (res) => {
 								uni.removeStorageSync('user');
 								uni.navigateBack();

+ 54 - 28
app/pages/user/index.vue

@@ -1,40 +1,67 @@
 <template>
 	<view class="main">
-		<view class="user" @click="go('/pages/user/bind/index')">
+		<view class="user">
 			<image :src="user.avatar ? ip + user.avatar : '../../static/favicon.png'" class="head"></image>
-			<view class="con" v-if="user.id">
-				<view class="nickName">
-					{{ user.patientName ? user.patientName : '还未绑定就诊人' }}
-					<text class="icon" v-if="user.bindUserList.length > 1" @click.stop="show = true">&#xe6a7;切换就诊人</text>
+			<view class="con" v-if="user.id || user.token">
+				<view v-if="user.doctor" @click="go('/pages/user/info')">
+					<view class="nickName">{{ user.nickName }}</view>
+					<view class="welcome">{{ user.dept.deptName || '欢迎使用岑溪人民医院小程序' }}</view>
+				</view>
+				<view v-else @click="go('/pages/user/bind/index')">
+					<view class="nickName">
+						<text>{{ user.patientName ? user.patientName : '还未绑定就诊人' }}</text>
+						<text class="icon" v-if="user.bindUserList" @click.stop="show = true">&#xe6a7;切换就诊人</text>
+					</view>
+					<view class="welcome">欢迎使用岑溪人民医院小程序</view>
 				</view>
-				<view class="welcome">欢迎使用岑溪人民医院小程序</view>
 			</view>
-			<view class="con" v-else>
+			<view class="con" v-else @click="go('/pages/user/info')">
 				<view class="nickName">你还没登录</view>
 				<view class="welcome">欢迎使用岑溪人民医院小程序</view>
 			</view>
 			<view class="icon edit">&#xe62b;</view>
 		</view>
 		<view class="cmd">
-			<view class="s_item" @click="go('/pages/follow/remind')">
-				<text class="icon ic" style="color: #03a9f4">&#xe6a3;</text>
-				<text class="title">复诊提醒</text>
-				<text class="icon arrow">&#xe62b;</text>
-			</view>
-			<view class="s_item" @click="go('/pages/follow/index')">
-				<text class="icon ic" style="color: #607d8b">&#xe60b;</text>
-				<text class="title">我的回访</text>
-				<text class="icon arrow">&#xe62b;</text>
-			</view>
-			<view class="s_item" @click="go('/pages/visit/index')">
-				<text class="icon ic" style="color: #03a9f4">&#xe685;</text>
-				<text class="title">就诊记录</text>
-				<text class="icon arrow">&#xe62b;</text>
+			<!--医生菜单-->
+			<view v-if="user.doctor">
+				<view class="s_item" @click="go('/pages/follow/remind')">
+					<text class="icon ic" style="color: #03a9f4">&#xe6a3;</text>
+					<text class="title">复诊提醒</text>
+					<text class="icon arrow">&#xe62b;</text>
+				</view>
+				<view class="s_item" @click="go('/pages/follow/index')">
+					<text class="icon ic" style="color: #607d8b">&#xe60b;</text>
+					<text class="title">回访记录</text>
+					<text class="icon arrow">&#xe62b;</text>
+				</view>
+				<view class="s_item" @click="go('/pages/follow/index')">
+					<text class="icon ic" style="color: #607d8b">&#xe60b;</text>
+					<text class="title">我的知识库</text>
+					<text class="icon arrow">&#xe62b;</text>
+				</view>
 			</view>
-			<view class="s_item" @click="go('/pages/detection/index')">
-				<text class="icon ic" style="color: #ff9800">&#xe63a;</text>
-				<text class="title">检测报告</text>
-				<text class="icon arrow">&#xe62b;</text>
+			<!--患者菜单-->
+			<view v-else>
+				<view class="s_item" @click="go('/pages/follow/remind')">
+					<text class="icon ic" style="color: #03a9f4">&#xe6a3;</text>
+					<text class="title">复诊提醒</text>
+					<text class="icon arrow">&#xe62b;</text>
+				</view>
+				<view class="s_item" @click="go('/pages/follow/index')">
+					<text class="icon ic" style="color: #607d8b">&#xe60b;</text>
+					<text class="title">我的回访</text>
+					<text class="icon arrow">&#xe62b;</text>
+				</view>
+				<view class="s_item" @click="go('/pages/visit/index')">
+					<text class="icon ic" style="color: #03a9f4">&#xe685;</text>
+					<text class="title">就诊记录</text>
+					<text class="icon arrow">&#xe62b;</text>
+				</view>
+				<view class="s_item" @click="go('/pages/detection/index')">
+					<text class="icon ic" style="color: #ff9800">&#xe63a;</text>
+					<text class="title">检测报告</text>
+					<text class="icon arrow">&#xe62b;</text>
+				</view>
 			</view>
 			<button class="s_item" open-type="share" @click="go('/pages/help/my')" hover-class="none">
 				<text class="icon ic" style="color: #f44336">&#xe7c4;</text>
@@ -69,10 +96,9 @@ export default {
 			token: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImI3ZjVlNDYwLThjY2YtNDkxZi1hNTBjLWI1MjQzNDUzNjFkZiJ9.VTDBJ3929h8qGWMZFkfq-dQAkWOptIfQk7f5CaIahgltFV4QACgf3QBabcswisGTMQZaJMkxt5uCzjv3AkN48w'
 		};
 		uni.setStorageSync('user', this.user); */
-		if (this.hasLogin()) {
+		this.user = this.getUser();
+		if (this.hasLogin() && !this.user.doctor) {
 			this.getUserInfo();
-		} else {
-			this.user = {};
 		}
 	},
 	methods: {

+ 14 - 1
app/pages/user/login.vue

@@ -9,7 +9,14 @@
 			<text>和</text>
 			<text class="a" @click="go('/pages/other/agreement?title=隐私政策')">《隐私政策》</text>
 		</view>
-		<button class="btn" @click="getUserProfile()" :disabled="disabled">微信一键登录</button>
+		<button class="btn" @click="getUserProfile()" :disabled="disabled">
+			<text class="icon">&#xe62d;</text>
+			<text>用户登录</text>
+		</button>
+		<button class="btn" style="background-color: #607d8b" @click="go('/pages/user/loginDoctor')">
+			<text class="icon">&#xe6a3;</text>
+			<text>医生登录</text>
+		</button>
 	</view>
 </template>
 <script>
@@ -72,9 +79,15 @@ export default {
 <style lang="scss">
 .bg {
 	padding: 30px;
+	margin-top: -20px;
 	.pic {
 		width: 100%;
 		border-radius: 5px;
 	}
+	.btn {
+		.icon {
+			padding-right: 5px;
+		}
+	}
 }
 </style>

+ 197 - 0
app/pages/user/loginDoctor.vue

@@ -0,0 +1,197 @@
+<template>
+	<view>
+		<view class="app_top">
+			<image src="https://axure-file.lanhuapp.com/md5__f93627286149f825890eb821ab5d5abb.png" mode="widthFix" class="img"></image>
+		</view>
+		<view class="dk">
+			<view class="tx">
+				<image src="../../static/favicon.png" mode="aspectFill"></image>
+			</view>
+			<view class="unit">岑溪人民医院随访系统</view>
+			<view class="bg">
+				<text class="icon">&#xe616;</text>
+				<input v-model="item.username" placeholder="请输入账号" class="input" />
+			</view>
+			<view class="bg">
+				<text class="icon">&#xe62a;</text>
+				<input :password="show" v-model="item.password" placeholder="请输入密码" class="input" />
+				<view class="label"><view class="icon" :class="{ active: !show }" @click="show = !show">&#xe6ef;</view></view>
+			</view>
+			<view class="bg">
+				<text class="icon">&#xe613;</text>
+				<input type="number" v-model="item.code" placeholder="请输入验证码" class="input" />
+				<view class="label" @click="getCaptcha()"><image :src="img" mode="widthFix" class="captcha"></image></view>
+			</view>
+			<button class="btn" @click="login()">立即登录</button>
+			<view class="fg" @click="forget()">忘记密码?</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			img: '',
+			item: { username: '', password: '' },
+			show: true
+		};
+	},
+	onLoad(e) {
+		this.getCaptcha();
+		if (this.hasLogin()) {
+			uni.redirectTo({
+				url: '/pages/index/index'
+			});
+		}
+	},
+	methods: {
+		back() {
+			uni.navigateBack();
+		},
+		//图形验证码
+		getCaptcha() {
+			this.http.request({
+				url: '/app/common/captcha',
+				success: (res) => {
+					this.img = res.data.data.img;
+					this.item.uuid = res.data.data.uuid;
+				}
+			});
+		},
+		//登录
+		login() {
+			let rule = [
+				{ name: 'username', checkType: 'notnull', errorMsg: '请输入账号' },
+				{ name: 'password', checkType: 'notnull', errorMsg: '请输入密码' }
+			];
+			if (!this.verify.check(this.item, rule)) {
+				uni.showModal({ content: this.verify.error, showCancel: false });
+				return false;
+			}
+			this.http.request({
+				url: '/login',
+				data: this.item,
+				method: 'POST',
+				success: (res) => {
+					let user = res.data.user.user;
+					user.doctor = true;
+					user.token = res.data.token;
+					uni.setStorageSync('user', user);
+					uni.showToast({ title: '登录成功' });
+					setTimeout(() => {
+						uni.navigateBack({
+							delta: 2
+						});
+					}, 1000);
+				},
+				fail: (res) => {
+					this.getCaptcha();
+				}
+			});
+		},
+		forget() {
+			uni.showModal({ title: '提示', content: '如忘记密码,请联系管理员重置密码', showCancel: false });
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.app_top {
+	display: block;
+	position: relative;
+	.icon {
+		position: absolute;
+		color: white;
+		z-index: 2;
+		top: 18%;
+		left: 13px;
+		font-size: 25px;
+	}
+	.img {
+		width: 100%;
+	}
+}
+.dk {
+	position: relative;
+	margin: 0 auto;
+	padding: 20px;
+	width: 75%;
+	background-color: white;
+	border-radius: 10px;
+	margin-top: -130px;
+	box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+	.tx {
+		text-align: center;
+		position: relative;
+		margin-top: -70px;
+		image {
+			width: 80px;
+			height: 80px;
+			border-radius: 50%;
+			border: 2px solid white;
+		}
+	}
+	.unit {
+		text-align: center;
+		margin-bottom: 25px;
+		font-size: 20px;
+		color: #545555;
+		margin-top: 10px;
+		font-weight: bold;
+	}
+	.bg {
+		overflow: hidden;
+		margin-bottom: 15px;
+		border-radius: 5px;
+		border: 1px solid #cdcdcd;
+		.icon {
+			float: left;
+			padding-left: 10px;
+			margin-top: 12px;
+			font-size: 18px;
+			color: $font-c;
+		}
+		.input {
+			height: 45px;
+			text-align: left;
+			padding-left: 15px;
+			font-size: 14px;
+			color: $font-c;
+			width: 60%;
+		}
+		.label {
+			float: right;
+			margin-top: -31px;
+			padding-right: 15px;
+			font-size: 14px;
+			color: $main-color;
+			cursor: pointer;
+			.icon {
+				color: darkgray;
+				font-size: 22px;
+				margin-top: -4px;
+				&.active {
+					color: $main-color;
+				}
+			}
+			.captcha {
+				width: 90px;
+				height: 34px;
+				margin-top: -8px;
+				border-radius: 3px;
+			}
+		}
+	}
+	.fg {
+		text-align: center;
+		margin-top: 30px;
+		color: #989898;
+		font-size: 14px;
+	}
+}
+.btn {
+	margin-top: 30px;
+}
+</style>

+ 30 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/api/Api_CommonController.java

@@ -6,18 +6,25 @@ import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.SysDictData;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.sign.Base64;
+import com.ruoyi.common.utils.uuid.IdUtils;
 import com.ruoyi.system.service.ISysDictTypeService;
 import com.ruoyi.web.work.api.config.BaseController;
 import com.ruoyi.web.work.domain.Introduction;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.FastByteArrayOutputStream;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 @RestController
 @RequestMapping("/app/common")
@@ -58,5 +65,28 @@ public class Api_CommonController extends BaseController {
         }
         return AjaxResult.error();
     }
+
+    //图形验证码
+    @GetMapping("/captcha")
+    public AjaxResult captcha() {
+        String uuid = IdUtils.simpleUUID();
+        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
+        // 生成验证码
+        String capText = captchaProducerMath.createText();
+        String capStr = capText.substring(0, capText.lastIndexOf("@"));
+        String code = capText.substring(capText.lastIndexOf("@") + 1);
+        BufferedImage image = captchaProducerMath.createImage(capStr);
+        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
+        try {
+            ImageIO.write(image, "jpg", os);
+            redisCache.setCacheObject(verifyKey, code, 2, TimeUnit.MINUTES);
+        } catch (IOException e) {
+            return AjaxResult.error(e.getMessage());
+        }
+        AjaxResult ajax = AjaxResult.success();
+        ajax.put("uuid", uuid);
+        ajax.put("img", "data:image/gif;base64," + Base64.encode(os.toByteArray()));
+        return AjaxResult.success(ajax);
+    }
 }
 

+ 1 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/api/config/InterceptorConfig.java

@@ -26,6 +26,7 @@ public class InterceptorConfig implements WebMvcConfigurer {
         registration.excludePathPatterns("/app/doctor/**"); //排除
         registration.excludePathPatterns("/app/department/**"); //排除
         registration.excludePathPatterns("/app/common/type/*"); //排除
+        registration.excludePathPatterns("/app/common/captcha"); //排除
         registration.excludePathPatterns("/app/common/introduction/*"); //排除
 
 

+ 11 - 11
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java

@@ -1,18 +1,8 @@
 package com.ruoyi.framework.web.service;
 
-import javax.annotation.Resource;
-
-import com.qiniu.util.Auth;
-import com.ruoyi.common.core.domain.AjaxResult;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.env.Environment;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.stereotype.Component;
 import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.core.redis.RedisCache;
@@ -30,6 +20,15 @@ import com.ruoyi.framework.manager.factory.AsyncFactory;
 import com.ruoyi.framework.security.context.AuthenticationContextHolder;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
 
 /**
  * 登录校验方法
@@ -96,6 +95,7 @@ public class SysLoginService {
         // 生成token
         String token = tokenService.createToken(loginUser);
         result.put(Constants.TOKEN, token);
+        result.put("user",loginUser);
         return result;
     }