1
0
Jelajahi Sumber

feat:新增小程序医生端

lsw 8 bulan lalu
induk
melakukan
bd497446c9

+ 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_dx1v5gcq327.ttf?t=1723528417636') format('truetype');
+	src: url('https://at.alicdn.com/t/c/font_4620946_xu7r79yyesr.ttf?t=1723535617548') format('truetype');
 	/* src: url('~@/static/font/iconfont.ttf') format('truetype'); */
 }
 .icon {

+ 3 - 0
app/common/common.scss

@@ -369,4 +369,7 @@
     border-color: transparent transparent white transparent;
     left: -10px;
   }
+}
+.ql-editor.ql-blank:before {
+	font-style: normal !important;
 }

+ 169 - 0
app/components/leditor/leditor.vue

@@ -0,0 +1,169 @@
+<template>
+	<view class="editor">
+		<view class="cons">
+			<view v-if="read">
+				<u-parse :content="value"></u-parse>
+			</view>
+			<view v-else>
+				<view class="toolbar" @tap="format">
+					<view :class="formats.bold ? 'ql-active' : ''" class="icon" data-name="bold" title="加粗">&#xec84;</view>
+					<view :class="formats.align === 'left' ? 'ql-active' : ''" class="icon" data-name="align" data-value="left" title="左对齐">&#xec86;</view>
+					<view :class="formats.align === 'center' ? 'ql-active' : ''" class="icon" data-name="align" data-value="center" title="居中对齐">&#xec80;</view>
+					<view :class="formats.align === 'right' ? 'ql-active' : ''" class="icon" data-name="align" data-value="right" title="右对齐">&#xec82;</view>
+					<view :class="formats.align === 'justify' ? 'ql-active' : ''" class="icon" data-name="align" data-value="justify" title="两端对齐">&#xec87;</view>
+					<view :class="formats.lineHeight ? 'ql-active' : ''" class="icon" data-name="lineHeight" data-value="2" title="行距">&#xe7f8;</view>
+					<view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="icon" data-name="list" data-value="ordered" title="编号">&#xe7f5;</view>
+					<!-- <view class="icon" title="分割线" @tap="insertDivider">&#xe620;</view> -->
+					<view class="icon" @tap="insertDate">&#xe8b8;</view>
+					<view class="icon" @tap="insertImage" title="插入图片">&#xe64a;</view>
+					<view class="icon" @tap="clear" title="清空内容">&#xe8b6;</view>
+				</view>
+				<editor id="editor" class="ql-container" :placeholder="placeholder" showImgSize showImgToolbar showImgResize @input="editorChange" @statuschange="onStatusChange" :read-only="false" @ready="onEditorReady"></editor>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'leditor',
+	props: {
+		value: {
+			default: ''
+		},
+		read: {
+			type: Boolean,
+			default: false
+		},
+		placeholder: {
+			type: String,
+			default: '输入内容'
+		}
+	},
+	data() {
+		return {
+			ip: this.http.ip,
+			ready: false,
+			formats: {}
+		};
+	},
+	methods: {
+		//初始化
+		onEditorReady() {
+			uni.createSelectorQuery()
+				.in(this)
+				.select('#editor')
+				.context((res) => {
+					this.editorCtx = res.context;
+				})
+				.exec();
+		},
+		//设置编辑器内容
+		setContents() {
+			if (!this.read) {
+				setTimeout(() => {
+					this.editorCtx.setContents({
+						html: this.value
+					});
+				}, 3000);
+			}
+		},
+		//修改样式
+		format(e) {
+			let { name, value } = e.target.dataset;
+			if (!name) return;
+			this.editorCtx.format(name, value);
+		},
+		//插入分割线
+		insertDivider() {
+			this.editorCtx.insertDivider();
+		},
+		//插入日期
+		insertDate() {
+			const date = new Date();
+			const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
+			this.editorCtx.insertText({
+				text: formatDate
+			});
+		},
+		//改变编辑器内样式
+		onStatusChange(e) {
+			const formats = e.detail;
+			this.formats = formats;
+		},
+		//清除全部内容
+		clear() {
+			this.editorCtx.clear();
+		},
+		//内容改变时
+		editorChange: function (e) {
+			this.$emit('input', e.detail.html);
+		},
+		//插入图片
+		insertImage() {
+			uni.chooseImage({
+				count: 9, //默认9
+				sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
+				sourceType: ['album'], //从相册选择
+				success: (chooseImageRes) => {
+					chooseImageRes.tempFilePaths.forEach((item) => {
+						uni.showLoading({ title: '正在上传图片...', mask: true });
+						uni.uploadFile({
+							url: this.ip + '/common/upload',
+							filePath: item,
+							name: 'file',
+							header: { Authorization: this.getUser().token },
+							success: (res) => {
+								uni.hideLoading();
+								let result = JSON.parse(res.data);
+								if (result.code === 200) {
+									this.editorCtx.insertImage({
+										src: this.ip + result.fileName,
+										alt: '图像'
+									});
+								} else {
+									uni.showModal({ content: result.msg, showCancel: false });
+								}
+							}
+						});
+					});
+				}
+			});
+		}
+	}
+};
+</script>
+<style lang="scss">
+.editor {
+	padding: 0px 0px 0px 0px;
+	.cons {
+		width: 100%;
+		.toolbar {
+			border-bottom: 0px;
+			background-color: whitesmoke;
+			border-radius: 0px 0px 0px 0px;
+			.icon {
+				display: inline-block;
+				cursor: pointer;
+				font-size: 20px;
+				padding: 6px 6px;
+				width: 23px;
+				height: 23px;
+			}
+			.ql-active {
+				color: #06c;
+			}
+		}
+		.ql-container {
+			padding: 10px;
+			height: 320px;
+			font-size: 15px;
+			background-color: white;
+			border-bottom: 1px solid #eeeeee;
+			image {
+				width: 100%;
+			}
+		}
+	}
+}
+</style>

+ 1 - 1
app/manifest.json

@@ -98,7 +98,7 @@
     "quickapp" : {},
     /* 小程序特有相关 */
     "mp-weixin" : {
-        "appid" : "wx25d3f9356f5fdf80",
+        "appid" : "wxff094b320041c1e8",
         "setting" : {
             "urlCheck" : false,
             "minified" : true

+ 14 - 0
app/pages.json

@@ -144,6 +144,20 @@
 			{
 				"navigationBarTitleText" : "医生登录"
 			}
+		},
+		{
+			"path" : "pages/knowledge/doctor/index",
+			"style" : 
+			{
+				"navigationBarTitleText" : "我的知识库"
+			}
+		},
+		{
+			"path" : "pages/knowledge/doctor/add",
+			"style" : 
+			{
+				"navigationBarTitleText" : "新增知识库"
+			}
 		}
 	],
 	"tabBar": {

+ 97 - 0
app/pages/knowledge/doctor/add.vue

@@ -0,0 +1,97 @@
+<template>
+	<view class="main">
+		<view class="bgm">
+			<view class="form_group">
+				<view class="lable">标题</view>
+				<input v-model="item.title" placeholder="请输入标题" />
+			</view>
+			<view class="form_group">
+				<view class="lable">分类</view>
+				<picker :range="type" range-key="dictLabel" @change="picker($event, 'type')">
+					<input placeholder="请选择" v-model="item.type" :disabled="true" />
+					<view class="icon more">&#xe62b;</view>
+				</picker>
+			</view>
+			<leditor v-model="item.content"></leditor>
+			<view class="form_group">
+				<view class="lable">状态</view>
+				<picker :range="state" @change="picker($event, 'state')">
+					<input placeholder="请选择" :value="item.state == 0 ? '启用' : '停用'" :disabled="true" />
+					<view class="icon more">&#xe62b;</view>
+				</picker>
+			</view>
+		</view>
+		<button class="btn" @click="add()">确认</button>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			item: { state: 0 },
+			type: [],
+			state: ['启用', '停用']
+		};
+	},
+	onLoad() {
+		this.getType();
+	},
+	methods: {
+		picker(e, tag) {
+			if (tag == 'type') {
+				this.item.type = this.type[e.detail.value].dictLabel;
+			} else {
+				this.item[tag] = e.detail.value;
+			}
+			this.$forceUpdate();
+		},
+		getType() {
+			this.http.request({
+				url: '/app/common/type/knowledge_type',
+				loading: 'false',
+				success: (res) => {
+					this.type = res.data.data;
+				}
+			});
+		},
+		add() {
+			let rule = [
+				{ name: 'title', checkType: 'notnull', errorMsg: '请输入标题' },
+				{ name: 'type', checkType: 'notnull', errorMsg: '请选择分类' },
+				{ name: 'content', checkType: 'notnull', errorMsg: '请输入内容' }
+			];
+			if (!this.verify.check(this.item, rule)) {
+				uni.showModal({ content: this.verify.error, showCancel: false });
+				return false;
+			}
+			this.http.request({
+				url: '/work/knowledge/add',
+				method: 'POST',
+				data: this.item,
+				success: (res) => {
+					uni.showModal({
+						title: '提示',
+						content: '新增成功',
+						showCancel: false,
+						success: (res) => {
+							uni.$emit('knowledge');
+							uni.navigateBack();
+						}
+					});
+				}
+			});
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.bgm {
+	border-radius: 5px;
+	overflow: hidden;
+}
+.btn {
+	margin-top: 35px;
+}
+</style>

+ 163 - 0
app/pages/knowledge/doctor/index.vue

@@ -0,0 +1,163 @@
+<template>
+	<view>
+		<view class="search">
+			<u-search placeholder="搜索标题" v-model="param.title" bgColor="white" :showAction="false" @search="(current = 0), (param.type = ''), refresh()" @clear="(current = 0), (param.type = ''), (param.title = ''), refresh()"></u-search>
+		</view>
+		<view class="tab">
+			<u-tabs :list="tab" :current="current" keyName="dictLabel" @click="click"></u-tabs>
+		</view>
+		<view class="list">
+			<view class="item" v-for="(item, index) in list" :key="index" @click="go('/pages/knowledge/detail?id=' + item.id)">
+				<view class="title omit">
+					<text class="icon" v-if="item.top === 1">&#xe61f;</text>
+					<text>{{ item.title }}</text>
+				</view>
+				<view class="desc">
+					<text>{{ item.type }}</text>
+					<text>发布于 {{ item.createTime }}</text>
+					<text class="del" @click.stop="del(item, index)">删除</text>
+				</view>
+			</view>
+			<view class="loading" v-if="loadMore"><u-loadmore :status="loadMore ? 'loading' : 'nomore'" /></view>
+			<u-empty v-if="!loadMore && list.length == 0"></u-empty>
+		</view>
+		<view class="mfooter">
+			<button class="btn" @click="go('/pages/knowledge/doctor/add')">
+				<text class="icon">&#xe8d5;</text>
+				<text>发布</text>
+			</button>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			tab: [],
+			current: 0,
+			list: [],
+			param: { pageNum: 1, pageSize: 10 },
+			loadMore: true
+		};
+	},
+	onLoad(e) {
+		this.getType();
+		this.getData();
+		uni.$on('knowledge', (res) => {
+			this.refresh();
+		});
+	},
+	methods: {
+		click(e) {
+			this.current = e.index;
+			this.param.type = e.dictValue;
+			this.refresh();
+		},
+		getData() {
+			this.http.request({
+				url: '/work/knowledge/list',
+				data: this.param,
+				loading: 'false',
+				success: (res) => {
+					this.loadMore = res.data.pages > this.param.pageNum ? true : false;
+					res.data.rows.forEach((item) => {
+						item.createTime = uni.$u.timeFrom(Date.parse(item.createTime));
+						this.list.push(item);
+					});
+				}
+			});
+		},
+		getType() {
+			this.http.request({
+				url: '/app/common/type/knowledge_type',
+				loading: 'false',
+				success: (res) => {
+					this.tab = res.data.data;
+					this.tab.unshift({ dictLabel: '全部类型', dictValue: '' });
+				}
+			});
+		},
+		del(item, index) {
+			uni.showModal({
+				title: '提示',
+				content: '确定删除该知识?',
+				success: (res) => {
+					if (res.confirm) {
+						this.http.request({
+							url: '/work/knowledge/remove/' + item.id,
+							success: (res) => {
+								uni.showToast({ title: '删除成功' });
+								this.list.splice(index, 1);
+							}
+						});
+					}
+				}
+			});
+		},
+		go(url) {
+			uni.navigateTo({ url: url });
+		},
+		//刷新数据
+		refresh() {
+			this.loadMore = true;
+			this.param.pageNum = 1;
+			this.list = [];
+			this.getData();
+		}
+	},
+	//下拉刷新
+	onPullDownRefresh() {
+		setTimeout(() => {
+			this.refresh();
+			uni.stopPullDownRefresh();
+		}, 1000);
+	},
+	//上拉加载
+	onReachBottom() {
+		if (this.loadMore) {
+			this.param.pageNum++;
+			this.getData();
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.list {
+	padding: 10px 12px;
+	background-color: white;
+	margin: 10px;
+	border-radius: 10px;
+	.item {
+		border-radius: 5px;
+		padding: 13px 12px 13px 12px;
+		margin-bottom: 10px;
+		overflow: hidden;
+		border-bottom: 1px solid $line;
+		&:last-child{
+			border: 0px;
+		}
+		.title {
+			font-size: 15px;
+			font-weight: bold;
+			.icon {
+				color: orangered;
+				padding-right: 3px;
+			}
+		}
+		.desc {
+			font-size: 14px;
+			padding-top: 10px;
+			color: $font-c;
+			text {
+				padding-right: 30px;
+			}
+			.del {
+				color: red;
+				float: right;
+			}
+		}
+	}
+}
+</style>

+ 2 - 2
app/pages/user/index.vue

@@ -34,8 +34,8 @@
 					<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>
+				<view class="s_item" @click="go('/pages/knowledge/doctor/index')">
+					<text class="icon ic" style="color: #FF5722">&#xe69a;</text>
 					<text class="title">我的知识库</text>
 					<text class="icon arrow">&#xe62b;</text>
 				</view>

+ 2 - 2
ruoyi-admin/src/main/resources/application.yml

@@ -97,8 +97,8 @@ qiniu:
   bucketname: xiaoshushu
 # 微信小程序/公众号配置
 wx:
-  appid: wx25d3f9356f5fdf80
-  appSecret: dc584fd3c332b3f597321b3f5f33d6a0
+  appid: wxff094b320041c1e8
+  appSecret: f9ba1f9c5106eb7a67829dade4f064b8
 # 阿里云存储
 oss:
   callback: http://39.96.28.235/api/oss/callback