This commit is contained in:
liuyuan
2025-05-21 16:31:37 +08:00
parent 23cb7534ac
commit 060344610a
683 changed files with 70083 additions and 0 deletions

15
.hbuilderx/launch.json Normal file
View File

@@ -0,0 +1,15 @@
{
"version" : "1.0",
"configurations" : [
{
"default" : {
"launchtype" : "local"
},
"h5" : {
"launchtype" : "remote"
},
"provider" : "aliyun",
"type" : "uniCloud"
}
]
}

167
App.vue Normal file
View File

@@ -0,0 +1,167 @@
<script>
import { iap } from "@/utils/myIapCheck.js";
import store from "@/store/index.js";
import socket from "@/config/socket";
// #ifdef H5
import { h5Login } from "@/config/html5Utils";
// #endif
// #ifdef APP-PLUS
import updata from "@/uni_modules/uni-upgrade-center-app/utils/check-update";
// #endif
import Vue from "vue";
export default {
data() {
return {
platform: null, // 系统
appRegisterMap: undefined,
};
},
onLaunch: function() {
// 禁止横屏
// #ifdef APP-PLUS
plus.screen.lockOrientation("portrait-primary");
// 检测自动更新
updata();
// #endif
uni.getSystemInfo({
success(res) {
Vue.prototype.winWidth = res.screenWidth;
Vue.prototype.winHeight = res.screenHeight;
Vue.prototype.statusBarHeight = res.statusBarHeight;
},
});
//取出缓存数据
store.commit("setCacheData");
// #ifdef MP-WEIXIN
if (store.state.userInfo.token) {
socket.init();
}
// #endif
// #ifdef H5
if (store.state.userInfo.token) {
socket.init();
} else {
h5Login("force", () => {
socket.init();
});
}
// #endif
// #ifdef APP-PLUS
if (store.state.userInfo.token) {
socket.init();
}
// #endif
},
onShow: function(e) {
// #ifdef APP-PLUS
plus.screen.lockOrientation("portrait-primary");
// 检测是否有未关闭苹果内购订单
iap.getChannels()
// #endif
// #ifdef MP-WEIXIN
//获取二维码携带的参数
let scene = decodeURIComponent(e.query.scene);
scene = scene.split("&");
let data = {
//场景值
scene: e.scene,
};
scene.forEach((item) => {
let arr = item.split("=");
if (arr.length == 2) {
data[arr[0]] = arr[1];
}
});
store.commit("setChatScenesInfo", Object.assign(e.query, data));
// #endif
},
onHide: function() {
console.log('App Hide')
},
//页面销毁
destroyed() {
store.commit("setUserInfo", {
playFlag: true,
});
},
}
</script>
<style lang="scss">
@import "@/uni_modules/uview-ui/index.scss";
@import "@/uni_modules/uni-scss/index.scss";
/* #ifndef APP-PLUS-NVUE */
/* uni.css - 通用组件、模板样式库可以当作一套ui库应用 */
@import "@/static/uni.css";
@import "@/static/customicons.css";
@import "@/static/common.scss";
/* H5 兼容 pc 所需 */
/* #ifdef H5 */
@media screen and (min-width: 768px) {
body {
overflow-y: scroll;
}
}
/deep/uni-page-body {
background-color: $themeBgColor;
min-height: 100% !important;
height: 100% !important;
}
.uni-top-window uni-tabbar .uni-tabbar {
background-color: #fff !important;
}
.uni-app--showleftwindow .hideOnPc {
display: none !important;
}
/* #endif */
/* 以下样式用于 hello uni-app 演示所需 */
page {
height: 100%;
font-size: 28rpx;
}
.fix-pc-padding {
padding: 0 50px;
}
.uni-header-logo {
padding: 30rpx;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 10rpx;
}
.uni-header-image {
width: 100px;
height: 100px;
}
.uni-hello-text {
color: #7a7e83;
}
.uni-hello-addfile {
text-align: center;
line-height: 300rpx;
background: #fff;
padding: 50rpx;
margin-top: 10px;
font-size: 38rpx;
color: #808080;
}
/* #endif*/
/deep/ .uni-tabbar__label {
font-size: 12px !important; /* 修改 tabBar 文字大小 */
}
</style>

3
androidPrivacy.json Normal file
View File

@@ -0,0 +1,3 @@
{
"prompt" : "template"
}

140
common/commonJS.js Normal file
View File

@@ -0,0 +1,140 @@
import uniCopy from '@/js_sdk/xb-copy/uni-copy.js'
import $http from '@/config/requestConfig'
import { mapState, mapMutations } from "vuex";
export default {
...mapMutations(["setUserInfo"]),
showToast(title, icon) {
return uni.showToast({
title: title,
icon: icon ? icon : 'none'
})
},
//拨打电话
handleMakingPhoneCalls(value, title) {
uni.showModal({
title: title ? title : '联系我们',
content: value,
confirmText: '确认',
success(res) {
if (res.confirm) {
uni.makePhoneCall({
phoneNumber: value, //电话号码
success: function (e) {
console.log(e);
},
fail: function (e) {
console.log(e);
}
})
}
}
})
},
//复制内容
handleCopy(value, title) {
uniCopy({
content: value,
success: (res) => {
uni.showToast({
title: title + '复制成功',
icon: 'none'
})
},
error: (e) => {
}
})
},
//用户协议
async getAgreement(id) {
console.log('id at line 56:', id)
var data = {
id: id
}
var result = {
title:'',
content:''
}
await $http
.request({
url: "sys/agreement/getAgreement",
method: "POST",
data: data,
header: {
"Content-Type": "application/json",
},
}).then((res) => {
console.log('res at line 111:', res)
if (res.code == 0) {
result = res.agreement
}
})
return result
},
async getCheckCourseStatus(data) {
var result
await $http
.post('app/phone.do?getCheckCourseStatus', {
customerType
:
"D",
token
: uni.getStorageSync("token")
,
customerOid
: uni.getStorageSync("customerOid"),
oid: data.oid
})
.then(async res => {
result = res.obj
})
return result
},
// 退出登录
signOut() {
uni.showModal({
title: "提示",
content: "确定要退出当前账户吗?",
success: function (res) {
if (res.confirm) {
setUserInfo({ token: null });
uni.reLaunch({
url: "/pages/user/login",
});
} else if (res.cancel) {
// 取消操作
}
},
});
},
// 注销账户
logout() {
let that = this;
uni.showModal({
title: "提示",
content: "确定要注销当前账户吗?",
success: function (res) {
if (res.confirm) {
uni.showModal({
title: "提示",
showCancel: false,
content: `注销申请已提交成功,请联系客服进行后续操作022-24142321`,
success: function (res1) {
if (res1.confirm) {
that.signOut();
}
},
});
} else if (res.cancel) {
// 取消操作
}
},
});
}
}

29
common/debounce.js Normal file
View File

@@ -0,0 +1,29 @@
let timeout = null
/**
* 防抖原理一定时间内只有最后一次操作再过wait毫秒后才执行函数
*
* @param {Function} func 要执行的回调函数
* @param {Number} wait 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
function debounce(func, wait = 500, immediate = false) {
// 清除定时器
if (timeout !== null) clearTimeout(timeout)
// 立即执行,此类情况一般用不到
if (immediate) {
const callNow = !timeout
timeout = setTimeout(() => {
timeout = null
}, wait)
if (callNow) typeof func === 'function' && func()
} else {
// 设置定时器当最后一次操作后timeout不会再被清除所以在延时wait毫秒后执行func回调方法
timeout = setTimeout(() => {
typeof func === 'function' && func()
}, wait)
}
}
export default debounce

136
common/uni-nvue.css Normal file
View File

@@ -0,0 +1,136 @@
/* #ifndef APP-PLUS-NVUE */
page {
min-height: 100%;
height: auto;
}
/* #endif */
/* 解决头条小程序字体图标不显示问题因为头条运行时自动插入了span标签且有全局字体 */
/* #ifdef MP-TOUTIAO */
/* text :not(view) {
font-family: uniicons;
} */
/* #endif */
.uni-icon {
font-family: uniicons;
font-weight: normal;
}
.uni-container {
padding: 15px;
background-color: #f8f8f8;
}
.uni-header-logo {
/* #ifdef H5 */
display: flex;
/* #endif */
padding: 15px 15px;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 10rpx;
}
.uni-header-image {
width: 80px;
height: 80px;
}
.uni-hello-text {
margin-bottom: 20px;
}
.hello-text {
color: #7A7E83;
font-size: 14px;
line-height: 20px;
}
.hello-link {
color: #7A7E83;
font-size: 14px;
line-height: 20px;
}
.uni-panel {
margin-bottom: 12px;
}
.uni-panel-h {
/* #ifdef H5 */
display: flex;
/* #endif */
background-color: #ffffff;
flex-direction: row !important;
/* justify-content: space-between !important; */
align-items: center !important;
padding: 12px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
/*
.uni-panel-h:active {
background-color: #f8f8f8;
}
*/
.uni-panel-h-on {
background-color: #f5f5f5;
}
.uni-panel-text {
flex: 1;
color: #000000;
font-size: 14px;
font-weight: normal;
}
.uni-panel-icon {
margin-left: 15px;
color: #999999;
font-size: 14px;
font-weight: normal;
transform: rotate(0deg);
transition-duration: 0s;
transition-property: transform;
}
.uni-panel-icon-on {
transform: rotate(180deg);
}
.uni-navigate-item {
/* #ifdef H5 */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
background-color: #FFFFFF;
border-top-style: solid;
border-top-color: #f5f5f5;
border-top-width: 1px;
padding: 12px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-navigate-item:active {
background-color: #f8f8f8;
}
.uni-navigate-text {
flex: 1;
color: #000000;
font-size: 14px;
font-weight: normal;
}
.uni-navigate-icon {
margin-left: 15px;
color: #999999;
font-size: 14px;
font-weight: normal;
}

1434
common/uni.css Normal file

File diff suppressed because it is too large Load Diff

74
common/util.js Normal file
View File

@@ -0,0 +1,74 @@
function formatTime(time) {
if (typeof time !== 'number' || time < 0) {
return time
}
var hour = parseInt(time / 3600)
time = time % 3600
var minute = parseInt(time / 60)
time = time % 60
var second = time
return ([hour, minute, second]).map(function (n) {
n = n.toString()
return n[1] ? n : '0' + n
}).join(':')
}
function formatLocation(longitude, latitude) {
if (typeof longitude === 'string' && typeof latitude === 'string') {
longitude = parseFloat(longitude)
latitude = parseFloat(latitude)
}
longitude = longitude.toFixed(2)
latitude = latitude.toFixed(2)
return {
longitude: longitude.toString().split('.'),
latitude: latitude.toString().split('.')
}
}
var dateUtils = {
UNITS: {
'年': 31557600000,
'月': 2629800000,
'天': 86400000,
'小时': 3600000,
'分钟': 60000,
'秒': 1000
},
humanize: function (milliseconds) {
var humanize = '';
for (var key in this.UNITS) {
if (milliseconds >= this.UNITS[key]) {
humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
break;
}
}
return humanize || '刚刚';
},
format: function (dateStr) {
var date = this.parse(dateStr)
var diff = Date.now() - date.getTime();
if (diff < this.UNITS['天']) {
return this.humanize(diff);
}
var _format = function (number) {
return (number < 10 ? ('0' + number) : number);
};
return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDate()) + '-' +
_format(date.getHours()) + ':' + _format(date.getMinutes());
},
parse: function (str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串转化为一个Date对象
var a = str.split(/[^0-9]/);
return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
}
};
export {
formatTime,
formatLocation,
dateUtils
}

View File

@@ -0,0 +1,260 @@
<template>
<view v-if="iosHide">
<view class="footer_box">
<view
v-for="(item, index) of navigationList"
:key="index"
class="footer_item"
>
<view class="footer_nav_item" @click="onPageJump(item.pagePath)">
<image
v-if="item.pagePath == path"
class="footer_nav_item_image footer_nav_item_image_scale"
:src="'/' + item.selectedIconPath"
mode="aspectFit"
></image>
<image
v-else
class="footer_nav_item_image"
:src="'/' + item.iconPath"
mode="aspectFit"
></image>
<text
class="footer_nav_item_text"
:class="[item.pagePath == path ? 'footer_item_text_active' : '']"
>{{ item.text }}</text
>
<text class="image"></text>
</view>
</view>
</view>
</view>
<view v-else>
<view class="footer_box">
<view
v-for="(item, index) of navigationIos"
:key="index"
class="footer_item"
>
<view class="footer_nav_item" @click="onPageJump(item.pagePath)">
<image
v-if="item.pagePath == path"
class="footer_nav_item_image footer_nav_item_image_scale"
:src="'/' + item.selectedIconPath"
mode="aspectFit"
></image>
<image
v-else
class="footer_nav_item_image"
:src="'/' + item.iconPath"
mode="aspectFit"
></image>
<text
class="footer_nav_item_text"
:class="[
item.pagePath == path ? 'footer_item_text_active' : 'normal_text',
]"
>{{ item.text }}</text
>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
bg: {
type: Boolean,
default: true,
},
},
data() {
return {
path: "",
navigationList: [
{
"pagePath": "pages/home/index",
"iconPath": "static/tab/icon_tab1.png",
"selectedIconPath": "static/tab/icon_tab1_a.png",
"text": "智慧医疗"
},
{
"pagePath": "pages/talents/index",
"iconPath": "static/tab/icon_tab2.png",
"selectedIconPath": "static/tab/icon_tab2_a.png",
"text": "太湖英才"
},
// {
// "pagePath": "pages/doctors/index",
// "iconPath": "static/tab/icon_tab3.png",
// "selectedIconPath": "static/tab/icon_tab3_a.png",
// "text": "名医精彩"
// },
// {
// "pagePath": "pages/wumen/index",
// "iconPath": "static/tab/icon_tab4.png",
// "selectedIconPath": "static/tab/icon_tab4_a.png",
// "text": "吴门医述"
// },
{
"pagePath": "pages/my/index",
"iconPath": "static/tab/icon_tab5.png",
"selectedIconPath": "static/tab/icon_tab5_a.png",
"text": "我的"
}
],
navigationIos: [
{
"pagePath": "pages/home/index",
"iconPath": "static/tab/icon_tab1.png",
"selectedIconPath": "static/tab/icon_tab1_a.png",
"text": "智慧医疗"
},
{
"pagePath": "pages/talents/index",
"iconPath": "static/tab/icon_tab2.png",
"selectedIconPath": "static/tab/icon_tab2_a.png",
"text": "太湖英才"
},
// {
// "pagePath": "pages/doctors/index",
// "iconPath": "static/tab/icon_tab3.png",
// "selectedIconPath": "static/tab/icon_tab3_a.png",
// "text": "名医精彩"
// },
// {
// "pagePath": "pages/wumen/index",
// "iconPath": "static/tab/icon_tab4.png",
// "selectedIconPath": "static/tab/icon_tab4_a.png",
// "text": "吴门医述"
// },
{
"pagePath": "pages/my/index",
"iconPath": "static/tab/icon_tab5.png",
"selectedIconPath": "static/tab/icon_tab5_a.png",
"text": "我的"
}
],
};
},
//第一次加载
created() {
//获取所有页面
let currentPages = getCurrentPages();
let page = currentPages[currentPages.length - 1];
this.path = page.route;
},
//方法
methods: {
onPageJump(url) {
if (this.path !== url) {
uni.switchTab({
url: "/" + url,
});
}
},
},
};
</script>
<style lang="scss" scoped>
@import "@/static/mixin.scss";
.normal_text {
color: #fff;
}
.footer_station {
height: 110rpx;
box-sizing: content-box;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
.footer_box {
background: #fff;
padding-top: 10rpx;
height: 120rpx;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
z-index: 502;
box-sizing: content-box;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
.footer_bg {
background-color: #fff;
box-shadow: 0 0px 10px 1px #0000001a;
}
.footer_item {
position: relative;
flex: 1;
}
.image{
position: absolute;
right: -10rpx;
top: 0;
width: 10rpx;
height: 110rpx;
background-image: url('../../static/icon/icon_line.png');
background-repeat: no-repeat;
background-size: contain;
}
.footer_item:last-child .image{
display: none;
}
.footer_nav_item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
.footer_nav_item:active {
background-color: rgba($color: #fff, $alpha: 0.1);
}
.footer_nav_item_text {
font-size: 26rpx;
color: #606061;
margin-top: 6rpx;
}
.footer_nav_item_text.redText{color: red;}
.footer_nav_item_text_active {
color: #f9a633;
}
.footer_nav_item_image {
width: 80rpx;
height: 58rpx;
}
.footer_nav_item_image_scale {
animation: mescrollUpRotate 0.6s linear 1;
}
@keyframes mescrollUpRotate {
0% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
.footer_item_text_active {
color: #00348b;
}
</style>

56
config/baseUrl.js Normal file
View File

@@ -0,0 +1,56 @@
let baseUrl = "";
let socketUrl = "";
if (process.env.NODE_ENV === 'development') {
// 开发环境
baseUrl = "http://192.168.110.100:9200/pb/"; // 张川川
//baseUrl = "https://api.nuttyreading.com/"; //线上正式
} else if (process.env.NODE_ENV === 'production') {
baseUrl = "http://192.168.110.100:9200/pb/"; // 张川川
//baseUrl = "https://api.nuttyreading.com/"; //线上正式
}
const courtConfig = {
//微信公众号APPID
publicAppId: "",
//请求接口
baseUrl: baseUrl,
//webSocket地址
socketUrl: socketUrl,
//平台名称
platformName: "uniApp-案例",
//项目logo
logoUrl: "https://qn.kemean.cn/upload/201906/19/3f3b4751f3ed4a97be804450c3ec4c79",
//页面分享配置
share: {
title: 'uniApp-案例',
// #ifdef MP-WEIXIN
path: '/pages/home/home', //小程序分享路径
// #endif
// #ifdef H5 || APP-PLUS
//公众号||APP分享
desc: "uniApp-案例", // 分享描述
link: "https://www.kemean.com/sameCity/18031201/index.html", // 分享链接该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: "http://qn.kemean.cn/upload/201901/28/23bedfc34597482292ecd6dc107f6342", // 分享图标
// #endif
}
};
// 订单编号的正则
const orderRegular = /[0-9]\d{31}$/;
//手机号验证正则表达式
// (中国大陆)
// const phoneRegular = /^1\d{10}$/;
const phoneRegular = /^1([358][0-9]|4[579]|66|7[0135678]|9[89])\d{8}$/;
// const phoneRegular = /^[1][3-8]\d{9}$|^([6|9])\d{7}$|^[0][9]\d{8}$|^[6]([8|6])\d{5}$/;
// 手机号码验证 支持港澳台 大陆
// const phoneRegular = /^[1][3-8]\d{9}$|^([6|9])\d{7}$|^[0][9]\d{8}$|^[6]([8|6])\d{5}$|^(00){0,1}(65){1}[13689]\d{6,7}$/;
//邮箱验证正则表达式
const mailRegular = /^\w+([-+._']\w+)*@\w+(\.[a-zA-Z]{2,3}){1,2}$/;
//密码验证正则表达式
// const passwordRegular = /^[a-zA-Z0-9]{4,10}$/;
const passwordRegular = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/;
export default Object.assign({
orderRegular,
phoneRegular,
mailRegular,
passwordRegular
}, courtConfig);

76
config/componentConfig.js Normal file
View File

@@ -0,0 +1,76 @@
import $http from '@/config/requestConfig'
const platform = uni.getSystemInfoSync().platform;
export default {
/****************以下是z-nav-bar插件配置*******************/
// 主页页面的页面路径
// 关联功能:打开的页面只有一个的时候右上角自动显示返回首页按钮,下面这个数组是排除显示返回首页的页面。
// 主页使用场景:小程序分享出去的页面,用户点击开是分享页面,很多情况下是没有返回首页按钮的
mainPagePath: ['pages/home/index'],
//返回首页的地址
homePath: '/pages/home/index',
/****************以下是zhouWei-APPUpdate插件配置*******************/
// 发起ajax请求获取服务端版本号
getServerNo: (version, isPrompt = false, callback) => {
let httpData = {
version: version.versionCode,
// 版本名称
versionName: version.versionName,
// setupPage参数说明判断用户是不是从设置页面点击的更新如果是设置页面点击的更新有不要用静默更新了不然用户点击没反应很奇怪的
setupPage: isPrompt
};
if (platform == "android") {
httpData.type = 1101;
} else {
httpData.type = 1102;
}
/* 接口入参说明
* version: 应用当前版本号(已自动获取)
* versionName: 应用当前版本名称(已自动获取)
* type平台1101是安卓1102是IOS
*/
/****************以下是示例*******************/
// 可以用自己项目的请求方法
$http.get("api/common/v1/app_version", httpData,{
isPrompt: isPrompt
}).then(res => {
/* res的数据说明
* | 参数名称 | 一定返回 | 类型 | 描述
* | -------------|--------- | --------- | ------------- |
* | versionCode | y | int | 版本号 |
* | versionName | y | String | 版本名称 |
* | versionInfo | y | String | 版本信息 |
* | updateType | y | String | forcibly = 强制更新, solicit = 弹窗确认更新, silent = 静默更新 |
* | downloadUrl | y | String | 版本下载链接IOS安装包更新请放跳转store应用商店链接,安卓apk和wgt文件放文件下载链接 |
*/
if (res && res.downloadUrl) {
// 判断用户是不是从设置页面点击的更新,如果是设置页面点击的更新,无视接口给的更新类型,强制修改为弹窗确认更新
if(isPrompt){
res.updateType = "solicit";
}
// 兼容之前的版本updateType是新版才有的参数
if(res.updateType){
callback && callback(res);
} else {
if(res.forceUpdate){
res.updateType = "forcibly";
} else {
res.updateType = "solicit";
}
callback && callback(res);
}
} else if (isPrompt) {
uni.showToast({
title: "暂无新版本",
icon: "none"
});
}
});
/****************以上是示例*******************/
},
// 弹窗主颜色(不填默认粉色)
appUpdateColor: "f00",
// 弹窗图标(不填显示默认图标,链接配置示例如: '/static/demo/ic_attention.png'
appUpdateIcon: ''
}

228
config/html5Utils.js Normal file
View File

@@ -0,0 +1,228 @@
import base from '@/config/baseUrl';
import store from '@/store';
import $http from '@/config/requestConfig';
/**
* APP内嵌网页 -- 安卓IOS交互
* 交互区分名称shangChengView
* 示例appMutual("方法名称", "传递的参数")
* 相当与安卓交互window.shangChengView["方法名称"]("传递的参数");
*/
export const appMutual = (name, query = null, errCallback) => {
if (/android/i.test(navigator.userAgent)) {
if (window.shangChengView) {
if (typeof(query) == "object") {
query = JSON.stringify(query);
}
window.shangChengView[name](query);
} else {
errCallback && errCallback();
}
} else if (/ios|iphone|ipod|pad/i.test(navigator.userAgent)) {
if (window.webkit) {
window.webkit.messageHandlers[name].postMessage(query)
} else {
errCallback && errCallback();
}
}
};
/**
* 获取url中的参数
*/
export const getUrlData = () => {
var strs;
var url = window.location.href; //获取url中"?"符后的字串
var theRequest = new Object();
if (url.indexOf("?") != -1) {
url = url.substr(url.indexOf("?"));
var str = url.substr(1);
strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
var index = strs[i].indexOf("=");
theRequest[strs[i].slice(0, index)] = unescape(strs[i].slice(index + 1, strs[i].length));
}
}
return theRequest;
}
//公众号微信支付
export const wxPublicPay = (payInfo, callback) => {
$http.get("api/pay/v1/pay_public_wx", {
orderNo: payInfo.orderNo
}).then(data => {
let wxConfigObj = {
appId: data.appId,
timeStamp: data.timeStamp,
nonceStr: data.nonceStr,
package: data.package,
signType: data.signType,
paySign: data.sign
};
function onBridgeReady() {
window.WeixinJSBridge.invoke("getBrandWCPayRequest", wxConfigObj, function(
res
) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
callback && callback(res);
} else // 使用以上方式判断前端返回,微信团队郑重提示res.err_msg将在用户支付成功后返回 ok但并不保证它绝对可靠。
if (res.err_msg == "get_brand_wcpay_request:cancel") {
// common.loadWarn('支付遇到问题,您取消了支付');
} else
if (res.err_msg == "get_brand_wcpay_request:fail") {
// common.myConfirm('支付遇到问题,您可能需要重新登录', '', function () {
// obj.wxLoginOAuth();
// });
}
});
}
if (typeof window.WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener("WeixinJSBridgeReady", onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent("WeixinJSBridgeReady", onBridgeReady);
document.attachEvent("onWeixinJSBridgeReady", onBridgeReady);
}
} else {
onBridgeReady();
}
});
};
// 浏览器判断
export const getBrowser = () => {
let ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
return "微信";
}
return "其他";
};
//公众号获取code
function getLogin(type) {
let urlNow = encodeURIComponent(window.location.href);
let url =
`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${
base.publicAppId
}&redirect_uri=${urlNow}&response_type=code&scope=snsapi_userinfo&state=${type}#wechat_redirect`;
window.location.replace(url);
}
//判断是否登录,登录处理
let isGetOpenId = true;
function getRecommendCode() {
var url = window.location.href;
let codeIndex = url.indexOf("recommendCode=");
if (codeIndex >= 0) {
let recommendCode = url.substr(codeIndex + 14);
if (recommendCode.indexOf("&") >= 0) {
return recommendCode.substr(0, recommendCode.indexOf("&"));
} else if (recommendCode.indexOf("?") >= 0) {
return recommendCode.substr(0, recommendCode.indexOf("?"));
} else if (recommendCode.indexOf("/") >= 0) {
return recommendCode.substr(0, recommendCode.indexOf("/"));
} else if (recommendCode.indexOf("#") >= 0) {
return recommendCode.substr(0, recommendCode.indexOf("#"));
}
return recommendCode;
} else {
return;
}
}
function getRecommend() {
var url = window.location.href;
let codeIndex = url.indexOf("recommend=");
if (codeIndex >= 0) {
let recommend = url.substr(codeIndex + 10);
if (recommend.indexOf("&") >= 0) {
return recommend.substr(0, recommend.indexOf("&"));
} else if (recommend.indexOf("?") >= 0) {
return recommend.substr(0, recommend.indexOf("?"));
} else if (recommend.indexOf("/") >= 0) {
return recommend.substr(0, recommend.indexOf("/"));
} else if (recommend.indexOf("#") >= 0) {
return recommend.substr(0, recommend.indexOf("#"));
}
return recommend;
} else {
return;
}
}
export const h5Login = function(type = "judge", callback) {
var getRequest = getUrlData();
let recommendCode = getRecommendCode();
if (recommendCode && recommendCode !== "null" && recommendCode !== "undefined") {
uni.setStorageSync("recommendCode", recommendCode);
} else {
let recommend = getRecommend();
if(recommend && recommend !== "null" && recommend !== "undefined"){
uni.setStorageSync("recommendCode", recommend);
}
}
if (getBrowser() == "微信") {
if (getRequest.code) {
if(isGetOpenId){
isGetOpenId = false;
let httpData = {
code: getRequest.code
};
let recommendCode = uni.getStorageSync("recommendCode");
if(recommendCode){
httpData.recommendUid = recommendCode;
store.commit("setChatScenesInfo", {
recommendCode: recommendCode
});
uni.removeStorageSync("recommendCode");
}
$http.get("api/open/v2/get_public_login", httpData)
.then(result => {
store.commit('setUserInfo', result);
//publicShare();
callback && callback();
uni.showToast({
title: "欢迎回来",
icon: "none"
});
},() => {
isGetOpenId = true;
});
}
} else {
getLogin(type);
}
} else {
if (getRequest.userToken) {
store.commit('setUserInfo', {
token: getRequest.userToken
});
$http.get("api/mime/v1/info").then(res => {
store.commit('setUserInfo', res);
callback && callback();
});
} else {
appMutual("jumpLogin", null, function() {
if (type == "force") {
// 没登录跳转回登录页
uni.showToast({
icon: 'none',
title: '用户信息失效,请重新登陆。'
})
uni.navigateTo({
url: "/pages/user/login"
});
}else{
uni.showModal({
title:"提示",
content:"您还未登录,请先登录~",
confirmText: "去登录",
cancelText: "再逛会",
success: (res) => {
if(res.confirm){
uni.navigateTo({
url: "/pages/user/login"
});
}
}
});
}
});
}
}
}

133
config/login.js Normal file
View File

@@ -0,0 +1,133 @@
import store from '@/store';
import $http from '@/config/requestConfig'
import base from '@/config/baseUrl';
// #ifdef H5
import { h5Login } from '@/config/html5Utils';
// #endif
let code = "";
let loginStart = true;
let userInfo = {
token: ""
};
let lastPageUrl = "";
// 微信小程序登录
function onLogin(type = "judge",callback) {
//判断登录状态
if (loginStart) {
loginStart = false;
const _this = this;
let platform;
// #ifdef MP-WEIXIN
platform = 'weixin';
// #endif
// #ifdef MP-ALIPAY
platform = 'alipay';
// #endif
// #ifdef MP-BAIDU
platform = 'baidu';
// #endif
uni.login({
provider: platform,
success: function(loginRes) {
if (loginRes.errMsg == 'login:ok') {
// 获取用户信息
uni.getUserInfo({
provider: platform,
success: function(infoRes) {
let httpData = {
wxSmallCode: loginRes.code, //小程序code
iv: infoRes.iv, //小程序加密算法的初始向量
encryptedData: infoRes.encryptedData //包括敏感数据在内的完整用户信息的加密数据
};
// store.state.chatScenesInfo里面是小程序二维码附带的信息
if(store.state.chatScenesInfo.invite){
// 推荐码
httpData.invite = store.state.chatScenesInfo.invite;
}
$http.post('api/open/v1/login', httpData).then(res => {
loginStart = true;
store.commit('setUserInfo', res);
callback && callback();
if (res.nullUserInfo) {
// 没有绑定过微信的头像或者昵称弹出授权获取头像昵称的弹窗
store.commit('setBindUserInfoShow', true);
} else {
uni.showToast({
title: "登录成功"
});
}
}, err => {
loginStart = true;
});
}
});
}
}
});
}
}
//判断是否登录(所有端)
function judgeLogin(callback, type = "judge"){
if(store.state.chatScenesInfo.scene == 1154){
uni.showToast({
title: '请前往小程序使用完整服务',
icon: "none"
});
} else {
let storeUserInfo = store.state.userInfo;
if(!storeUserInfo.token){ // nvue页面读取不到vuex里面数据将取缓存
storeUserInfo = uni.getStorageSync("userInfo");
}
if (type != "force" && storeUserInfo.token) {
callback();
} else if (storeUserInfo.token && !storeUserInfo.phone) {
if (type == "force") {
uni.navigateTo({
url: ''
});
} else {
uni.showModal({
title: "提示",
content: "您还未绑定手机号,请先绑定~",
confirmText: "去绑定",
cancelText: "再逛会",
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: ''
});
}
}
});
}
} else {
// #ifdef MP
onLogin(type, callback);
// #endif
// #ifdef APP-PLUS
uni.showModal({
title: "登录提示",
content: "此时此刻需要您登录喔~",
confirmText: "去登录",
cancelText: "再逛会",
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: "/pages/user/login"
});
}
}
});
// #endif
// #ifdef H5
h5Login(type, () => {
callback();
});
// #endif
}
}
}
export {
onLogin,
judgeLogin
}

290
config/requestConfig.js Normal file
View File

@@ -0,0 +1,290 @@
import request from "@/uni_modules/zhouWei-request/js_sdk/request";
import store from '@/store';
import base from '@/config/baseUrl';
// #ifdef H5
import {
h5Login
} from '@/config/html5Utils';
// #endif
// #ifdef MP-WEIXIN
import {
onLogin
} from '@/config/login';
// #endif
let version_code = '';
// #ifdef APP-PLUS
import {
getCurrentNo
} from '@/uni_modules/zhouWei-APPUpdate/js_sdk/appUpdate';
setTimeout(() => {
getCurrentNo(function (res) {
console.log("版本号", res);
version_code = res.versionCode;
});
}, 200);
// #endif
//可以new多个request来支持多个域名请求
let $http = new request({
//接口请求地址
baseUrl: base.baseUrl,
//服务器本地上传文件地址
fileUrl: base.baseUrl,
// 服务器上传图片默认url
defaultUploadUrl: "api/common/v1/upload_image",
// 服务器上传文件名称
defaultFileName: "file",
//设置请求头如果使用报错跨域问题可能是content-type请求类型和后台那边设置的不一致
header: {
'Content-Type': 'application/x-www-form-urlencoded',
}
});
// 添加获取七牛云token的方法
$http.getQnToken = function (callback) {
//该地址需要开发者自行配置(每个后台的接口风格都不一样)
$http.get("api/common/v1/qn_upload").then(data => {
/*
*接口返回参数:
*visitPrefix:访问文件的域名
*token:七牛云上传token
*folderPath:上传的文件夹
*region: 地区 默认为SCN
*/
callback({
visitPrefix: data.visitPrefix,
token: data.token,
folderPath: data.folderPath
});
});
}
// 添加获取阿里云token的方法
$http.getAliToken = function (callback) {
//该地址需要开发者自行配置(每个后台的接口风格都不一样)
$http.get("api/open/v1/ali_oss_upload").then(data => {
/*
*接口返回参数:
*visitPrefix:访问文件的域名
*folderPath:上传的文件夹
*accessKeyId: 您的oss的访问ID
*accessKeySecret: 您的oss的访问密钥
*timeout: 签名过期时间毫秒默认1800000
*/
callback({
accessKeyId: data.accessKeyId,
accessKeySecret: data.accessKeySecret,
visitPrefix: data.visitPrefix,
folderPath: data.folderPath,
timeout: 60000
});
});
}
//请求开始拦截器
$http.requestStart = function (options) {
// console.log("请求开始", options);
if (options.load && options.data.loadAnimate != 'none') {
//打开加载动画
store.commit("setLoadingShow", true);
}
if (options.data.loadAnimate == 'none') {
delete options.data.loadAnimate
}
// 图片、视频上传大小限制
if (options.method == "FILE") {
// 文件最大字节: options.maxSize 可以在调用方法的时候加入参数
let maxSize = options.maxSize || '';
for (let item of options.files) {
if (item.fileType == 'image') {
if (maxSize && item.size > maxSize) {
setTimeout(() => {
uni.showToast({
title: "图片过大,请重新上传",
icon: "none"
});
}, 500);
return false;
}
} else if (item.fileType == "video") {
if (item.duration < 3) {
setTimeout(() => {
uni.showToast({
title: "视频长度不足3秒请重新上传",
icon: "none"
});
}, 500);
return false;
}
}
}
}
// #ifdef APP-PLUS
// 添加当前版本号
if (version_code) {
options.header['version_code'] = version_code;
}
// #endif
//请求前加入token
let storeUserInfo = store.state.userInfo;
if (!storeUserInfo) { // nvue页面读取不到vuex里面数据将取缓存
storeUserInfo = uni.getStorageSync("userInfo");
}
if (storeUserInfo.token) {
options.header['token'] = storeUserInfo.token;
};
options.header['appType'] = 'psyche';
return options;
}
//请求结束
$http.requestEnd = function (options) {
//判断当前接口是否需要加载动画
if (options.load) {
// 关闭加载动画
store.commit("setLoadingShow", false);
}
}
let loginPopupNum = 0;
//所有接口数据处理(此方法需要开发者根据各自的接口返回类型修改,以下只是模板)
$http.dataFactory = async function (res) {
if (res.response.statusCode && res.response.statusCode == 200) {
let httpData = res.response.data;
if (typeof (httpData) == "string") {
httpData = JSON.parse(httpData);
}
/*********以下只是模板(及共参考),需要开发者根据各自的接口返回类型修改*********/
//判断数据是否请求成功
if (httpData.success || httpData.code == 0) {
// 返回正确的结果(then接受数据)
return Promise.resolve(httpData);
} else if (httpData.code == "401") {
if (uni.getStorageSync('guidePages') == 2) {
var jump = uni.getStorageSync('isJump') //以下解决多次跳转登录页的重点
if (!jump) {
//以下做token失效的操作
uni.showToast({
title: '登录失效,请重新登录',
icon: 'none'
});
uni.setStorageSync('userInfo', {})
uni.setStorageSync('token', null)
setTimeout(() => {
uni.redirectTo({
url: "/pages/user/login",
success: function () {
setTimeout(() => {
uni.setStorageSync('isJump', null)
}, 1000)
},
});
}, 100);
uni.setStorageSync('isJump', 'true')
}
}
} else if (httpData.code == "500" && !httpData.msg) {
//500
uni.showToast({
title: '系统错误,请联系管理员',
icon: 'none'
});
} else if (httpData.code == "1000" || httpData.code == "1001" || httpData.code == 1100 || httpData
.code == 402) {
store.commit("emptyUserInfo");
// #ifdef MP-WEIXIN
onLogin();
// #endif
// #ifdef H5
h5Login("force");
// #endif
// #ifdef APP-PLUS
var content = '此时此刻需要您登录喔~';
if (httpData.code == "1000") {
content = '此时此刻需要您登录喔';
}
if (loginPopupNum <= 0) {
loginPopupNum++;
uni.showModal({
title: '温馨提示',
content: content,
confirmText: "去登录",
cancelText: "再逛会",
success: function (res) {
loginPopupNum--;
if (res.confirm) {
uni.navigateTo({
url: "/pages/user/login"
});
}
}
});
}
// #endif
// 返回错误的结果(catch接受数据)
return Promise.reject({
statusCode: 0,
errMsg: "【request】" + (httpData.info || httpData.msg),
data: res.data
});
} else if (httpData.code == "1004") {
if (loginPopupNum <= 0) {
loginPopupNum++;
uni.showModal({
title: "提示",
content: "您还未绑定手机号,请先绑定~",
confirmText: "去绑定",
cancelText: "再逛会",
success: (res) => {
loginPopupNum--;
if (res.confirm) {
uni.navigateTo({
url: ''
});
}
}
});
}
// 返回错误的结果(catch接受数据)
return Promise.reject({
statusCode: 0,
errMsg: "【request】" + (httpData.info || httpData.msg),
data: res.data
});
} else { //其他错误提示
if (res.isPrompt && res.data.loadAnimate != 'none') {
uni.showToast({
title: httpData.info || httpData.msg,
icon: "none",
duration: 3000
});
}
// 返回错误的结果(catch接受数据)
return Promise.reject({
statusCode: 0,
errMsg: "【request】" + (httpData.info || httpData.msg),
data: res.data
});
}
/*********以上只是模板(及共参考),需要开发者根据各自的接口返回类型修改*********/
} else {
// 返回错误的结果(catch接受数据)
return Promise.reject({
statusCode: res.response.statusCode,
errMsg: "【request】数据工厂验证不通过",
data: res.data
});
}
};
// 错误回调
$http.requestError = function (e) {
// e.statusCode === 0 是参数效验错误抛出的
if (e.statusCode === 0) {
throw e;
} else {
console.log(e);
}
}
export default $http;

103
config/socket.js Normal file
View File

@@ -0,0 +1,103 @@
import base from '@/config/baseUrl';
import store from '@/store';
class socket {
constructor(options) {
//地址
this.socketUrl = base.socketUrl;
this.socketStart = false;
this.monitorSocketError();
this.monitorSocketClose();
this.socketReceive();
}
init(callback) {
const _this = this;
if (base.socketUrl) {
if(this.socketStart){
console.log('webSocket已经启动了');
}else{
uni.connectSocket({
url: this.socketUrl,
method: 'GET'
});
uni.onSocketOpen((res) => {
this.socketStart = true;
callback && callback();
console.log('WebSocket连接已打开');
});
setTimeout(() => {
_this.getHeartbeat();
}, 5000);
}
}else{
console.log('config/baseUrl socketUrl为空');
}
}
//Socket给服务器发送消息
send(data, callback) {
const _this = this;
if (store.state.userInfo.uid) {
data.userUid = store.state.userInfo.uid;
}
console.log(data);
uni.sendSocketMessage({
data: JSON.stringify(data),
success: () => {
callback && callback(true);
},
fail: () => {
callback && callback(false);
}
});
}
//Socket接收服务器发送过来的消息
socketReceive() {
const _this = this;
uni.onSocketMessage(function(res) {
let data = JSON.parse(res.data);
console.log('收到服务器内容:', data);
_this.acceptMessage && _this.acceptMessage(data);
});
}
//关闭Socket
closeSocket() {
uni.closeSocket();
_this.socketStart = false;
}
//监听Socket关闭
monitorSocketClose() {
const _this = this;
uni.onSocketClose(function(res) {
console.log('WebSocket 已关闭!');
_this.socketStart = false;
setTimeout(function() {
_this.init();
}, 3000);
});
}
//监听Socket错误
monitorSocketError() {
const _this = this;
uni.onSocketError(function(res) {
_this.socketStart = false;
console.log('WebSocket连接打开失败请检查');
});
}
//心跳
getHeartbeat() {
const _this = this;
this.send({
type: "心跳",
userUid: store.state.userInfo.userUid
}, (val) => {
setTimeout(() => {
if (val) {
_this.getHeartbeat();
} else {
_this.init();
}
}, 10000);
});
}
};
const mySocket = new socket();
export default mySocket;

316
config/utils.js Normal file
View File

@@ -0,0 +1,316 @@
import $http from '@/config/requestConfig'
import store from '@/store';
import base from '@/config/baseUrl';
import {
getAppWxLatLon
} from '@/plugins/utils';
// #ifdef H5
import {
getLatLonH5,
publicShareFun,
wxPublicPay,
getBrowser,
appMutual
} from '@/config/html5Utils';
// 公众号分享
export const publicShare = publicShareFun;
// #endif
// #ifdef APP-PLUS
import appShareFun, {
closeShare
} from '@/uni_modules/zhouWei-APPshare/js_sdk/appShare';
// APP分享
export const appShare = function(data, callbcak) {
let userInfo = store.state.userInfo;
if (!(userInfo && userInfo.uid)) {
userInfo = uni.getStorageSync("userInfo");
}
let shareData = {
shareTitle: data.shareTitle || base.share.title,
shareUrl: data.shareUrl || base.share.link,
shareContent: data.shareContent || base.share.desc,
shareImg: data.shareImg || base.share.imgUrl,
}
if (userInfo && userInfo.uid) {
if (data.shareUrl) {
if (data.shareUrl.indexOf("?") >= 0) {
shareData.shareUrl = data.shareUrl + "&recommend=" + userInfo.uid
} else {
shareData.shareUrl = data.shareUrl + "?recommend=" + userInfo.uid
}
} else if (base.share && base.share.link) {
if (base.share.link.indexOf("?") >= 0) {
shareData.shareUrl = base.share.link + "&recommend=" + userInfo.uid
} else {
shareData.shareUrl = base.share.link + "?recommend=" + userInfo.uid
}
}
}
return appShareFun({
shareTitle: data.shareTitle || base.share.title,
shareUrl: data.shareUrl || base.share.link,
shareContent: data.shareContent || base.share.desc,
shareImg: data.shareImg || base.share.imgUrl,
}, callbcak);
};
export const closeAppShare = closeShare;
// #endif
// #ifdef MP-WEIXIN
// 微信小程序分享
export const wxShare = function(data = {}) {
let shareInfo = {
title: data.title || base.share.title,
};
if (data.path && typeof(data.path) == "string") {
shareInfo.path = data.path;
} else if (data.path != 1) {
shareInfo.path = "pages/home/index";
}
if (data.imageUrl) {
shareInfo.imageUrl = data.imageUrl;
}
let userInfo = store.state.userInfo;
if (!(userInfo && userInfo.uid)) {
userInfo = uni.getStorageSync("userInfo");
}
if (userInfo && userInfo.uid) {
if (data.query && typeof(data.query) == "object") {
data.query.recommendCode = userInfo.uid;
} else {
data.query = {
recommendCode: userInfo.uid
};
}
}
if (data.query && typeof(data.query) == "object") {
Object.keys(data.query).forEach((key, index) => {
if (index > 0 && shareInfo.query) {
shareInfo.query += "&" + key + "=" + data.query[key];
shareInfo.path += "&" + key + "=" + data.query[key];
} else {
shareInfo.query = key + "=" + data.query[key];
shareInfo.path += "?" + key + "=" + data.query[key];
}
});
}
return shareInfo;
}
// #endif
//支付APP微信支付、APP支付宝支付、微信小程序支付
export const setPay = function(payInfo, callback) {
console.log(payInfo)
payInfo.customerId = store.state.userInfo.id
let httpUrl = "";
if (payInfo.typePay == 'wxpay') {
// APP微信支付
httpUrl = '/v3/pay/placeAnOrder/app'
} else if (payInfo.typePay == 'alipay') {
// APP支付宝支付
httpUrl = 'pay/aliPay/pay'
} else if (payInfo.typePay == 'smallPay') {
// 微信小程序支付
httpUrl = 'api/pay/v1/small_pay_sign_wx'
} else if (payInfo.typePay == 'appleiap') {
// 苹果支付
}
$http.post(httpUrl, payInfo).then(data => {
console.log(data, 'data')
let payData = {
success: function(res) {
callback && callback({
success: true,
data: res
});
console.log('success:' + JSON.stringify(res));
},
fail: function(err) {
callback && callback({
success: false,
data: err
});
console.log('fail:' + JSON.stringify(err));
}
};
if (payInfo.typePay == 'smallPay') {
// 小程序
payData.provider = 'wxpay';
payData.timeStamp = data.timeStamp;
payData.nonceStr = data.nonceStr;
payData.package = data.package;
// payData.package = "prepay_id=" + data.prepayid;
payData.signType = "MD5";
payData.paySign = data.sign;
} else if (payInfo.typePay == 'wxpay') {
// app微信
payData.provider = 'wxpay';
payData.orderInfo = data;
} else if (payInfo.typePay == 'alipay') {
// app 支付宝
payData.provider = 'alipay';
payData.orderInfo = data.orderInfo;
} else if (payInfo.typePay == 'baidu') {
payData.provider = 'baidu';
payData.orderInfo = data;
}
if (payData.orderInfo != '' && payData.orderInfo != undefined) {
console.log("支付参数", payData);
// let EnvUtils = plus.android.importClass('com.alipay.sdk.app.EnvUtils');
// EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
uni.requestPayment(payData);
}
}, err => {
callback && callback({
success: false,
data: err
});
});
}
// 支付统一分配
export const setPayAssign = function(orderInfo, callback) {
orderInfo.price = orderInfo.price || orderInfo.pricePay;
orderInfo.title = orderInfo.title || orderInfo.orderTitle;
//支付
// #ifdef APP-PLUS
uni.navigateTo({
url: '/pages/home/weChatPay?orderNo=' + orderInfo.orderNo + '&price=' + orderInfo.price +
'&title=' + orderInfo.title
});
// #endif
// #ifdef MP-WEIXIN
setPay({
...orderInfo,
type: "smallPay"
}, res => {
if (res.success) {
uni.redirectTo({
url: "/pages/shopCar/paySuccess?orderNo=" + orderInfo.orderNo
});
}
});
// #endif
// #ifdef H5
if (getBrowser() === '微信') {
wxPublicPay({
orderNo: orderInfo.orderNo
}, function() {
uni.redirectTo({
url: "/pages/shopCar/paySuccess?orderNo=" + orderInfo.orderNo
});
});
} else {
appMutual('setJumpPay', orderInfo);
}
// #endif
}
// 获取地址信息 微信小程序、APP、公众号
export const getLatLon = function(tip) {
return new Promise((resolve, reject) => {
const successProcess = function(res) {
store.commit("setCurrentAddress", {
latitude: res.latitude,
longitude: res.longitude
});
resolve(res);
};
const errProcess = function(err) {
reject(err);
if (tip) {
uni.showToast({
title: err,
icon: "none"
});
}
};
// #ifdef H5
getLatLonH5(successProcess, errProcess);
// #endif
// #ifndef H5
getAppWxLatLon(successProcess, errProcess);
// #endif
});
}
// 查看是否有某本书的权限
export const checkBookRight = function(data, callback) {
console.log('接受的值', data)
$http.request({
url: "/book/user/checkUserBook",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data: data,
header: { //默认 无 说明请求头1
'Content-Type': 'application/json'
},
}).then(res => {
// console.log(res,'checkBookRight')
if (res.code === 0) {
callback && callback({
success: true,
data: '有权限'
});
}
}).catch(e => {
callback && callback({
success: false,
data: '无权限'
});
})
}
// 单独微信支付
export const setWXPay = function(payInfo, callback) {
$http.request({
url: "pay/placeAnOrder/shoppingPay",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data: {
...payInfo,
appName: 'xlkj'
},
header: { //默认 无 说明请求头1
'Content-Type': 'application/json'
},
}).then(res => {
console.log(res, 'resshoppingPay')
if (res.code === 0) {
console.log('接下来走微信接口啦')
let payData = {
provider: 'wxpay',
orderInfo: {
"appid": res.paramMap.appid, // 微信开放平台 - 应用 - AppId注意和微信小程序、公众号 AppId 可能不一致
"noncestr": res.Map.noncestr, // 随机字符串
"package": res.Map.package, // 固定值
"partnerid": res.paramMap.mchid, // 微信支付商户号
"prepayid": res.Map.prepayid, // 统一下单订单号
"timestamp": res.Map.timestamp, // 时间戳(单位:秒)
"signType": "SHA256-RSA",
"sign": res.Map.sign
},
success(res) {
callback && callback({
success: true,
data: res
});
console.log('success:' + JSON.stringify(res));
},
fail(err) {
callback && callback({
success: false,
data: err
});
console.log('微信错误fail:' + JSON.stringify(err));
}
}
// console.log(payData)
if (payData.orderInfo.prepayid != '' && payData.orderInfo.prepayid != undefined) {
uni.requestPayment(payData);
}
}
})
}

20
index.html Normal file
View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,405 @@
/**
* 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
*/
var isIos
// #ifdef APP-PLUS
isIos = (plus.os.name == "iOS")
// #endif
// 判断推送权限是否开启
function judgeIosPermissionPush() {
var result = false;
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
console.log("enabledTypes1:" + enabledTypes);
if (enabledTypes == 0) {
console.log("推送权限没有开启");
} else {
result = true;
console.log("已经开启推送功能!")
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if (enabledTypes == 0) {
console.log("推送权限没有开启!");
} else {
result = true;
console.log("已经开启推送功能!")
}
console.log("enabledTypes2:" + enabledTypes);
}
plus.ios.deleteObject(app);
plus.ios.deleteObject(UIApplication);
return result;
}
// 判断定位权限是否开启
function judgeIosPermissionLocation() {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var status = cllocationManger.authorizationStatus();
result = (status != 2)
console.log("定位权限开启:" + result);
// 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
/* var enable = cllocationManger.locationServicesEnabled();
var status = cllocationManger.authorizationStatus();
console.log("enable:" + enable);
console.log("status:" + status);
if (enable && status != 2) {
result = true;
console.log("手机定位服务已开启且已授予定位权限");
} else {
console.log("手机系统的定位没有打开或未给予定位权限");
} */
plus.ios.deleteObject(cllocationManger);
return result;
}
// 判断麦克风权限是否开启
function judgeIosPermissionRecord() {
var result = false;
var avaudiosession = plus.ios.import("AVAudioSession");
var avaudio = avaudiosession.sharedInstance();
var permissionStatus = avaudio.recordPermission();
console.log("permissionStatus:" + permissionStatus);
if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
console.log("麦克风权限没有开启");
} else {
result = true;
console.log("麦克风权限已经开启");
}
plus.ios.deleteObject(avaudiosession);
return result;
}
// 判断相机权限是否开启
function judgeIosPermissionCamera() {
var result = false;
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
console.log("authStatus:" + authStatus);
if (authStatus == 3) {
result = true;
console.log("相机权限已经开启");
} else {
console.log("相机权限没有开启");
}
plus.ios.deleteObject(AVCaptureDevice);
return result;
}
// 判断相册权限是否开启
function judgeIosPermissionPhotoLibrary() {
var result = false;
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
var authStatus = PHPhotoLibrary.authorizationStatus();
console.log("authStatus:" + authStatus);
if (authStatus == 3) {
result = true;
console.log("相册权限已经开启");
} else {
console.log("相册权限没有开启");
}
plus.ios.deleteObject(PHPhotoLibrary);
return result;
}
// 判断通讯录权限是否开启
function judgeIosPermissionContact() {
var result = false;
var CNContactStore = plus.ios.import("CNContactStore");
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
if (cnAuthStatus == 3) {
result = true;
console.log("通讯录权限已经开启");
} else {
console.log("通讯录权限没有开启");
}
plus.ios.deleteObject(CNContactStore);
return result;
}
// 判断日历权限是否开启
function judgeIosPermissionCalendar() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
if (ekAuthStatus == 3) {
result = true;
console.log("日历权限已经开启");
} else {
console.log("日历权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// 判断备忘录权限是否开启
function judgeIosPermissionMemo() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
if (ekAuthStatus == 3) {
result = true;
console.log("备忘录权限已经开启");
} else {
console.log("备忘录权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// Android权限查询
function requestAndroidPermission(permissionID) {
return new Promise((resolve, reject) => {
plus.android.requestPermissions(
permissionID.split(","),
// [permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
function(resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log('已获取的权限:' + grantedPermission);
result = 1
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
result = 0
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
result = -1
}
resolve(result);
// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
// if (result != 1) {
// gotoAppPermissionSetting()
// }
},
function(error) {
console.log('申请权限错误:' + error.code + " = " + error.message);
resolve({
code: error.code,
message: error.message
});
}
);
});
}
// 使用一个方法,根据参数判断权限
function judgeIosPermission(permissionID) {
if (permissionID == "location") {
return judgeIosPermissionLocation()
} else if (permissionID == "camera") {
return judgeIosPermissionCamera()
} else if (permissionID == "photoLibrary") {
return judgeIosPermissionPhotoLibrary()
} else if (permissionID == "record") {
return judgeIosPermissionRecord()
} else if (permissionID == "push") {
return judgeIosPermissionPush()
} else if (permissionID == "contact") {
return judgeIosPermissionContact()
} else if (permissionID == "calendar") {
return judgeIosPermissionCalendar()
} else if (permissionID == "memo") {
return judgeIosPermissionMemo()
}
return false;
}
// 跳转到**应用**的权限页面
function gotoAppPermissionSetting() {
if (isIos) {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
// console.log(plus.device.vendor);
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
}
}
// 检查系统的设备服务是否开启
// var checkSystemEnableLocation = async function () {
function checkSystemEnableLocation() {
if (isIos) {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var result = cllocationManger.locationServicesEnabled();
console.log("系统定位开启:" + result);
plus.ios.deleteObject(cllocationManger);
return result;
} else {
var context = plus.android.importClass("android.content.Context");
var locationManager = plus.android.importClass("android.location.LocationManager");
var main = plus.android.runtimeMainActivity();
var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
console.log("系统定位开启:" + result);
return result
}
}
let permissionMap = {
"android": {
"CAMERA_EXTERNAL_STORAGE": {
"name": "android.permission.READ_EXTERNAL_STORAGE,android.permission.WRITE_EXTERNAL_STORAGE,android.permission.CAMERA",
"title": "相机/相册权限说明",
"content": "便于您使用该功能上传您的照片/图片用于上传用户头像、留言上传图片、申诉反馈上传图片等场景中读取和写入相册和文件内容"
},
"CAMERA": {
"name": "android.permission.CAMERA",
"title": "相机权限说明",
"content": "便于您使用该功能上传您的照片/图片用于上传用户头像、留言上传图片、申诉反馈上传图片等场景中拍摄图片"
},
// "EXTERNAL_STORAGE": {
// "name": "android.permission.READ_EXTERNAL_STORAGE,android.permission.WRITE_EXTERNAL_STORAGE",
// "title": "相册权限说明",
// "content": "便于您使用该功能上传您的照片/图片/视频及用于上传工单故障、维修图片、扫码识别设备等信息、意见反馈上传图片、上传设备、客户、设备图片等场景中读取和写入相册和文件内容"
// },
// "LOCATION": {
// "name": "android.location.LocationManager",
// "title": "定位权限说明",
// "content": "便于您使用该功能定位您当前的位置,并上报当前位置给服务器,来智能得按照当前位置给您分配距离您最近的工单信息等功能"
// },
"CALLPHONE": {
"name": "android.permission.CALL_PHONE",
"title": "拨打电话权限说明",
"content": "便于您使用该功能能够快速和提交工单信息的客户进行联系并进行及时处理"
},
},
"ios": {}
}
let view = null;
let viewShow = false;
function showViewDesc(permission) {
let plat = isIos ? "ios" : "android";
view = new plus.nativeObj.View('per-modal', {
top: '0px',
left: '0px',
width: '100%',
backgroundColor: 'rgba(0,0,0,0.4)',
//opacity: '.9'
})
view.drawRect({
color: '#fff',
radius: '5px'
}, {
top: '170px',
left: '5%',
width: '90%',
height: "150px",
})
view.drawText(permissionMap[plat][permission]["title"], {
top: '180px',
left: "8%",
height: "30px"
}, {
align: "left",
color: "#000",
}, {
onClick: function(e) {
console.log(e);
}
})
view.drawText(permissionMap[plat][permission]["content"], {
top: '210px',
height: "80px",
left: "8%",
width: "84%"
}, {
whiteSpace: 'normal',
size: "14px",
align: "left",
color: "#656563"
})
setTimeout(() => {
view.show()
}, 200)
}
function premissionCheck(permission) {
return new Promise(async (resolve, reject) => {
let plat = isIos ? "ios" : "android";
if (isIos) { // ios
// const camera = permission.judgeIosPermission("camera");//判断ios是否给予摄像头权限
// //ios相册没权限系统会自动弹出授权框
// //let photoLibrary = permission.judgeIosPermission("photoLibrary");//判断ios是否给予相册权限
// if(camera){
// resolve();
// }else{
// reject('需要开启相机使用权限');
// }
resolve(1)
} else { // android
let permission_arr = permissionMap[plat][permission]["name"].split(",");
let flag = true;
for (let i = 0; i < permission_arr.length; i++) {
let status = plus.navigator.checkPermission(permission_arr[i]);
if (status == "undetermined") {
flag = false;
}
}
if (flag == false) { // 未完全授权
showViewDesc(permission);
requestAndroidPermission(permissionMap[plat][permission]["name"]).then((res) => {
viewShow = false;
setTimeout(() => {
viewShow = true;
}, 120)
view.close();
// if (res == -1) {
// uni.showModal({
// title: '提示',
// content: '操作权限已被拒绝,请手动前往设置',
// confirmText: "立即设置",
// success: (res) => {
// if (res.confirm) {
// gotoAppPermissionSetting()
// }
// }
// })
// }
resolve(res)
})
} else {
resolve(1)
}
}
})
}
module.exports = {
judgeIosPermission: judgeIosPermission,
requestAndroidPermission: requestAndroidPermission,
checkSystemEnableLocation: checkSystemEnableLocation,
gotoAppPermissionSetting: gotoAppPermissionSetting,
premissionCheck: premissionCheck
}

View File

@@ -0,0 +1,42 @@
export default function uniCopy({content,success,error}) {
if(!content) return error('复制的内容不能为空 !')
content = typeof content === 'string' ? content : content.toString() // 复制内容,必须字符串,数字需要转换为字符串
/**
* 小程序端 和 app端的复制逻辑
*/
//#ifndef H5
uni.setClipboardData({
data: content,
success: function() {
success("复制成功~")
console.log('success');
},
fail:function(){
success("复制失败~")
}
});
//#endif
/**
* H5端的复制逻辑
*/
// #ifdef H5
if (!document.queryCommandSupported('copy')) { //为了兼容有些浏览器 queryCommandSupported 的判断
// 不支持
error('浏览器不支持')
}
let textarea = document.createElement("textarea")
textarea.value = content
textarea.readOnly = "readOnly"
document.body.appendChild(textarea)
textarea.select() // 选择对象
textarea.setSelectionRange(0, content.length) //核心
let result = document.execCommand("copy") // 执行浏览器复制命令
if(result){
success("复制成功~")
}else{
error("复制失败请检查h5中调用该方法的方式是不是用户点击的方式调用的如果不是请改为用户点击的方式触发该方法因为h5中安全性不能js直接调用")
}
textarea.remove()
// #endif
}

53
main.js Normal file
View File

@@ -0,0 +1,53 @@
import Vue from 'vue'
import App from './App'
import qs from 'qs'
// uView组件库
import uView from '@/uni_modules/uview-ui'
Vue.use(uView)
//挂载全局http请求
import http from '@/config/requestConfig.js';
Vue.prototype.$http = http
import commonJS from '@/common/commonJS.js'
Vue.prototype.$commonJS = commonJS
//数据管理中心
import store from '@/store'
Vue.prototype.$store = store;
//权限配置中心
import base from '@/config/baseUrl.js'
Vue.prototype.$base = base;
Vue.config.productionTip = false
//判断是否登录
import { judgeLogin } from '@/config/login';
Vue.prototype.judgeLogin = judgeLogin;
Vue.prototype.isShowHtml = store.state.loadingShow;
//Vue.prototype.$baseUrl = "https://api.nuttyreading.com/"
Vue.prototype.$baseUrl = "http://192.168.110.100:9200/pb/"
//判断手机型号
uni.getSystemInfo({
success: function (res) {
Vue.prototype.$platform = res.platform;
Vue.prototype.iosHidden = true;
if (res.platform == 'ios') {
Vue.prototype.iosHidden = false; //ios临时隐藏听书
Vue.prototype.iosHide = true;
} else {
Vue.prototype.iosHide = true;
}
}
})
import commonList from '@/pages/component/commonComponents/list.vue'
Vue.component('common-list', commonList);
App.mpType = 'app'
const app = new Vue({
store,
...App
})
app.$mount()

170
manifest.json Normal file
View File

@@ -0,0 +1,170 @@
{
"name" : "太湖云医",
"appid" : "__UNI__1B1584A",
"description" : "太湖云医",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : false,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"privacy" : {
"prompt" : "template",
"template" : {
"title" : "用户协议和隐私政策",
"message" : "请你务必审慎阅读、充分理解“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>你可阅读<a href='https://www.taimed.cn/agreement.html'>《用户协议》</a>和<a href='https://www.taimed.cn/privacy.html'>《隐私协议》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept" : "同意",
"buttonRefuse" : "暂不同意"
}
},
/* */
"modules" : {
"Camera" : {},
"Payment" : {}
},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
"minSdkVersion" : 23,
"targetSdkVersion" : 35,
"schemes" : "taimed"
},
/* ios */
"ios" : {
"urlschemewhitelist" : "nuttyreading,medicine",
"idfa" : false,
"urltypes" : "taimed",
"capabilities" : {
"entitlements" : {
"com.apple.developer.associated-domains" : [
"applinks:static-mp-3614b80b-2d75-4462-a481-4998f8187274.next.bspapp.com",
"applinks:verification.nuttyreading.com"
]
}
},
"dSYMs" : false
},
/* SDK */
"sdkConfigs" : {
"payment" : {
"appleiap" : {},
"alipay" : {
"__platform__" : [ "ios", "android" ]
},
"weixin" : {
"__platform__" : [ "ios", "android" ],
"appid" : "wx5c50e3696028d2ec",
"UniversalLinks" : "https://verification.nuttyreading.com/uni-universallinks/__UNI__1B1584A/"
}
}
},
"splashscreen" : {
"useOriginalMsgbox" : true
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true,
"setting" : {
"urlCheck" : false
}
},
"mp-toutiao" : {
"usingComponents" : true,
"setting" : {
"urlCheck" : false
}
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2",
"h5" : {
"devServer" : {
"https" : false
},
"optimization" : {
"treeShaking" : {
"enable" : true
}
}
},
"_spaceID" : "mp-3614b80b-2d75-4462-a481-4998f8187274",
"mp-qq" : {
"setting" : {
"urlCheck" : false
}
}
}

223
pages.json Normal file
View File

@@ -0,0 +1,223 @@
{
"pages": [ //pages数组中第一项表示应用启动页参考https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/home/index",
"style": {
"navigationBarTitleText": "首页",
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/my/index",
"style": {
"navigationBarTitleText": "我的",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/my/recordsList",
"style": {
"navigationBarTitleText": "历史记录",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/user/login",
"style": {
"navigationBarTitleText": "登录",
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/user/forget",
"style": {
"navigationBarTitleText": "忘记密码",
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/user/workOrder",
"style": {
"navigationBarTitleText": "问题反馈",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/my/index",
"style": {
"navigationBarTitleText": "我的",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/my/set",
"style": {
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/my/persData",
"style": {
"navigationBarTitleText": "个人资料",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/my/aboutUs",
"style": {
"navigationBarTitleText": "关于我们",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/talents/index",
"style": {
"navigationBarTitleText": "太湖英才",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/talents/detail",
"style": {
"navigationBarTitleText": "太湖英才",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/doctors/index",
"style": {
"navigationBarTitleText": "名医精彩",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/wumen/index",
"style": {
"navigationBarTitleText": "吴门医述",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
//提示更新的弹窗
{
"path": "uni_modules/uni-upgrade-center-app/pages/upgrade-popup",
"style": {
"app-plus": {
"animationDuration": 200,
"animationType": "fade-in",
"background": "transparent",
"backgroundColorTop": "transparent",
"popGesture": "none",
"scrollIndicator": false,
"titleNView": false
},
"disableScroll": true
}
}
],
"tabBar": {
"color": "#333",
"selectedColor": "#5188e5",
"borderStyle": "black",
"backgroundColor": "#fff",
"list": [{
"pagePath": "pages/home/index",
"text": "智慧医疗"
},
{
"pagePath": "pages/talents/index",
"text": "太湖英才"
},
// {
// "pagePath": "pages/doctors/index",
// "text": "名医精彩"
// },
// {
// "pagePath": "pages/wumen/index",
// "text": "吴门医述"
// },
{
"pagePath": "pages/my/index",
"text": "我的"
}
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}

View File

@@ -0,0 +1,129 @@
<template>
<view style="width: 100%; height: 100%;">
<view v-if="axiosStatus!=''">
<scroll-view @scrolltolower="lower" scroll-y="true" class="scroll-Y" v-if="dataList&&dataList.length > 0"
style="height: 100%">
<view @click="gotoDetail(item, index)" class="scroll-view-item list_item"
v-for="(item, index) in dataList" :key="indexKey ? item[indexKey] : item.id"
:index="indexKey ? item[indexKey] : index">
<view :class="['titleItem', '']" :style="`width:${isNoIcon ? '100%' : 'calc(100% - 30rpx)'}`">
<slot name="leftSlot" :row="item" :item="item" :index="index"> </slot>
<template v-if="isCondition">
<slot name="labelSlot" :row="item" :rowIndex="index"></slot>
</template>
<template v-else>
{{ item[label] }}
</template>
<slot name="rightSlot" :row="item" :rowIndex="index"></slot>
</view>
<image v-if="!isNoIcon" src="@/static/icon/icon_right.png" class="rightArrow" style=""></image>
</view>
</scroll-view>
<u-empty v-else-if="noDataIcon && isLoadingHide" :mode="noDataIcon"
:icon="`http://cdn.uviewui.com/uview/empty/${noDataIcon}.png`">
</u-empty>
<u-divider style="width: 100%;" v-else-if="!isOrderList" text="暂无数据"></u-divider>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
props: [
"indexKey",
"dataList",
"label",
"isCondition",
"isNoIcon",
"pagination",
"noDataIcon",
"isLoadingHide",
"axiosStatus",
"isOrderList"
],
data() {
return {
status: '',
};
},
onLoad() {},
onShow() {
this.status = '';
},
computed: {
...mapState(["userInfo"]),
},
methods: {
lower() {
this.$emit("lower");
},
gotoDetail(data, index) {
this.$emit("hancleClick", data, index);
},
},
onBackPress() {
// #ifdef APP-PLUS
plus.key.hideSoftKeybord();
// #endif
},
components: {},
};
</script>
<style lang="scss" scoped>
.list_item {
width: 100%;
padding: 20rpx 20rpx;
font-size: 30rpx;
box-sizing: border-box;
border-bottom: 1rpx solid #e0e0e0;
display: flex;
align-items: center;
justify-content: space-between;
}
.list_item :last-child(1) {
border-bottom: none;
}
.scroll-view-item:nth-child(2n-1) {
background-color: #f5f5f5 !important;
}
.rightArrow {
width: 40rpx;
height: 40rpx;
}
.scroll-Y {
height: 100%;
}
.scroll-view_H {
white-space: nowrap;
width: 100%;
}
.scroll-view-item_H {
display: inline-block;
width: 100%;
}
.titleItem {
width: calc(100% - 30rpx);
}
/deep/.scroll-view-item:nth-child(2n-1) {
background-color: transparent !important;
}
.list_item:last-child {
border-bottom: none !important;
}
</style>

55
pages/doctors/index.vue Normal file
View File

@@ -0,0 +1,55 @@
<template>
<view class="content">
<z-nav-bar title="名医精彩"></z-nav-bar>
<z-navigation></z-navigation>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
export default {
data() {
return {
list: [],
}
},
onLoad() {
uni.hideTabBar();
},
onShow() {
uni.removeStorageSync('homeParams');
},
methods: {
//获取数据
getData() {
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'common/ragFlowApi/getChatAssistants',
method: "POST",
data: {},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
uni.hideLoading();
if (res.list&&res.list.length>0) {
}
});
}
},
}
</script>
<style lang="scss" scoped>
@import '@/static/mixin.scss';
.content{
height: 100%;
overflow: auto;
background-color: #fff;
}
</style>

806
pages/home/index.vue Normal file
View File

@@ -0,0 +1,806 @@
<template>
<view class="content">
<view class="home_top">
<view class="home_top_icon">
<image src='../../static/icon/icon_bars.png' class="home_top_left" @click="openDrawer"></image>
<image src='../../static/icon/icon_dialog.png' class="home_top_right" @click="showMode"></image>
</view>
<text>智慧医疗</text>
</view>
<view class="home_wrap" v-if="!showMessages">
<view class="home_logo">
<image src='../../static/logo.png'></image>
<text class="logo_main">我是太湖云医的智慧医疗<br/>很高兴见到您</text>
<text class="logo_con">我是您的诊断小助手您可以把情况发给我我会结合太湖学堂知识数据库为您进行分析解答</text>
</view>
<view class="home_form">
<template>
<view class="form_item">
<text>西医诊断</text>
<input type="text" v-model="formData.diagnosis" placeholder="请输入西医诊断" placeholder-class="custom-placeholder" />
</view>
<view class="form_item">
<text>详细病情</text>
<textarea v-model="formData.illness" maxlength="-1"
auto-height
placeholder="请输入详细病情"
placeholder-class="custom-placeholder" />
</view>
<view class="form_item">
<text>主要症状</text>
<textarea auto-height v-model="formData.symptoms" maxlength="-1"
placeholder="请输入主要症状" placeholder-class="custom-placeholder" />
</view>
<view class="form_item form_item_genetic">
<text>基因检测阳性</text>
<input type="text" v-model="formData.genetic" placeholder="选填" placeholder-class="custom-placeholder" />
</view>
<view class="form_item">
<text>患者姓名</text>
<input type="text" v-model="formData.name" placeholder="如果您是医生,建议填写" placeholder-class="custom-placeholder" />
</view>
</template>
</view>
</view>
<view class="submit_form" v-if="!showMessages">
<view class="assistants_list">
<view v-for="(item,index) in chatAssistants" :key="index"
@click="clickAssistants(item,index)"
class="assistants_item"
:class="activeIndex==index?'active':''"
>
<image class="assistants_img_1" :src="item.icon_1" mode="widthFix" ></image>
<image class="assistants_img_2" :src="item.icon_2" mode="widthFix" ></image>
<text>{{item.name}}</text>
</view>
</view>
<button class="submit_btn" @click="submit">
<image src='../../static/icon/icon_submit.png'></image>
</button>
</view>
<view class="message_wrap" :style="{ top: 82 + 'px' }" v-if="showMessages">
<text class="message_title" v-if="tishi">好的结合您的情况下面是分析结果</text>
<!-- 显示聊天记录 -->
<view class="message-container-block" ref="messageContainerBlock">
<view class="message-container" v-for="(item, index) in messages" :key="index"
:class="{'message-left': item.type === 'answer', 'message-right': item.type === 'question'}">
<text v-html="item.content"></text>
</view>
<view class="loading-spinner" v-if="loading"></view>
</view>
<view class="submit_form submit_form_2">
<view class="assistants_list">
<textarea auto-height v-model="question_send" placeholder="给智慧医疗发送消息" placeholder-class="custom-placeholder" />
</view>
<button class="submit_btn" @click="sendAgain">
<image src='../../static/icon/icon_submit.png' v-if="!pauseStatus"></image>
<image src='../../static/icon/icon_submit_pause.png' v-if="pauseStatus"></image>
</button>
</view>
</view>
<!-- 左侧弹窗 -->
<uni-drawer ref="drawer" mode="left" :width="230">
<view class="drawer-content">
<scroll-view scroll-y="true" class="list_content" v-if="record_list.length>0">
<view v-for="(item, index) in record_list" :key="index" class="list_item"
:class="activeRecord == index?'active_item':''"
@click="clickRecord(item, index)">
<text class="text_item">{{ item.chatName }}</text>
</view>
</scroll-view>
<view class="null_text" v-else>{{ null_text }}</view>
</view>
</uni-drawer>
<z-navigation></z-navigation>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
import { mapState, mapMutations } from "vuex";
export default {
data() {
return {
containerHeight: null,
formData: {
diagnosis: '',
illness: '',
symptoms: '',
genetic: '',
name: '',
},
chatId: null, //选择助手的id
chatName: '',
chatAssistants: [],
activeIndex: null,
sessionId: null, //对话id
eventSource: null,
showMessages: false,
loading: false,
question: '', //传递的问题
messages: [],
previousAnswer: null, //存储上一条回答内容
question_send: '',
pauseStatus: false, //暂停操作
record_list: [], //对话列表
null_text: '',
activeRecord: null,
tishi: false, //提示语
}
},
computed: {
...mapState(["userInfo"]),
},
mounted() {
},
onLoad() {
uni.hideTabBar();
uni.removeStorageSync('homeParams');
//获取设备信息
const systemInfo = uni.getSystemInfoSync();
this.containerHeight = systemInfo.windowHeight; //获取设备的窗口高度
this.getChatAssistants();
},
onShow(){
this.showMessages = false;
this.activeRecord = null;
this.getRecordsData();
//我的-会话记录跳转来的
let data = uni.getStorageSync('homeParams').data;
let index = uni.getStorageSync('homeParams').index;
if(data){
this.clickRecord(data, index);
}
},
methods: {
//获取病症种类数据
getChatAssistants() {
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'common/ragFlowApi/getChatAssistants',
method: "POST",
data: {},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
if (res.list&&res.list.length>0) {
uni.hideLoading();
res.list = res.list.filter(item => {
return !item.name.includes('心理助手') && !item.name.includes('太湖云翳');
});
res.list.forEach(item => {
if (item.name === "呼吸专科") {
item.icon_1 = '../../static/icon/iocn_zs_2.png';
item.icon_2 = '../../static/icon/iocn_zs_2_a.png';
} else if (item.name === "妇科专科") {
item.icon_1 = '../../static/icon/iocn_zs_5.png';
item.icon_2 = '../../static/icon/iocn_zs_5_a.png';
} else if (item.name === "风湿免疫专科") {
item.icon_1 = '../../static/icon/iocn_zs_3.png';
item.icon_2 = '../../static/icon/iocn_zs_3_a.png';
} else if (item.name === "消化专科") {
item.icon_1 = '../../static/icon/iocn_zs_1.png';
item.icon_2 = '../../static/icon/iocn_zs_1_a.png';
} else if (item.name === "肿瘤专科") {
item.icon_1 = '../../static/icon/iocn_zs_4.png';
item.icon_2 = '../../static/icon/iocn_zs_4_a.png';
} else if (item.name === "全科医生") {
item.icon_1 = '../../static/icon/iocn_zs_6.png';
item.icon_2 = '../../static/icon/iocn_zs_6_a.png';
}
});
this.chatAssistants = res.list;
}
})
.catch(e=>{
uni.setStorageSync("guidePages", 2);
});
},
//获取对话记录数据
getRecordsData() {
this.$http.request({
url: 'common/ragFlowApi/getChats',
method: "POST",
data: {
chatId: '',
sessionId: '',
page: 1,
pageSize: 300
},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
if(res.code==0){
if(res.list&&res.list.length>0){
this.record_list = res.list;
}else{
this.null_text = '暂无数据';
}
}
})
.catch(e=>{
uni.setStorageSync("guidePages", 2);
uni.redirectTo({
url: "/pages/user/login",
});
});
},
//点击每个记录
clickRecord(item,index){
//重新定义id
this.chatId = item.chatAssistantId;
this.sessionId = item.chatId;
this.activeRecord = index;
this.messages = [];
this.showMessages = true;
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'common/ragFlowApi/getChats',
method: "POST",
data: {
chatId: item.chatAssistantId,
sessionId: item.chatId,
page: 1,
pageSize: 300
},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
if(res.code==0){
uni.hideLoading();
if(res.list&&res.list.length>0){
this.messages = res.list.map(item => {
let content = item.content.replace(/##\d+$$/g, '');
content = content.replace(/<\/?think>/g, '');
content = content.replace(/\*\*(.*?)\*\*/g, '<b class="bold-text">$1</b>');
content = content.replace(/\*(.*?)\*/g, '<span class="red-text">$1</span>');
content = content.replace(/\n\n/g, '\n');
content = content.replace(/\n/g, '<br>');
content = content.replace(/^#{3,4}.*(\r?\n)?/gm, '');
return {
...item,
type: item.type === 1 ? 'answer' : 'question',
content: content
};
});
}
this.tishi = false; //提示语不用展示
this.$refs.drawer.close();
}
});
},
//
//选中科目类别
clickAssistants(item, index){
this.activeIndex = index;
this.chatId = item.id;
this.chatName = item.name;
},
//提交
submit(){
if(!this.formData.diagnosis){
this.$commonJS.showToast("请输入西医诊断");
return
}
if(!this.formData.illness){
this.$commonJS.showToast("请输入详细病情");
return
}
if(!this.formData.symptoms){
this.$commonJS.showToast("请输入主要症状");
return
}
if(!this.chatId){
this.$commonJS.showToast("请选择助手分类");
return
}
let question = '';
if(this.formData.name){
question += '患者'+this.formData.name+'';
}
if(this.formData.diagnosis){
question += '诊断:'+this.formData.diagnosis+'';
}
question += '病情为:'+this.formData.illness+''+this.formData.symptoms+',请根据这位患者的情况出一个中医治疗方案';
this.question = question;
//创建对话 获取sessionId
this.createChat();
},
//创建新对话
createChat(){
let data = {
chatId: this.chatId,
name: this.question.slice(0, 30)
}
this.$http.request({
url: 'common/ragFlowApi/createChat',
method: "POST",
data: data,
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
if (res.code==0) {
this.sessionId = res.id;
//获取回答
this.sendQuestion();
}
});
},
//交谈请求,获取回答
sendQuestion(){
//清空消息记录
this.messages = [];
this.showMessages = true;
this.pauseStatus = true;
this.loading = true;
//展示提示语
this.tishi = true;
const params = {
chatId: this.chatId,
chatName: this.chatName,
question: this.question,
sessionId: this.sessionId,
sessionName: this.question.slice(0, 30),
patientName: this.formData.name
};
//调用后端 SSE 接口,发送问题并接收实时回答
this.startSSE(params);
},
//开始监听 SSE 数据
startSSE(params){
// 拼接查询字符串
const query = new URLSearchParams({
...params,
token: uni.getStorageSync('token')
}).toString();
// 创建 SSE 连接
this.eventSource = new EventSource(this.$baseUrl+`common/ragFlowApi/chatToAssistantStream?${query}`);
// 监听服务器发送的消息
this.eventSource.onmessage = (event) => {
try {
const message = JSON.parse(event.data);
if (message.data === true) {
console.log("回答已结束");
this.pauseStatus = false;
this.eventSource.close();
this.loading = false;
return;
}
const answer = message.data.answer.replace(/##\d+$$/g, '');
let newAnswer = ''; //初始化 newAnswer 变量
if(this.previousAnswer === null){
console.log("第一次进来")
//如果没有包含上一条的内容,则直接显示当前 answer
newAnswer = answer;
this.messages.push({ content: newAnswer, type: 'answer' });
this.previousAnswer = newAnswer;
}else{
//只显示新增的部分
newAnswer = answer.replace(this.previousAnswer, '');
newAnswer = newAnswer.replace(/\*\*(.*?)\*\*/g, '<b class="bold-text">$1</b>');
newAnswer = newAnswer.replace(/\*(.*?)\*/g, '<span class="red-text">$1</span>');
newAnswer = newAnswer.replace(/\n\n/g, '\n');
newAnswer = newAnswer.replace(/\n/g, '<br>');
newAnswer = newAnswer.replace(/####([\s\S]*?)$/gm, '<h4>$1</h4>')
.replace(/###([\s\S]*?)$/gm, '<h3>$1</h3>');
this.messages.push({ content: newAnswer, type: 'answer' });
this.previousAnswer = answer;
}
} catch (error) {
this.$commonJS.showToast("处理消息时发生错误");
}
};
//监听 SSE 连接关闭
this.eventSource.onclose = () => {
console.log("SSE 连接已关闭");
this.loading = false;
};
//监听 SSE 错误
this.eventSource.onerror = (error) => {
console.error("SSE 连接发生错误", error);
this.loading = false;
};
//获取最近的会话记录数据
this.getRecordsData();
},
//回答界面的提交
sendAgain(){
console.log('这是再一次提问')
if(!this.question_send){
this.$commonJS.showToast("请输入发送内容");
return
}
const params = {
chatId: this.chatId,
chatName: this.chatName,
question: this.question_send,
sessionId: this.sessionId,
sessionName: this.question_send.slice(0, 15),
patientName: this.formData.name
};
this.messages.push({
content: `${this.question_send}`,
type: 'question',
});
this.loading = true;
this.question_send = '';
this.pauseStatus = true;
this.previousAnswer = null;
//调用后端 SSE 接口,发送问题并接收实时回答
this.startSSE(params);
},
//点击左侧弹窗
openDrawer() {
this.$refs.drawer.open();
},
//点击新会话
showMode(){
this.showMessages = false;
this.messages = [];
this.formData = {
diagnosis: '',
illness: '',
symptoms: '',
genetic: '',
name: ''
}
this.chatId = null;
this.activeIndex = null;
this.activeRecord = null;
if(this.eventSource){
this.eventSource.close();
}
this.previousAnswer = null;
this.pauseStatus = false;
}
},
beforeDestroy() {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/mixin.scss';
.content{
background: linear-gradient(to bottom, #d8e6ff 20%, #ffffff 100%);
}
.home_top{
width: 100%;
background: #fff;
position: fixed;
top: 0;
left: 0;
padding: 90rpx 50rpx 30rpx;
text-align: center;
box-sizing: border-box;
z-index: 999;
.home_top_icon{
position: absolute;
left: 50rpx;
top: 90rpx;
display: flex;
align-items: center;
.home_top_left,.home_top_right{
width: 40rpx;
height: 40rpx;
}
.home_top_right{
margin-left: 40rpx;
}
}
text{
font-size: 43rpx;
font-weight: bold;
color: $themeColor;
}
}
.home_wrap{
margin: 170rpx 50rpx 0;
.home_logo{
padding-top: 40rpx;
image{
display: block;
width: 130rpx;
height: 130rpx;
margin: 0 auto;
}
.logo_main{
text-align: center;
display: block;
padding-top: 30rpx;
font-size: 35rpx;
color: $themeColor;
line-height: 46rpx;
}
.logo_con{
display: block;
width: 490rpx;
margin: 30rpx auto;
font-size: 28rpx;
color: #303030;
line-height: 40rpx;
text-indent: 2em;
}
}
}
.home_form{
margin-top: 60rpx;
.form_item{
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 30rpx;
text{
line-height: 65rpx;
font-size: 30rpx;
color: #fff;
background: $themeBgColor;
text-align: center;
border-radius: 20rpx;
padding: 0 25rpx;
}
textarea,input{
display: inline-block;
width:calc(100% - 255rpx);
height: 70rpx;
line-height: 36rpx;
padding: 17rpx 30rpx;
font-size: 28rpx;
color: #303030;
border-radius: 50rpx;
border: 1rpx solid #777778;
box-sizing: border-box;
resize: none;
max-height: 200rpx;
overflow-y: scroll;
}
}
}
.custom-placeholder{
font-size: 25rpx;
color: #8b8c90 !important;
}
.submit_form{
width: 100%;
height: 90px;
background: #fff;
position: fixed;
left: 0;
bottom: 120rpx;
padding: 0 50rpx;
z-index: 999;
}
.submit_form_2{
height: 145rpx;
padding: 30rpx;
.assistants_list{
textarea,input{
width: calc(100% - 65px);
font-size: 26rpx;
line-height: 34rpx;
border-radius: 50rpx;
padding: 22rpx 30rpx;
color: #303030;
background: #f3f4f6;
max-height: 72rpx;
overflow: hidden;
}
}
.submit_btn{
top: 42rpx;
}
}
.assistants_list{
display: flex;
align-items: center;
flex-wrap: wrap;;
.assistants_item{
display: flex;
align-items: center;
width: 217rpx;
margin-top: 30rpx;
image{
width: 38rpx;
height: 38rpx;
}
text{
padding-left: 10rpx;
display: inline-block;
font-size: 28rpx;
color: #606061;
}
.assistants_img_1{
display: block;
}
.assistants_img_2{
display: none;
}
}
}
.submit_btn{
position: absolute;
right: 50rpx;
top: 90rpx;
image{
width: 55rpx;
height: 55rpx;
}
}
.active{
text{
color: $themeBgColor;
}
.assistants_img_1{
display: none !important;
}
.assistants_img_2{
display: block !important;
}
}
.message_wrap{
position: relative;
width: 100%;
background: #fff;
z-index: 99;
padding: 0 50rpx;
overflow: scroll;
}
.message_title{
text-align: center;
font-size: 34rpx;
color: #333;
line-height: 50rpx;
display: block;
font-weight: bold;
padding: 10rpx 0;
}
.message-container-block{
padding-top: 10rpx;
padding-bottom: 150px;
font-size: 30rpx;
}
.message-container {
display: inline;
}
.message-item {
}
/* 自定义的loading效果 */
.loading-spinner {
margin-top: 10rpx;
border: 2px solid #f3f3f3; /* 灰色背景 */
border-top: 2px solid #3498db; /* 蓝色顶部 */
border-radius: 50%;
width: 16px;
height: 16px;
animation: spin 1s linear infinite; /* 旋转动画 */
}
/* 旋转动画 */
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.bold-text {
display: block;
font-weight: bold;
font-size: 28rpx; /* 增大字号 */
}
h3{
font-size: 36rpx;
font-weight: bold;
}
h3{
font-size: 32rpx;
}
.red-text {
color: red;
font-size: 28rpx; /* 增大字号 */
}
.message-right{
display: block;
text-align: right;
margin: 30rpx 0;
text{
display: inline-block;
padding: 20rpx;
line-height: 34rpx;
background-color: rgba(81, 136, 229, 0.2);
border-radius: 15rpx;
color: #333;
font-size: 28rpx;
text-align: left;
}
}
.drawer-content {
height: 100vh;
display: flex;
flex-direction: column;
}
.list_content{
padding: 30rpx 20rpx;
overflow-y: auto;
}
.list_item{
padding: 20rpx 10rpx;
}
.text_item{
display: block;
width: 100%;
font-size: 30rpx;
line-height: 40rpx;
padding: 0 10rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.null_text{
display: block;
text-align: center;
font-size: 30rpx;
color: #999;
padding-top: 150rpx;
}
.active_item{
background: #d8e6ff;
border-radius: 15rpx;
text{
color: #5188e5;
}
}
</style>

76
pages/my/aboutUs.vue Normal file
View File

@@ -0,0 +1,76 @@
<template>
<view class="commonPage">
<z-nav-bar title="关于我们"></z-nav-bar>
<view class="APPinfo">
<image src="@/static/logo_zi.png" mode="" style="height: 230rpx; width: 240rpx; margin: 0 auto;"></image><br/>
<p v-if="versionCode">版本信息{{versionName}},{{versionCode}}</p>
</view>
<view class="telInfo">
<view class="nav_list flexbox">
<text>客服热线</text>
<view class="view1" @click="makeTel">
<uni-icons type="phone" size="20" color="#5188e5"></uni-icons>
<text>022-24142321</text>
</view>
</view>
</view>
<view class="prof">
太湖云医是一款以吴雄志老师独有的一以贯之的中医学针灸学与心学学术体系把精准医学思想引入传统医学将中西医有机整合医学与心理学有机整合同时将心理学与东方心学及国学的有机融合为患者及医生提供现代医学中医学与心理学的治疗预防及康复指导意见的一款app
</view>
<view style="text-align: right; padding-right: 20rpx; padding-top: 30rpx;">
<uni-link href="https://soulspace.taihumed.com/privacy.html" text="隐私政策"></uni-link>
</view>
</view>
</template>
<script>
export default {
data() {
return {
playData:{},
versionCode:null,
versionName:null
}
},
onLoad() {
this.getAppInfo()
},
methods: {
// 获取版本信息
getAppInfo(){
let that = this
plus.runtime.getProperty(plus.runtime.appid, function(inf) {
that.versionCode = inf.version
that.versionName = inf.name
});
},
makeTel(){
uni.showModal({
title: '提示',
content: '微信号yilujiankangkefu'
})
}
}
}
</script>
<style scoped lang="scss">
@import '@/static/mixin.scss';
.commonPage{
background: #fff;
padding: 0 20rpx;
}
.prof{ color: #666; font-size: 28rpx; line-height: 42rpx; padding: 30rpx 10rpx;}
.telInfo{background-color:#fff;
.nav_list{padding: 30rpx 0; border-top: 1px solid #e5e5e5; border-top: 1px solid #e5e5e5; justify-content: space-between; color: #666;
.view1{ display: flex; align-items: center;}
}
}
.APPinfo{background-color:#fff; padding: 40rpx 0; text-align: center;
p{font-size: 28rpx;}
}
.flexbox{display: flex; justify-content: center;}
</style>

764
pages/my/index.vue Normal file
View File

@@ -0,0 +1,764 @@
<template>
<view class="commonPage commonPageBox">
<view class="bg_top">
<u-icon @click="goSetting" class="setIcon" labelColor="#5188e5" labelPos="bottom" label="设置" name="setting"
:style="`top:${(20 + statusBarHeight) * 2}rpx`" color="#5188e5" size="22"></u-icon>
</view>
<view class="mine_box" :style="`top:${(80 + statusBarHeight) * 2}rpx`">
<view class="per_mes">
<view class="per_mes_user">
<view style="display: flex; align-items: center; flex-direction: column">
<image @click="goUserInfo" :src="userMes.avatar" v-if="userMes.avatar&&userMes.avatar!=''"
class="per_mes_img color_shandow"></image>
<image src="../../static/image.png" v-if="userMes.avatar == null||userMes.avatar == ''"
class="per_mes_img color_shandow"></image>
</view>
</view>
<view class="userInfoBox">
<view class="name">{{ userMes.nickname ? userMes.nickname : "未设置" }}</view>
<view class="phone" v-if="userMes.tel">手机号({{ userMes.tel }})</view>
</view>
<br clear="both" />
</view>
<view class="list_box">
<view class="xiugai boxShadow box_fillet">
<common-list :dataList="pageList" @hancleClick="handleClickTab" label="name">
<template slot="rightSlot" slot-scope="slotProps">
<text class="fdButtonBox aui-text-success"
style="line-height: 40rpx">{{ slotProps.row.content }}</text>
</template>
</common-list>
</view>
</view>
</view>
<z-navigation></z-navigation>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
import {
mapState,
mapMutations
} from "vuex";
export default {
data() {
return {
userMes: {},
pageList: [
{
name: "会话记录",
url: "/pages/my/recordsList",
type: "pageJump",
},
{
name: "个人资料",
url: "/pages/my/persData",
type: "pageJump",
},
{
name: "关于我们",
url: "/pages/my/aboutUs",
type: "pageJump",
},
{
name: "问题反馈/申诉",
url: "/pages/user/workOrder",
type: "pageJump"
}
]
};
},
//第一次加载
onLoad(e) {
uni.hideTabBar();
},
computed: {
...mapState(["userInfo"]),
},
//页面显示
onShow() {
uni.removeStorageSync('homeParams');
this.getData();
},
//方法
methods: {
...mapMutations(["setUserInfo"]),
//跳转设置
goSetting() {
this.onPageJump("/pages/my/set");
},
//获取个人信息
goUserInfo() {
this.onPageJump("/pages/my/persData");
},
//点击切换
handleClickTab(v) {
switch (v.type) {
case "pageJump":
this.onPageJump(v.url);
break;
case "switchTab":
this.switchTab(v.url);
break;
}
},
//获取个人信息
getData() {
if (this.userInfo.id != undefined) {
this.$http.post("common/user/getUserInfo").then((res) => {
this.userMes = res.result;
});
}
},
onPageJump(url) {
uni.navigateTo({
url: url,
});
},
switchTab(url) {
uni.switchTab({
url: url,
});
},
},
};
</script>
<style lang="scss" scoped>
@import "@/static/mixin.scss";
.commonPage{
background-image: linear-gradient(to bottom, #d8e6ff 20%, #ffffff 100%);
}
.per_mes {
padding: 0 30rpx;
margin-bottom: 20rpx;
position: relative;
align-items: center;
display: flex;
align-items: center;
.per_mes_img {
width: 120rpx;
height: 120rpx;
border-radius: 90rpx;
margin: 0 0 0 0;
float: left;
}
.userInfoBox{
padding-left: 20rpx;
}
view {
.name {
width: 100%;
font-size: 30rpx;
line-height: 40rpx;
color: #333;
}
.phone {
font-size: 26rpx;
line-height: 42rpx;
color: #666;
}
.per_user_img {
display: inline-block;
width: 40upx;
height: 40upx;
margin-left: 10rpx;
vertical-align: super;
}
}
}
.now_vip {
background-color: #fff;
margin: 0 0 30upx 0;
padding: 0 30upx;
height: 120upx;
background-image: linear-gradient(90deg, #feeed6 0%, #f5ce99 100%);
image {
width: 46rpx;
height: 50rpx;
display: inline-block;
vertical-align: text-bottom;
margin: 0 10rpx 0 0;
}
text {
font-size: 30upx;
line-height: 120upx;
color: #977749;
font-weight: bold;
}
.kt_btn {
font-size: 26upx;
display: block;
float: right;
border-radius: 50rpx;
color: #fffbf6;
padding: 12rpx 26rpx;
margin: 33rpx 0 0 0;
background-image: linear-gradient(90deg, #dfa964 0%, #7f5218 100%);
}
}
.chong_zhi {
box-shadow: none;
padding: 0 30upx;
height: auto;
.zhanghu {
width: 100%;
margin-bottom: 10rpx;
font-size: 44rpx;
font-weight: bold;
display: flex;
align-items: center;
justify-content: space-between;
color: $themeColor;
font-weight: 700;
}
.noVip {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20rpx;
.zhanghu {
font-size: 42rpx;
width: auto;
display: inline-block;
margin-bottom: 0rpx;
text-align: center;
display: flex;
align-items: center;
}
}
.chong_list {
display: flex;
align-items: center;
font-size: 30rpx;
justify-content: space-between;
.left {
display: flex;
align-items: center;
}
.chong_list_item {
width: auto;
height: 100rpx;
margin-right: 60rpx;
text-align: center;
display: inline-block;
color: #294a97;
.text {
font-size: 30rpx;
display: block;
font-weight: 700;
color: #294a97 !important;
}
}
.chong_btn {
font-size: 26rpx;
border-radius: 50rpx;
color: #fffbf6;
padding: 8rpx 32rpx;
background: $themeBgColor;
}
}
}
.xiugai {
border-radius: 10rpx !important;
margin: 0 30rpx;
background: rgba(255, 255, 255, 0.65);
.nav_list {
background-color: #b7e0e2;
padding: 15rpx 0 15rpx 10rpx;
display: flex;
align-items: center;
font-size: 22rpx;
position: relative;
font-weight: bold;
border-bottom: 1px solid #e5e5e5;
&:active {
background-color: #f5f5f5;
}
text {
color: #333;
margin-left: 10rpx;
}
&::after {
content: "";
position: absolute;
right: 20rpx;
top: 50%;
transform: translateY(-50%);
width: 30rpx;
height: 30rpx;
background-image: url("@/static/icon/icon_right.png");
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
}
.nav_list:nth-last-child(1) {
border-bottom: 0;
}
}
.box_fillet {
border-radius: 40rpx;
overflow: hidden;
}
.chongzhi_box {
position: relative;
width: calc(100%);
height: 100%;
float: left;
padding: 20rpx 30rpx;
background: rgba(255, 255, 255, 0.65);
border-radius: 10rpx;
box-shadow: 0px 0px 5px 1px rgba(0, 82, 79, 0.1);
}
.bg_top {
padding: 0 30rpx;
height: 30vh;
position: relative;
.setIcon {
position: absolute;
right: 30rpx;
}
}
.mine_box {
width: 100%;
position: absolute;
left: 0;
padding: 0 0rpx;
}
.list_box {
padding: 40rpx 0;
}
.pay_item_img {
display: flex;
color: #333;
align-items: center;
padding: 0;
box-sizing: border-box;
font-weight: bold;
margin: 0 auto;
margin-bottom: 10rpx;
}
.popup_box {
padding-bottom: 20rpx;
width: 88vw;
overflow: hidden;
position: relative;
height: auto;
.title {
font-family: PangMenZhengDaoBiaoTiTiMianFeiBan;
font-weight: normal;
font-size: 46rpx;
color: $themeColor;
padding: 20rpx;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
.content {
font-size: 26rpx;
letter-spacing: 0.15rpx;
padding: 20rpx;
color: #3f3f3f;
.top {
margin: 30rpx 0;
}
.center {
line-height: 40rpx;
}
.bottom {
width: 100%;
margin-top: 60rpx;
font-size: 24rpx;
line-height: 26rpx;
color: #b0b0b0;
}
}
.button_box {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 20rpx;
.u-button {
margin-left: 40rpx;
}
.u-button:nth-child(1) {
margin-left: 0;
}
}
}
.modal_vip{
margin-top: 50rpx;
padding: 20rpx 20rpx 0;
height: auto;
display: flex;
align-items: center;
justify-content: space-between;
}
.cate_box {
width: 100%;
height: auto;
display: flex;
justify-content: center;
box-shadow: 0rpx 0rpx 6rpx 0rpx #f9f6ea;
border-radius: 7rpx;
display: flex;
align-items: center;
justify-content: space-around;
padding: 5rpx 0rpx 20rpx;
box-sizing: border-box;
.cate_item_box {
min-width: 110rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.cate_item_border {
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.cate_item_name {
margin-top: 6rpx;
font-weight: normal;
font-size: 28rpx;
color: #000000;
// line-height: 46rpx;
text-align: center;
// color: #fff;
}
}
}
.order_box {
.title {
padding: 20rpx 20rpx 10rpx;
font-size: 30rpx;
font-weight: bold;
}
}
.viptime {
font-size: 24rpx;
margin-top: 4rpx;
border-radius: 50rpx;
color: rgb(211, 59, 27) !important;
line-height: 20rpx;
}
.current_identity {
top: 0;
line-height: 32rpx;
position: absolute;
padding: 2rpx 10rpx;
border: 4rpx solid #fff;
border-bottom-right-radius: 20rpx;
border-top-left-radius: 20rpx;
font-size: 20rpx;
font-weight: bold;
}
.hasVipBox {
padding-top: 45rpx;
padding-bottom: 0rpx;
box-shadow: 0px 0px 5px 1px rgba(255, 255, 255, 0.45);
border-radius: 20rpx;
.vip_name {
font-size: 60rpx;
}
.vip_info {
display: flex;
align-items: center;
font-size: 24rpx;
padding: 0 30rpx;
}
.viptime {
text-align: left;
padding: 0 30rpx;
font-size: 24rpx;
color: #333 !important;
font-weight: 500;
margin-bottom: 20rpx;
}
}
.vbg {
font-size: 300px;
font-weight: 800;
position: absolute;
color: #3e9d78bd !important;
right: -40rpx;
top: -10px;
}
.xufei {
position: absolute;
height: 46rpx;
right: 20rpx;
color: rgba(244, 43, 51, 0.85) !important;
font-size: 24rpx;
border-radius: 50rpx;
line-height: 46rpx;
padding: 0rpx 20rpx;
background: rgba(255, 255, 255, 1);
}
.hasVipSuper {
border: 2rpx solid #fff1ca;
background-image: linear-gradient(90deg, #fff0dc 0%, #f8e483 100%);
.current_identity {
background-color: #fdefb5;
color: #c47029;
}
.PM_font {
color: #f4a04c;
}
}
.hasVipZmZm {
box-shadow: 0px 0px 5px 1px RGBA(235, 247, 243, 0.45);
background-image: linear-gradient(90deg, #aff7d6 0%, #edf5f1 100%);
.viptime {
color: #486a65;
}
.vip_name {
letter-spacing: 1px;
}
.current_identity {
background-color: #a9ddc4;
color: #20575c;
}
.PM_font {
color: #3e9d78;
}
.viptime {
color: #9acbce;
}
.hasVip .quanyi {
border-color: #b7f6ed;
color: #ffd598;
}
.xufei {
background-image: linear-gradient(90deg, #f6dc95 0%, #ffc45e 100%);
color: #3d2700 !important;
}
.vip_info_bottom {
color: #486a65;
}
}
.hasVipWumen {
background-image: linear-gradient(90deg, #c4e8fe 0%, #60bcff 100%);
box-shadow: 0px 0px 5px 1px RGBA(235, 247, 243, 0.45);
.viptime {
color: #486a65;
}
.vip_name {
letter-spacing: 1px;
}
.current_identity {
background-color: #e8f9ff;
color: #243a61;
}
.PM_font {
color: #127dff;
}
.viptime {
color: #1d3a65;
}
.hasVip .quanyi {
border-color: #e3f7fe;
color: #ffd598;
}
.xufei {
background-image: linear-gradient(90deg, #f6dc95 0%, #ffc45e 100%);
color: #3d2700 !important;
}
.vip_info_bottom {
color: #3583C3;
}
.vbg {
color: #d1effc !important;
}
}
.hasVip {
position: relative;
display: block !important;
.zhanghu {
display: block;
}
.quanyi {
border-top: 1rpx solid #f2d494;
width: 100% !important;
width: 100% !important;
}
}
.vip_image {
width: 55rpx;
height: 55rpx;
margin-right: 10rpx;
}
.user_vip_box{
width: 125rpx;
position: absolute;
margin-top: - 37rpx;
z-index: 99;
}
.user_vip_item{
display: flex;
align-items: center;
justify-content: center;
}
.user_vip_item {
border-radius: 20rpx;
background: linear-gradient(90deg, #ff1f00 0%, #fa9f93 100%);
color: #fff;
font-size: 20rpx;
line-height: 40rpx;
height: 40rpx;
font-weight: bold;
margin-bottom: 5rpx;
}
.user_vip_item image{
width: 49rpx;
height: 16rpx;
}
.vip_type{
margin-top: 10rpx;
display: flex;
align-items: center;
}
.vip_type_item{
display: flex;
align-items: center;
justify-content: center;
padding: 0 10rpx;
background: linear-gradient(90deg, #258feb 0%, #00e1ec 100%);
border-radius: 20rpx;
font-size: 20rpx;
line-height: 40rpx;
height: 40rpx;
font-weight: bold;
color: #fff;
margin-right: 10rpx;
}
.vip_type_item:last-child{
margin-right: 0;
}
.vip_type_item image{
width: 34rpx;
height: 24rpx;
}
.vip_infor{
}
.vip_infor_item{
display: block;
color: #fff;
font-size: 26rpx;
line-height: 36rpx;
font-family: PangMenZhengDaoBiaoTiTiMianFeiBan;
font-weight: normal;
}
.vip_infor_item text{
color: #fff;
}
.vip_btn{
}
.vip_btn button{
background: none;
border: 2rpx solid #294a97;
border-radius: 40rpx;
font-size: 24rpx;
width: 82rpx;
line-height: 42rpx;
color: #294a97;
font-weight: bold;
}
.vip_null{
color: #fff;
font-size: 26rpx;
line-height: 34rpx;
}
.expired{
opacity: 0.55;
}
</style>

1048
pages/my/persData.vue Normal file

File diff suppressed because it is too large Load Diff

113
pages/my/recordsList.vue Normal file
View File

@@ -0,0 +1,113 @@
<template>
<view class="content">
<z-nav-bar title="会话记录" bgColor="#5188e5" fontColor="#fff"></z-nav-bar>
<view class="list_wrap">
<view class="list_content" v-if="list&&list.length>0">
<view v-for="(item, index) in list" :key="index" class="list_item" @click="clickRecord(item, index)">
<text>{{item.chatName}}</text>
</view>
</view>
<text class="null_text" v-else>{{null_text}}</text>
</view>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
export default {
data() {
return {
list: [],
null_text: ''
};
},
//第一次加载
onLoad(e) {
},
//页面显示
onShow() {
this.getData();
},
//方法
methods: {
//获取数据
getData() {
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'common/ragFlowApi/getChats',
method: "POST",
data: {
chatId: '',
sessionId: '',
page: 1,
pageSize: 300
},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
if(res.code==0){
uni.hideLoading();
if(res.list&&res.list.length>0){
this.list = res.list;
}else{
this.null_text = '暂无数据';
}
}
});
},
//点击会话跳转到首页记录
clickRecord(item, index){
uni.setStorageSync('homeParams', { data: item, index: index });
uni.switchTab({
url: '/pages/home/index'
});
},
onPageJump(url) {
uni.navigateTo({
url: url,
});
}
},
};
</script>
<style lang="scss" scoped>
@import "@/static/mixin.scss";
.list_wrap{
padding-bottom: 20rpx;
}
.list_content{
margin: 20rpx 30rpx;
border-radius: 10rpx;
background-color: #fff;
padding: 20rpx 30rpx;
box-shadow: 0px 0px 10px 0px #a7bbe4;
text{
display: block;
width: 100%;
font-size: 30rpx;
line-height: 50rpx;
padding: 20rpx 0;
border-bottom: 1rpx solid #e5dcdc;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.list_item:last-child text{
border-bottom: none;
}
}
.null_text{
display: block;
text-align: center;
font-size: 30rpx;
color: #999;
padding-top: 150rpx;
}
</style>

360
pages/my/set.vue Normal file
View File

@@ -0,0 +1,360 @@
<template>
<view class="commonPageBox">
<z-nav-bar title="设置"></z-nav-bar>
<view class="contentBox commonPageContentBox">
<view class="set_box">
<list
:dataList="dataList"
@hancleClick="handleClickRightContent"
label="title"
>
<template slot="rightSlot" slot-scope="slotProps">
<text class="fdButtonBox aui-text-success">{{slotProps.row.content}}</text>
</template>
</list>
</view>
<view class="button_box" v-if="!visitorStatus">
<u-button
shape="square"
type=""
class="common_red_button button"
size="medium"
@click="handleClickButton(1)"
>注销账号</u-button
>
<u-button
shape="square"
type=""
class="common_grey_button button"
size="medium"
@click="handleClickButton(2)"
>退出登录</u-button
>
</view>
</view>
<u-modal
:show="signShow"
:content="signContent"
:showCancelButton="true"
@cancel="signShow = false"
@confirm="signOut"
>
</u-modal>
<u-popup key="1" v-if="showCodeImg" :show="showCodeImg" :round="10" @close="closePup">
<view class="box6">
<text style="color: #999; margin-bottom: 20rpx;">点击图片后长按图片保存到手机或使用微信扫描二维码添加客服企业微信</text>
<image src="/static/qiyeWx.jpg" mode="widthFix" style="width: 100px; height: 100px; margin: 0 auto;"></image>
</view>
</u-popup>
</view>
</template>
<script>
// #ifdef APP-PLUS
import updata from "@/uni_modules/uni-upgrade-center-app/utils/check-update";
// #endif
import list from "@/pages/component/commonComponents/list";
import $http from "@/config/requestConfig.js";
import { mapState, mapMutations } from "vuex";
export default {
components: {
list,
},
data() {
return {
signShow: false,
signContent: "是否要退出登录?",
playData: {},
options: {},
searchValue: "",
showCodeImg:false,
twoCateList: [], // 二级分类标题
titleList: [], // 方剂标题
curOneCateIndex: 0, // 当前选中的一级分类
curTwoCateIndex: 0, // 当前选中的二级分类
searchList: [], // 搜索结果数组
showSearchList: false,
userMes: {}, // 用户信息
searchDisable: false, // 搜索不可用
limitShow: false,
limitTitle: "提示",
limitContent: "",
scrollViewHeight: 0,
dataList: [
{
title: "客服热线",
content: "022-24142321",
type: "tel",
},
{
title: "客服邮箱",
content: "appyilujiankang@sina.com",
type: "email",
},
{
title: "企业微信",
content: "",
type: "wxNumber",
},
{
title: "版本检测",
content: "",
type: "checkVersion",
}
],
otherList: [
{
title: "关于我们",
url: "/pages/mine/aboutUs/index",
type: "pageJump",
}
],
visitorStatus: null, //游客身份访问set
};
},
onLoad(options) {
if(options&&options.name){
this.visitorStatus = true;
}
},
computed: {
...mapState(["userInfo"]),
},
methods: {
...mapMutations(["setUserInfo"]),
closePup(){
this.showCodeImg = false
},
//退出
signOut() {
this.signShow = false;
this.setUserInfo({ token: null });
uni.removeStorageSync('countryData');
uni.redirectTo({
url: "/pages/user/login",
});
},
//注销账户
logout() {
let that = this;
uni.showModal({
title: "提示",
content: "确定要注销当前账户吗?",
success: function (res) {
if (res.confirm) {
uni.showModal({
title: "提示",
showCancel: false,
content: `注销申请已提交成功,请联系客服进行后续操作022-24142321`,
success: function (res1) {
if (res1.confirm) {
that.signOut();
}
},
});
} else if (res.cancel) {
// 取消操作
}
},
});
},
//选择
handleClickButton(type) {
switch (type) {
case 1:
this.logout();
break;
case 2:
this.signShow = true;
break;
}
},
//list操作
handleClickRightContent(row) {
switch (row.type) {
case "tel":
this.$commonJS.handleMakingPhoneCalls(row.content);
break;
case "email":
this.$commonJS.handleCopy(row.content, row.title);
break;
case "wxNumber":
this.showCodeImg = true
break;
case "checkVersion":
this.getNewVersion()
break;
case "pageJump":
uni.navigateTo({
url: row.url,
});
break;
}
},
// 版本检测
async getNewVersion(){
// #ifdef APP-PLUS
var info = await updata();
console.log('info',JSON.stringify(info))
if(info.result.code == 0){
uni.showToast({
title:info.result.message,
icon:'none'
})
}
// #endif
},
}
};
</script>
<style lang="scss" scoped>
@import "@/static/common.scss";
.box6 {
padding: 20rpx;
text-align: center;
.title {
font-size: 28rpx;
margin: 10px 0;
}
.list {
padding: 0 10px;
padding-bottom: 20rpx;
.item {
font-size: 26rpx;
color: #333;
margin-bottom: 10rpx;
padding-top:20rpx ;
padding-bottom:20rpx ;
line-height:40rpx;
border-radius: 50rpx;
border: 1px solid #eee;
}
.item.active {
color: $themeColor;
border: 1px solid $themeColor;
}
}
.tbn {
justify-content: center;
}
.buybtn { padding: 0 20rpx;
background-color: #00d8df;
margin: 0;
margin-right: 20rpx;
text {
color: #fff;
}
}
.saveBtnss {
align-items: center;
justify-content: center;
height: 80rpx;
overflow: hidden;
border-radius: 50rpx;
text {
padding-left: 10rpx;
font-size: 28rpx;
}
}
.gouwuche {
border: 1px solid #666;
padding-right: 20rpx;
}
}
.searchList {
.item {
font-size: 28rpx;
padding: 20rpx;
border-bottom: 1px solid #dadbde;
}
}
.scroll-view_H {
background-color: #fff;
white-space: nowrap;
padding: 10rpx;
}
.scroll-Y {
height: 100%;
}
.scroll-view_H {
white-space: nowrap;
width: 100%;
}
.scroll-view-item_H {
display: inline-block;
width: 100%;
}
.titleList {
height: 100%;
}
.titleList2 {
height: calc(100% - 170rpx);
}
/deep/.scroll-view-item:nth-child(2n-1) {
background-color: transparent !important;
}
.fdButtonBox {
color: #b0b0b0;
float: right;
padding: 4rpx 14rpx;
font-size: 28rpx;
font-weight: 500;
line-height: 40rpx;
display: inline-block;
border-radius: 10rpx;
box-sizing: border-box;
}
.commonPageBox {
background-color: #f5f5f5;
}
/deep/.set_box {
background-color: #fff;
height: auto;
padding: 20rpx;
padding-bottom: 0;
padding-top: 0;
}
/deep/.titleItem {
line-height: 45rpx;
}
.button_box {
width: 100%;
position: fixed;
bottom: 40rpx;
padding: 20rpx 80rpx;
.button {
margin-top: 40rpx;
}
}
/deep/.rightArrow {
margin-top: 6rpx !important;
}
</style>

195
pages/talents/detail.vue Normal file
View File

@@ -0,0 +1,195 @@
<template>
<view class="content">
<z-nav-bar title="医生主页" bgColor="#5188e5" fontColor="#fff"></z-nav-bar>
<view class="taihu_wrap" v-if="status">
<view class="taihu_infor">
<image :src="taihuTalent.icon" class="infor_image" mode="aspectFit"></image>
<view class="infor_right">
<view class="infor_top">
<text class="infor_name">{{taihuTalent.name}}</text>
<text class="infor_title">{{taihuTalent.title}}</text>
</view>
<view class="infor_con">
<text v-for="item in label" :key="item">{{item}}</text>
</view>
</view>
</view>
<view class="taihu_common">
<text>介绍</text>
{{taihuTalent.introduce}}
</view>
<view class="taihu_common">
<text>业务专长</text>
{{taihuTalent.specialty}}
</view>
<view class="taihu_common">
<text>出诊信息</text>
{{taihuTalent.clinic}}
</view>
<view class="taihu_common">
<text>预约信息</text>
<span style="white-space: pre-line;">{{taihuTalent.reservation.replace('电话预约:', '电话预约:\n')}}</span>
</view>
<view class="taihu_common">
<text>太湖证书</text>
<view class="certificate-list" v-if="certificates.length>0">
<view class="list_block" v-for="(item,index) in displayedCertificates" :key="index" @click="showImg(item.certificateUrl)">
{{item.title}}
</view>
<view v-if="shouldShowToggle" class="toggle-btn" @click="toggleShow">
{{ showAll ? '收起' : '查看更多' }}
</view>
</view>
<view class="certificate-list" v-else>暂无</view>
</view>
</view>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
export default {
data() {
return {
id: null,
taihuTalent: {},
label: [], //标签
certificates: [], //证书
status: false,
showAll: false, //是否显示全部
defaultShowCount: 5 //默认显示条数
}
},
computed: {
displayedCertificates() {
if (this.showAll) {
return this.certificates
} else {
return this.certificates.slice(0, this.defaultShowCount)
}
},
shouldShowToggle() {
return this.certificates.length > this.defaultShowCount
}
},
onLoad(e) {
this.id = e.id;
this.getData();
},
methods: {
//获取数据
getData() {
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'common/taihuTalent/taihuTalentInfo',
method: "POST",
data: {
id: this.id
},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
if (res.code==0) {
uni.hideLoading();
this.status = true;
this.taihuTalent = res.taihuTalent;
this.label = res.label;
this.certificates = res.certificates;
}
});
},
//点击展示全部
toggleShow() {
this.showAll = !this.showAll
},
//展示图片
showImg(data){
let url = '';
if(data){
url = data.split(',')[0];
uni.previewImage({
urls: [url],
current: 0
});
}else{
this.$commonJS.showToast("暂无证书图片");
}
}
},
}
</script>
<style lang="scss" scoped>
@import '@/static/mixin.scss';
.content{
height: 100%;
overflow: auto;
background-color: #fff;
}
.taihu_wrap{
padding: 30rpx 30rpx 50rpx;
}
.taihu_infor{
display: flex;
align-items: center;
padding-bottom: 10rpx;
}
.infor_image{
display: block;
width: 180rpx;
height: 220rpx;
}
.infor_right{
width: calc(100% - 220rpx);
margin-left: 40rpx;
}
.infor_top{
display: flex;
align-items: center;
line-height: 40rpx;
}
.infor_name{
font-size: 38rpx;
color: #333;
font-weight: bold;
}
.infor_title{
font-size: 34rpx;
color: #999;
padding-left: 20rpx;
}
.infor_con{
padding-top: 20rpx;
text{
display: block;
font-size: 30rpx;
line-height: 34rpx;
padding: 8rpx 0;
color: $themeColor;
}
}
.taihu_common{
margin-top: 30rpx;
font-size: 30rpx;
line-height: 46rpx;
text{
font-size: 38rpx;
padding-right: 15rpx;
font-weight: bold;
color: $themeColor;
}
}
.list_block{
padding-top: 5rpx;
}
.toggle-btn{
color: $themeColor;
}
</style>

124
pages/talents/index.vue Normal file
View File

@@ -0,0 +1,124 @@
<template>
<view class="content">
<z-nav-bar title="太湖英才" bgColor="#5188e5" fontColor="#fff"></z-nav-bar>
<view class="talents_list">
<view class="talents_item" v-for="(item,index) in list" :key="index" @click="goToDetail(item.id)">
<image :src="item.icon" class="item_image" mode="aspectFit"></image>
<view class="item_right">
<view class="item_top">
<text class="item_name">{{item.name}}</text>
<text class="item_title">{{item.title}}</text>
</view>
<text class="item_con">{{item.introduce}}</text>
</view>
</view>
</view>
<z-navigation></z-navigation>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
export default {
data() {
return {
name: '',
region: '',
list: []
}
},
onLoad() {
uni.hideTabBar();
this.getData();
},
onShow() {
uni.removeStorageSync('homeParams');
},
methods: {
//获取数据
getData() {
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'common/taihuTalent/getTaihuTalents',
method: "POST",
data: {
name: this.name,
region: this.region
},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
uni.hideLoading();
if (res.list&&res.list.length>0) {
this.list = res.list;
}
});
},
//详情
goToDetail(id){
uni.navigateTo({
url: '/pages/talents/detail?id='+id,
});
},
},
}
</script>
<style lang="scss" scoped>
@import '@/static/mixin.scss';
.content{
height: 100%;
overflow: auto;
background-color: #fff;
}
.talents_list{
margin: 20rpx 30rpx;
}
.talents_item{
border: 1rpx solid $themeColor;
border-radius: 15rpx;
margin-bottom: 20rpx;
padding: 25rpx;
display: flex;
align-items: center;
}
.item_image{
display: block;
width: 160rpx;
height: 200rpx;
}
.item_right{
width: calc(100% - 200rpx);
margin-left: 30rpx;
}
.item_top{
display: flex;
align-items: center;
line-height: 40rpx;
}
.item_name{
font-size: 34rpx;
color: #333;
font-weight: bold;
}
.item_title{
font-size: 32rpx;
color: #999;
padding-left: 20rpx;
}
.item_con{
font-size: 30rpx;
color: #666;
margin-top: 10rpx;
line-height: 40rpx;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

873
pages/user/forget.vue Normal file
View File

@@ -0,0 +1,873 @@
<template>
<view class="page commonPage">
<view class="logo_bg">
<z-nav-bar title="" bgColor="none" fontColor="#fff"></z-nav-bar>
<view class="title PM_font">忘记密码</view>
</view>
<!-- 验证码登录 -->
<view class="register_page">
<input type="password" style="width: 0; height: 0; min-height: 0" />
<input
type="text"
autocomplete="off"
style="width: 0; height: 0; min-height: 0"
/>
<view class="flexbox" style="margin-top: 50rpx">
<view
class="input_tit emaPho"
style="margin-top: 0; margin-right: 20rpx"
>
<view
@click="handleChangeIsPassWordPhone"
:class="{ active: isPassWordPhone }"
>手机号</view
>
<span>/</span>
<view
@click="handleChangeIsPassWordPhone"
:class="{ active: !isPassWordPhone }"
>邮箱</view
>
</view>
</view>
<!-- 带区号手机号 -->
<view
class="flexbox"
v-if="isPassWordPhone"
style="margin: 36rpx 0; justify-content: space-between"
>
<view class="quhao">
<uni-data-select
class="myselect"
placeholder="请选择区号"
v-model="resetForm.quCode"
:localdata="quCodeList"
style="height: 30rpx !important"
@change="quChange"
></uni-data-select>
</view>
<view
class="triangle borderBottom phoneNumberInput"
:clasfs="[type == 1000 ? 'left_triangle' : 'right_triangle']"
>
<u--input
class="form_input_box"
type="number"
v-model="resetForm.phone"
placeholder="请输入您的手机号"
placeholder-class="grey"
/>
</view>
</view>
<view class="input_box" v-else>
<u--input
class="form_input_box"
v-model="resetForm.phone"
placeholder="请输入您的邮箱"
placeholder-class="grey"
/>
</view>
<view class="input_tit">验证码</view>
<view class="input_box">
<u--input
type="number"
class="form_input_box"
v-model="resetForm.code"
placeholder="请输入验证码"
placeholder-class="grey"
maxlength="6"
/>
<button class="sendCode" @click="getCode" size="mini">
{{ codeText }}
</button>
</view>
<view class="input_tit">密码</view>
<view class="input_box">
<u--input
class="form_input_box"
type="password"
maxlength="8"
v-model="resetForm.password"
placeholder="请输入密码"
@input="inputMethod(resetForm.password)"
/>
</view>
<view class="input_tit">确认密码</view>
<view class="input_box">
<u--input
type="password"
class="form_input_box"
maxlength="8"
v-model="resetForm.confirmPassword"
placeholder="请确认密码"
/>
</view>
<view class="btn_box">
<button @click="onSubmit"> </button>
</view>
</view>
</view>
</template>
<script>
// 密码验证的正则
//1、密码为八位及以上并且字母数字特殊字符三项都包括
var strongRegex = new RegExp(
"^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$",
"g"
);
//2、密码为八位及以上并且字母、数字、特殊字符三项中有两项强度是中等
var mediumRegex = new RegExp(
"^(?=.{8,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[a-z])(?=.*\\W))|((?=.*[0-9])(?=.*\\W))|((?=.*[A-Z])(?=.*\\W))).*$",
"g"
);
var enoughRegex = new RegExp("(?=.{8,}).*", "g");
var clear;
export default {
data() {
return {
quCodeList: [], // 国家区域码
isPassWordPhone: true,
resetForm: {},
playData: {},
type: '',
codeText: "获取验证码",
//验证码已发
readonly: false,
passwordOk: false,
note: "",
str2: "",
urlList: {
sendcode: "common/user/sms/sendcode", //密码登录
sendEmailcode: "common/user/getMailCaptcha", //密码登录
setPassword: "common/user/setPasswordByCode", //重置密码
},
};
},
//第一次加载
onLoad(e) {
this.getCountyCode();
},
//页面显示
onShow() {},
//方法
methods: {
// 获取国家区域编码
getCountyCode() {
this.$http
.request({
url: "book/baseArea/getAllBaseArea",
method: "POST",
data: {},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0 && res.baseAreas.length > 0) {
this.quCodeList = res.baseAreas.map((item) => {
let obj = {
text: item.title + " (+" + item.code + ")",
value: item.code,
};
return obj;
});
this.resetForm.quCode = this.quCodeList[0].value;
this.$forceUpdate();
} else {
this.quCodeList = [];
}
})
.catch((e) => {
console.log(e, "e");
});
},
handleChangeIsPassWordPhone() {
this.resetForm = {};
this.note = null;
this.isPassWordPhone = !this.isPassWordPhone;
this.resetForm.quCode = this.quCodeList[0].value;
this.OpenClear();
},
// 密码验证
inputMethod(value) {
this.passwordOk = false;
if (strongRegex.test(value)) {
this.str2 = "<span style='color:#18bc37'>密码强度很不错哦!</span>";
this.note = "";
this.passwordOk = true;
} else if (mediumRegex.test(value)) {
this.note =
"请至少使用大小写字母、数字、符号两种类型组合的密码长度为8位。";
this.str2 = "<span style='color:#2979ff'>密码强度中等!</span>";
this.passwordOk = true;
} else if (enoughRegex.test(value)) {
this.note =
"请至少使用大小写字母、数字、符号两种类型组合的密码长度为8位。";
} else {
this.passwordOk = false;
this.note =
"请至少使用大小写字母、数字、符号两种类型组合的密码长度为8位。";
this.str2 = "";
}
},
//获取验证码
async getCode() {
var data = {};
if (this.readonly) {
this.$commonJS.showToast("验证码已发送");
return;
}
if (this.isPassWordPhone) {
data.phone = this.resetForm.phone;
if (!this.resetForm.phone) {
this.$commonJS.showToast("请输入手机号");
return;
}
if (!this.$base.phoneRegular.test(this.resetForm.phone)) {
this.$commonJS.showToast("手机号格式不正确");
return;
}
} else {
data.email = this.resetForm.phone;
if (!this.resetForm.phone) {
this.$commonJS.showToast("请输入邮箱");
return;
}
if (!this.$base.mailRegular.test(this.resetForm.phone)) {
this.$commonJS.showToast("邮箱格式不正确");
return;
}
}
await this.$http
.post(
this.isPassWordPhone
? this.urlList.sendcode
: this.urlList.sendEmailcode,
data
)
.then((res) => {
this.getCodeState();
});
},
//验证码按钮文字状态
getCodeState() {
const _this = this;
this.readonly = true;
this.codeText = "60S后重新获取";
var s = 60;
clear = setInterval(() => {
s--;
_this.codeText = s + "S后重新获取";
if (s <= 0) {
clearInterval(clear);
_this.codeText = "获取验证码";
_this.readonly = false;
}
}, 1000);
},
// 清除验证码
OpenClear() {
clearInterval(clear);
this.codeText = "获取验证码";
this.readonly = false;
},
onSubmit() {
var data = {};
if (this.isPassWordPhone) {
data.phone = this.resetForm.phone;
if (!this.resetForm.phone) {
this.$commonJS.showToast("请输入手机号");
return;
}
if (this.resetForm.quCode == null || this.resetForm.quCode == 86) {
if (!this.$base.phoneRegular.test(this.resetForm.phone)) {
this.$commonJS.showToast("手机号格式不正确");
return;
}
}
} else {
data.email = this.resetForm.phone;
if (!this.resetForm.phone) {
this.$commonJS.showToast("请输入邮箱");
return;
}
if (!this.$base.mailRegular.test(this.resetForm.phone)) {
this.$commonJS.showToast("邮箱格式不正确");
return;
}
}
if (!this.resetForm.code) {
this.$commonJS.showToast("请输入验证码");
return;
}
if (!this.resetForm.password) {
this.$commonJS.showToast("请输入密码");
return;
}
if (!this.resetForm.confirmPassword) {
this.$commonJS.showToast("请输入确认密码");
return;
}
if (this.resetForm.confirmPassword != this.resetForm.password) {
this.$commonJS.showToast("两次密码不一致");
return;
}
if (!this.$base.passwordRegular.test(this.resetForm.password)) {
this.$commonJS.showToast("请输入不少于6位且包含数字和字母的密码");
return;
}
if (!this.passwordOk) {
this.$commonJS.showToast(this.note);
return;
}
this.$http
.post(this.urlList.setPassword, {
phone: this.resetForm.phone,
code: this.resetForm.code,
password: this.resetForm.password,
})
.then((res) => {
if (res.code == 0) {
this.$commonJS.showToast("密码修改成功!");
setTimeout(() => {
uni.navigateBack();
}, 1000);
}
});
},
},
//页面隐藏
onHide() {},
//页面卸载
onUnload() {},
//页面下来刷新
onPullDownRefresh() {},
//页面上拉触底
onReachBottom() {}
};
</script>
<style lang="scss" scoped>
@import "@/static/mixin.scss";
.page {
.title {
padding: 60rpx 0 80rpx 0;
font-size: 80rpx;
color: #fff;
}
.input_box {
display: flex;
justify-content: space-between;
height: 100rpx;
padding-top: 0rpx;
border-bottom: 1rpx solid #eeeeee;
align-items: center;
text {
font-size: 30rpx;
width: 180rpx;
}
input {
flex: 1;
height: 70rpx;
line-height: 70rpx;
font-size: 30rpx;
}
button {
height: 78rpx;
line-height: 78rpx;
font-size: 30rpx;
color: $themeColor;
&:active {
background-color: transparent;
}
}
}
.btn_box {
width: calc(100% - 100rpx);
left: 50rpx;
position: absolute;
bottom: 8vh;
button {
font-size: 32rpx;
background: $themeBgColor;
color: #fff;
height: 80rpx;
line-height: 80rpx;
border-radius: 50rpx;
}
}
.protocol {
font-size: 24rpx;
color: #999999;
text-align: center;
margin-top: 20rpx;
text {
color: $themeColor;
}
}
}
.commonPage {
padding: 0;
background: #fff;
}
.forget_box {
padding: 0 40rpx;
background: #fff;
padding-bottom: 40rpx;
}
.logo_bg {
background-image: url("@/static/login_bg.png");
padding: 0 40rpx;
background-repeat: no-repeat;
background-size: 100% 100%;
height: 25vh;
position: relative;
text {
font-size: 45upx;
line-height: 65rpx;
position: absolute;
bottom: 110rpx;
left: 60rpx;
color: #fff;
letter-spacing: 6rpx;
}
.icon_hua_1 {
position: absolute;
bottom: 60rpx;
left: 245rpx;
width: 150rpx;
height: 150rpx;
opacity: 0.08;
}
.icon_hua_2 {
position: absolute;
bottom: 10rpx;
right: 30rpx;
width: 250rpx;
height: 250rpx;
opacity: 0.15;
}
}
.phoneNumberInput {
width: calc(100% - 160rpx);
height: 67rpx;
input {
font-size: 28rpx;
margin: 20rpx 0;
}
}
.borderBottom {
border-bottom: 1px solid #efeef4;
}
.flexbox {
display: flex;
}
.quhao {
height: 50rpx;
width: 290rpx;
margin: 12rpx 15rpx 0 0;
}
.myselect {
width: 240rpx;
height: 50rpx !important;
/deep/.uni-select {
font-size: 24rpx;
}
/deep/.uni-select__selector-item {
font-size: 24rpx;
}
}
.highlight {
color: $themeColor;
}
.tanchu {
padding: 40rpx 30rpx 40rpx 30rpx;
position: relative;
}
.logo_bg {
background-image: url("@/static/login_bg.png");
background-repeat: no-repeat;
background-size: 100% 100%;
height: 25vh;
position: relative;
text {
font-size: 45upx;
line-height: 65rpx;
position: absolute;
bottom: 110rpx;
left: 60rpx;
color: #fff;
letter-spacing: 6rpx;
}
.icon_hua_1 {
position: absolute;
bottom: 60rpx;
left: 245rpx;
width: 150rpx;
height: 150rpx;
opacity: 0.08;
}
.icon_hua_2 {
position: absolute;
bottom: 10rpx;
right: 30rpx;
width: 250rpx;
height: 250rpx;
opacity: 0.15;
}
}
.register_page {
padding: calc(var(--status-bar-height)) 50rpx 40rpx;
background-color: #fff;
min-height: 75vh;
.login_method {
justify-content: space-between;
padding: 0 96rpx;
text-align: center;
.title {
margin: 0 auto;
font-size: 40rpx;
letter-spacing: 3rpx;
color: #666;
&.active {
position: relative;
color: $themeColor;
padding-bottom: 35rpx;
font-weight: bold;
}
&.active::after {
bottom: 0;
left: 50%;
transform: translateX(-50%) translateY(-50%);
position: absolute;
content: "";
width: 150rpx;
height: 6rpx;
background-color: $themeColor;
}
}
}
.left_triangle {
&::before {
left: 140rpx;
}
&::after {
left: 140rpx;
}
}
.right_triangle {
&::before {
left: 470rpx;
}
&::after {
left: 470rpx;
}
}
.input_tit {
margin-top: 40rpx;
font-size: 34rpx;
font-weight: bold;
color: $themeColor;
}
.emaPho {
}
.emaPho > view {
display: inline-block;
padding: 10rpx 0;
color: #888;
}
.emaPho > view.active {
color: $themeColor;
padding: 10rpx 10rpx;
border-bottom: 2px solid $themeColor;
font-weight: bold;
}
.emaPho > span {
display: inline-block;
margin: 0 30rpx;
color: #ccc;
}
.input_box {
display: flex;
align-items: center;
border-radius: 8rpx;
border-bottom: solid 2rpx #efeef4;
image {
width: 36rpx;
height: 24rpx;
}
input {
flex: 1;
font-size: 28rpx;
color: #333;
height: 70rpx;
}
.input_item {
font-size: 28rpx;
border: 0px;
flex: 1;
height: 70rpx;
width: 100%;
outline: none;
}
button {
height: 60rpx;
background-color: #f8f9fb;
font-size: 28rpx;
padding: 0 14rpx;
color: $themeColor;
line-height: 60rpx;
margin-left: 20rpx;
}
.grey {
color: #999999;
}
}
.password_register {
margin-top: 40rpx;
display: flex;
justify-content: space-between;
text {
font-size: 28rpx;
color: #333333;
}
}
.protocol_box {
margin-top: 40rpx;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
font-size: 28rpx;
color: #333333;
.select {
width: 36rpx;
height: 36rpx;
background-image: url("@/static/icon/ic_gender_unselected.png");
background-position: center center;
background-repeat: no-repeat;
background-size: 100% auto;
margin-right: 15rpx;
&.active {
background-image: url("@/static/icon/ic_agreed.png");
}
}
> text {
color: $themeColor;
}
}
}
.station {
height: 230rpx;
}
.third_party_login_box {
position: fixed;
bottom: 60rpx;
width: 100%;
left: 0;
padding: 0 30rpx;
.third_party_title {
display: flex;
align-items: center;
&:before,
&:after {
content: "";
flex: 1;
height: 2rpx;
background-color: #f5f5f5;
}
text {
font-size: 24rpx;
color: #999999;
flex-shrink: 0;
padding: 0 20rpx;
}
}
.third_party_content {
margin-top: 60rpx;
display: flex;
justify-content: center;
align-items: center;
image {
width: 80upx;
height: 80upx;
margin: 0 20rpx;
}
}
}
.popup_box {
width: 600upx;
border-radius: 10rpx;
.popup_title {
display: flex;
justify-content: center;
height: 88upx;
line-height: 88upx;
view {
align-items: center;
font-size: 30upx;
display: flex;
image {
width: 50upx;
height: 50upx;
margin: 0 20rpx 0 0;
}
}
}
.popup_content {
padding: 30rpx 40rpx;
}
.popup_footer {
display: flex;
justify-content: center;
view {
width: 45%;
flex-shrink: 0;
text-align: center;
font-size: 28upx;
color: #999;
line-height: 70upx;
margin: 0 0 30rpx 0;
}
view:last-child {
background-color: $themeColor;
color: #fff;
border-radius: 50rpx;
}
}
}
.dp_title {
font-size: 36rpx;
margin-bottom: 50rpx;
color: #555;
text-align: center;
font-weight: bold;
}
.dp_content {
max-height: 1000rpx;
overflow-y: scroll;
font-size: 28rpx;
color: #555;
line-height: 45rpx;
.dp_con1 {
font-weight: bold;
font-size: 32rpx;
margin-top: 20rpx;
margin-bottom: 20rpx;
}
}
.qie_huan {
font-size: 26rpx;
margin: 20rpx 0 0 0;
text-align: center;
}
.comTy {
font-size: 28rpx;
line-height: 46rpx;
text-align: left;
}
.youKeL {
display: flex;
justify-content: center;
margin: 30rpx 0 0 0;
font-size: 26rpx;
color: $themeColor;
view {
font-weight: bold;
border: 1px solid $themeColor;
border-radius: 10rpx;
padding: 5rpx 15rpx;
}
}
</style>

1112
pages/user/login.vue Normal file

File diff suppressed because it is too large Load Diff

376
pages/user/workOrder.vue Normal file
View File

@@ -0,0 +1,376 @@
<template>
<view class="page">
<z-nav-bar title="问题反馈/申诉"></z-nav-bar>
<uni-forms :modelValue="form" :rules="rules" ref="form" style="margin-top: 10rpx;">
<view class="input_box">
<uni-forms-item label="" name="type" label-width="0">
<view class="">
<text class="input_tit"><i>*</i>问题类型</text>
</view>
<view class="in" style="flex: 1; border: none;">
<uni-data-select style="width: 100%;" v-model="form.type"
:localdata="typeLIst"></uni-data-select>
</view>
</uni-forms-item>
</view>
<view class="input_box">
<uni-forms-item label="" name="account" label-width="0">
<text class="input_tit"><i>*</i>太湖云医账号:</text>
<view class="in">
<input placeholder-style="font-size:26rpx" type="text" v-model="form.account"
placeholder="请输入手机号/邮箱" />
</view>
</uni-forms-item>
</view>
<view class="input_box" v-if="form.type == 3">
<uni-forms-item label="" name="relation" label-width="0">
<text class="input_tit"><i>*</i>订单编号:</text>
<view class="in">
<input type="number" @input="relationInput" placeholder-style="font-size:26rpx"
v-model="form.relation" placeholder="请输入订单编号" />
</view>
<text v-show="relationError" style="font-size: 24rpx; color: red; margin-top: 10rpx;">请填写订单编号</text>
<text v-show="relationErrorPattern"
style="font-size: 24rpx; color: red; margin-top: 10rpx;">订单编号格式错误</text>
</uni-forms-item>
</view>
<view class="input_box">
<uni-forms-item label="" name="content" label-width="0">
<text class="input_tit"><i>*</i>问题描述:</text>
<view class="in">
<view class="uni-textarea">
<textarea placeholder-style="font-size:26rpx" v-model="form.content" maxlength="200"
placeholder="请输入您要反馈的问题" />
</view>
</view>
</uni-forms-item>
</view>
<view class="input_box">
<uni-forms-item label="" name="contactInformation" label-width="0">
<text class="input_tit"><i>*</i>联系电话:</text>
{{reversedMessage}}
<view class="in">
<input type="number" placeholder-style="font-size:26rpx" @input="telInput"
v-model="form.contactInformation" placeholder="请输入与您联系的手机号" />
</view>
<text v-show="telError" style="font-size: 24rpx; color: red; margin-top: 10rpx;">手机号格式错误</text>
</uni-forms-item>
</view>
<view class="input_box">
<text class="input_tit">问题截图:</text>
<view class="in" style="border: none;" @click="checkPermision">
<u-upload :fileList="fileList1" @afterRead="addPic" @delete="deletePic" multiple :maxCount="4"
width="40" height="40" :previewFullImage="true">
</u-upload>
<text style="font-size: 24rpx; color: #999;">可上传4张问题截图</text>
</view>
</view>
</uni-forms>
<view class="btn_box"><button @click="onSubmit"> </button></view>
</view>
</template>
<script>
import $http from '@/config/requestConfig.js';
import permission from "@/js_sdk/wa-permission/permission.js"
import {
mapState,
mapMutations
} from 'vuex';
export default {
data() {
return {
fileList1: [],
playData: {},
//手机号账号
form: {
account: '', // 账号
content: '', // 描述
image: '', //图片
contactInformation: '', // 联系电话
relation: '', // 订单号
type: null, // 反馈类型
},
telError: false,
relationError: false,
relationErrorPattern: false,
rules: {
account: {
rules: [{
required: true,
errorMessage: '请输入账号',
}
]
},
content: {
rules: [{
required: true,
errorMessage: '请输入问题描述',
}
]
},
contactInformation: {
rules: [{
required: true,
errorMessage: '请输入联系电话',
}
]
},
type: {
rules: [{
required: true,
errorMessage: '请选择反馈类型',
}
]
}
},
pageType: '',
typeLIst: [
{
value: "1",
text: "登录相关问题"
},
{
value: "2",
text: "账号相关问题"
},
{
value: "3",
text: "问答相关问题"
},
{
value: "5",
text: "病历相关问题"
},
{
value: "6",
text: "充值相关问题"
},
{
value: "7",
text: "网络暴力举报"
},
{
value: "8",
text: "其他"
},
],
};
},
//第一次加载
onLoad(e) {
this.pageType = e.name
switch (this.pageType) {
case "login":
this.form.type = '1'
break;
case "order":
this.form.type = '3'
break;
}
},
//页面显示
onShow() {
},
computed: {
...mapState(['userInfo']),
reversedMessage: function() {
this.form.account = this.userInfo.tel
}
},
//方法
methods: {
relationInput(e) {
this.relationError = false
this.relationErrorPattern = false
},
telInput(e) {
this.telError = false
},
async checkPermision() {
var result = await permission.premissionCheck("CAMERA_EXTERNAL_STORAGE")
if (result != 1) {
return false
}
},
async addPic(e) {
let that = this;
for (var i = 0; i < e.file.length; i++) {
uni.uploadFile({
url: this.$baseUrl + "/oss/fileoss",
filePath: e.file[i].url,
name: "file",
formData: {},
success: (res) => {
that.fileList1.push({
url: JSON.parse(res.data).url,
});
},
fail: (error) => {
},
});
}
},
deletePic(event) {
this.fileList1.splice(event.index, 1)
},
onSubmit() {
this.$refs.form.validate().then(res => {
if (this.form.type == 3) {
if (this.form.relation == '') {
this.relationError = true
return
} else {
if (!this.$base.orderRegular.test(this.form.relation)) {
this.relationErrorPattern = true
return
}
}
}
if (this.fileList1.length > 0) {
let _list = this.fileList1
_list = _list.map(item => item.url)
this.form.image = _list.join(',')
}
if (!this.$base.phoneRegular.test(this.form.contactInformation)) {
this.telError = true
uni.showToast({
title: '手机格式不正确',
icon: 'none'
});
return;
}
$http.request({
url: "common/sysFeedback/addSysFeedback",
method: "POST",
data: {
...this.form
},
header: {
'Content-Type': 'application/json'
},
})
.then(res => {
uni.showModal({
title: "提示",
content: "提交成功!",
showCancel: false,
success: (res) => {
this.fileList1 = []
uni.switchTab({
url: '/pages/my/index'
});
}
});
}).catch(e => {
uni.showToast({
title: '提交失败',
icon: 'error'
})
});
}).catch(err => {
uni.showToast({
title: '页面有未填写的内容哦',
icon: 'none'
})
})
}
}
};
</script>
<style lang="scss" scoped>
@import '@/static/mixin.scss';
::v-deep .uni-forms-item {
margin-bottom: 26rpx !important;
}
.input_tit {
font-weight: bold;
}
.page {
background-color: #ffffff;
padding: 0 20rpx;
min-height: 100vh;
.title {
padding: 30rpx 0 40rpx 0;
font-size: 40rpx;
color: #333333;
}
.input_box {
display: block;
padding-top: 10rpx;
align-items: center;
i {
font-size: 24rpx;
color: red;
padding-right: 10rpx;
}
.in {
border: 1rpx solid #eeeeee;
border-radius: 8rpx;
padding: 8rpx;
margin-top: 10rpx;
}
text {
font-size: 30rpx;
width: 180rpx;
}
input {
flex: 1;
height: 50rpx;
font-size: 30rpx;
}
button {
height: 78rpx;
line-height: 78rpx;
font-size: 30rpx;
color: $themeColor;
&:active {
background-color: transparent;
}
}
}
.btn_box {
margin-top: 70rpx;
padding-bottom: 20rpx;
button {
font-size: 30rpx;
background: linear-gradient(90deg, #005eae 0%, #5188e5 80%);
color: #fff;
line-height: 85rpx;
border-radius: 50rpx;
}
}
.protocol {
font-size: 24rpx;
color: #999999;
text-align: center;
margin-top: 20rpx;
text {
color: $themeColor;
}
}
}
</style>

48
pages/wumen/index.vue Normal file
View File

@@ -0,0 +1,48 @@
<template>
<view class="content">
<z-nav-bar title="吴门医述"></z-nav-bar>
<z-navigation></z-navigation>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
export default {
data() {
return {
list: [],
}
},
onLoad() {
uni.hideTabBar();
},
methods: {
//获取数据
getData() {
this.$http.request({
url: 'common/ragFlowApi/getChatAssistants',
method: "POST",
data: {},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
if (res.list&&res.list.length>0) {
}
});
}
},
}
</script>
<style lang="scss" scoped>
@import '@/static/mixin.scss';
.content{
height: 100%;
overflow: auto;
background-color: #fff;
}
</style>

343
static/common.scss Normal file
View File

@@ -0,0 +1,343 @@
@import './mixin.scss';
$themeColor: #5188e5;
$themeBgColor: #fff !important;
@font-face {
font-family: 'MicrosoftYaHei';
font-weight: normal;
font-style: normal;
}
/deep/uni-radio .uni-radio-input {
width: 20px !important;
height: 20px !important;
}
* {
margin: 0;
padding: 0;
list-style: none;
}
.common_radius_box {
width: 100%;
padding: 20rpx;
box-sizing: border-box;
border-radius: 10rpx;
overflow: hidden;
}
.goods_nav_box {
box-shadow: 0 4rpx 48rpx 0 rgba(0, 0, 0, .15);
width: 100%;
position: fixed;
left: 0;
bottom: 0;
}
.common_divider {
padding: 10rpx 20rpx;
.u-divider {
margin: 0 !important;
}
}
.flex_box {
display: flex;
}
.align-items_box {
align-items: center;
}
/deep/uni-page-body {
height: 100% !important;
}
.aui-text-danger {
color: red;
}
.common_red_button {
background-color: rgb(235, 10, 10);
color: #fff;
}
.common_grey_button {
background-color: #8b8d8d;
color: #fff;
}
.bg_box_shandow {
border-radius: 5px;
padding: 10rpx 20rpx;
font-weight: normal;
font-size: 18px;
}
.color_shandow {
box-shadow: 0px 0px 3px 0px rgba(0, 82, 79, 0.2) !important;
}
.bg_color {
background: rgba(125, 193, 240, 0.1);
}
/deep/.common_section {
.uni-section-header {
padding: 0 !important;
.uni-section-header__decoration {
background-color: #3ab3ae !important;
}
}
padding-bottom: 20rpx !important;
}
.commonTags {
background-color: #3AB3AE;
color: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
font-size: 24rpx !important;
padding: 4rpx 12rpx;
box-sizing: border-box;
border-radius: 12rpx;
}
.commonTagsRed {
border-color: rgb(247, 146, 146);
background-color: rgb(253, 70, 70);
}
.hidden1 {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.hidden2 {
line-height: 30px;
height: 60px;
text-overflow: ellipsis;
// white-space: nowrap;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.hidden5 {
text-overflow: ellipsis;
// white-space: nowrap;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
}
.form_input_box {
border: none !important;
border-bottom: 2rpx solid #efeef4;
padding-left: 0 !important;
padding-right: 0 !important;
}
.commonPageWhiteBox {
background-color: #fff;
}
.headImage {
width: 100%;
height: 300rpx;
// margin-bottom: 20rpx;
}
.flexbox {
background-color: #fff;
}
.commonPageContentBox {
height: calc(100% - 50px) !important;
}
.commonPageBox {
width: 100%;
height: 100%;
overflow: auto;
.componentPage {
width: 100%;
height: 100%;
}
.RightArrowGreenText {
width: 28rpx;
height: 18rpx;
font-family: MicrosoftYaHei;
font-weight: 600;
font-size: 35rpx;
color: #018F89;
line-height: 70rpx;
}
.greenCardBox {
width: 100%;
// height: 298rpx;
background: #EDFCF7;
box-shadow: 0rpx 0rpx 6rpx 0rpx rgba(0, 82, 79, 0.2);
border-radius: 10rpx;
overflow: hidden;
}
.scrollDataList {
font-size: 26rpx;
margin-top: 20rpx;
padding: 0 10rpx;
border-radius: 10rpx;
background-color: #f8f9fa;
.data_item {
align-items: flex-start;
border-bottom: 2px solid #fff;
padding: 10rpx;
}
}
}
.commonPage {
width: 100%;
box-sizing: border-box;
height: 100%;
overflow: auto;
.boxShadow {
box-shadow: 0px 0px 10rpx 2rpx rgba(0, 82, 79, 0.1);
}
.rightArrow {
width: 40rpx;
height: 40rpx;
float: right;
}
.sendCode {
height: 60rpx !important;
background-color: #f8f9fb;
font-size: 28rpx !important;
padding: 0 14rpx !important;
color: $themeColor !important;
line-height: 60rpx !important;
margin-left: 20rpx !important;
}
}
.container {
width: 100%;
padding: 10rpx;
height: 100%;
box-sizing: border-box;
.contentBox {
width: 100%;
height: 100%;
}
}
view,
page,
text,
button,
image,
textarea,
scroll-view,
input {
box-sizing: border-box;
}
image {
display: block;
}
button {
margin: 0;
padding: 0;
background-color: #FFFF;
}
button::after {
border: none;
}
// 主题背景色
.themeBgColor {
background-color: $themeColor;
}
// 主题字体色
.themeFontColor {
color: $themeColor !important;
}
// 中药检索弹出层样式
.CNMedicineSearchPopup {
.dp_title {
font-size: 28rpx;
font-weight: 700;
padding: 20rpx 20rpx 0;
}
.twoCateList {
font-size: 28rpx;
margin-top: 20rpx;
.u-border-bottom {
border-bottom-width: 0 !important
}
.u-border-right {
border-right-width: 0 !important
}
.grid-text {
width: 212rpx;
padding: 10rpx;
margin-bottom: 10rpx;
text-align: center;
border: 0.5px solid #dadbde;
}
.cur {
color: #087940;
border: 0.5px solid #3AB3AE;
background: #3AB3AE1c;
font-weight: bold;
}
.u-grid-list {
// border-top: 0.5px solid #dadbde;
// border-bottom: 0.5px solid #dadbde;
}
}
}

16
static/customicons.css Normal file
View File

@@ -0,0 +1,16 @@
.customicons {
font-family: "customicons" !important;
}
.youxi:before {
content: "\e60e";
}
.wenjian:before {
content: "\e60f";
}
.zhuanfa:before {
content: "\e610";
}

BIN
static/icon/ic_agreed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 B

BIN
static/icon/ic_close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/icon/icon_bars.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

BIN
static/icon/icon_dialog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
static/icon/icon_line.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/icon/icon_right.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

BIN
static/icon/icon_submit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
static/icon/icon_upload.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
static/icon/iocn_zs_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
static/icon/iocn_zs_1_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
static/icon/iocn_zs_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
static/icon/iocn_zs_2_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
static/icon/iocn_zs_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
static/icon/iocn_zs_3_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
static/icon/iocn_zs_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
static/icon/iocn_zs_4_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
static/icon/iocn_zs_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
static/icon/iocn_zs_5_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
static/icon/iocn_zs_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
static/icon/iocn_zs_6_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
static/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
static/login_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

BIN
static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
static/logo_zi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

152
static/mixin.scss Normal file
View File

@@ -0,0 +1,152 @@
@charset "utf-8";
//主题色
$themeColor: #5188e5;
$themeBgColor: #5188e5 !important;
@keyframes example1 {
0% {
transform: translate(-100px);
opacity: 0;
}
50% {
transform: translate();
opacity: 0.5;
}
100% {
transform: translate(0);
// opacity: 1;
}
}
@mixin theme($type, $path: '') {
@if $type =="btn_bg" {
background-image: linear-gradient(90deg, #3AB3AE 0%, #117e4c 100%);
}
@else if $type =="unselected_img" {
background-image: url($path + "static/icon/ic_gender_unselected.png");
}
@else if $type =="check_img" {
background-image: url($path + "static/icon/ic_agreed.png");
}
@else if $type =="radio_img" {
background-image: url($path + "static/icon/ic_gender_selected.png");
}
}
@mixin themeBorder($borderSize, $radiusSize, $linearGradient) {
border-radius: $radiusSize;
margin: auto;
box-sizing: border-box;
border: $borderSize solid transparent;
background-image: $linearGradient;
background-origin: border-box;
background-clip: content-box, border-box;
border-radius: $radiusSize;
}
@mixin themFlex($align,$justify1) {
display: flex;
align-items:$align;
justify-content: $justify1;
}
@mixin commonIconImage($x,$y) {
background-image: url(@/static/icon/icon_image.png);
background-position: $x,$y;
}
// 背景图片地址和大小
@mixin bis($url, $size: cover) {
background-image: url($url);
background-repeat: no-repeat;
background-position: center center;
background-size: $size;
}
// 头像
@mixin ic($width, $height) {
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
flex-shrink: 0;
width: $width;
height: $height;
}
// 单行省略号
@mixin toe() {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap
}
// 多行省略号
@mixin bov($num: 2) {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: $num;
-webkit-box-orient: vertical;
}
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* uni.scss */
@import '@/uni_modules/uview-ui/theme.scss';
/* 颜色变量 */
/* 主要颜色 */
$dominantHue: #3AB3AE; //主色调 蓝
$lightBlue: #ECF3FD; //淡蓝
//背景浅灰
$bgLightGray: #f7f7f7; //浅灰
/* 文本颜色 */
$blackAll: #333333; //主文字颜色 黑
$mediumGrey: #666777; //副文字颜色 中灰
$lightGray: #a4a6bf; //副文字颜色 浅灰
$redAll: #FF5050; // 文本红色
$bleed: 30upx; //屏幕左右边距
//屏幕适配数值
$barTopHeight: 0; //XR系列状态栏高度
$navBoxHeight: 34px; //XR系列底部 HOME 健预留高
$navHeight: 65px; //底部导航栏高度
$barHeight: 44px; //顶部标题栏高度
$classifyTopH: 44px; //分类顶部选项卡高
$stairTop: 68px; // 一级页面头部距离
$stairTopTow: 92px; // XR系列一级页面头部距离
/* 其它颜色 */
$skeletonColor: #eaeaea; //骨架背景色 图片为加载完成的背景颜色
$rippleBg: #EEEEEE; //全局分割线颜色
$brimColor: #EAEAEA; //书架复选框颜色
$starColor: #FFB32F; //星星

BIN
static/qiyeWx.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
static/tab/icon_tab1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
static/tab/icon_tab1_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
static/tab/icon_tab2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
static/tab/icon_tab2_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
static/tab/icon_tab3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
static/tab/icon_tab3_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
static/tab/icon_tab4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
static/tab/icon_tab4_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
static/tab/icon_tab5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
static/tab/icon_tab5_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

1458
static/uni.css Normal file

File diff suppressed because it is too large Load Diff

BIN
static/uni.ttf Normal file

Binary file not shown.

19
store/index.js Normal file
View File

@@ -0,0 +1,19 @@
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const files = require.context("./modules", false, /\.js$/);
let modules = {
state: {},
mutations: {},
actions: {}
};
files.keys().forEach((key) => {
Object.assign(modules.state, files(key)["state"]);
Object.assign(modules.mutations, files(key)["mutations"]);
Object.assign(modules.actions, files(key)["actions"]);
});
const store = new Vuex.Store(modules);
export default store;

111
store/modules/common.js Normal file
View File

@@ -0,0 +1,111 @@
export const state = {
//webView地址
webViewUrl: "",
loadingShow: false,
videoTimer: false,
//微信场景参数
chatScenesInfo: {},
//绑定微信头像昵称弹窗状态
bindUserInfoShow: false,
//当前位置
currentAddress: {
areaName: "请选择",
areaId: ''
},
guidePages:1
};
//缓存浏览器的数据名称
const cacheNameList = ["userInfo","HealthMes","webViewUrl","hisRecords"];
let clearTime;
export const mutations = {
//取出缓存数据打开APP就取出
setCacheData(state) {
for (let name of cacheNameList) {
let data;
// #ifndef H5
data = uni.getStorageSync(name);
// #endif
// #ifdef H5
data = sessionStorage.getItem(name) || localStorage.getItem(name);
// #endif
if (data) {
// #ifdef H5
try {
data = JSON.parse(data);
} catch (e) {
}
// #endif
state[name] = data;
}
}
},
//WebView地址
setWebViewUrl(state, data) {
if (data) {
state.webViewUrl = data;
// #ifdef H5
window.sessionStorage.setItem('webViewUrl', data);
// #endif
}
},
setVideoTimer(state, data) {
if (data) {
state.videoTimer = data;
// #ifdef H5
// window.sessionStorage.setItem('webViewUrl', data);
// #endif
}
},
//数据加载状态
setLoadingShow(state, data) {
if(state.loadingShow){
if(data){
clearTime && clearTimeout(clearTime);
clearTime = setTimeout(function(){
state.loadingShow = false;
},5000);
} else {
clearTime && clearTimeout(clearTime);
clearTime = setTimeout(function(){
state.loadingShow = false;
},50);
}
} else {
state.loadingShow = data;
}
// console.log('加载状态',state.loadingShow)
},
//微信场景参数
setChatScenesInfo(state, data) {
if (data) {
state.chatScenesInfo = Object.assign({}, state.chatScenesInfo, data);
}
},
//绑定微信头像昵称弹窗状态
setBindUserInfoShow(state, data) {
state.bindUserInfoShow = data;
},
//当前地址
setCurrentAddress(state, data) {
if (data) {
state.currentAddress = Object.assign(state.currentAddress, data);
let addressInfo = {
"provinceId": state.currentAddress.provinceId,
"provinceName": state.currentAddress.provinceName,
"cityId": state.currentAddress.cityId,
"cityName": state.currentAddress.cityName,
"areaId": state.currentAddress.areaId,
"areaName": state.currentAddress.areaName,
};
uni.setStorageSync('currentAddress', addressInfo);
}
},
// 苹果支付验证
checkIapOrder(){
console.log('验证苹果支付未关闭订单')
},
};
export const actions = {
};

9
store/modules/order.js Normal file
View File

@@ -0,0 +1,9 @@
export const state = {
};
export const mutations = {
};
export const actions = {
};

74
store/modules/user.js Normal file
View File

@@ -0,0 +1,74 @@
export const state = {
//用户数据
userInfo: {},
videoOssList:[],
videoList:[],
};
export const mutations = {
//储存用户信息
setUserInfo(state, data) {
// console.log(state)
// console.log(data)
if (data) {
state.userInfo = Object.assign({}, state.userInfo, data);
// #ifdef H5
window.sessionStorage.setItem('userInfo', JSON.stringify(state.userInfo));
// #endif
// #ifndef H5
uni.setStorageSync('userInfo', state.userInfo);
// #endif
}
},
setVideoOssList(state, data) {
// console.log(state)
// console.log(data)
if (data) {
state.videoOssList = data;
// #ifdef H5
window.sessionStorage.setItem('videoOssList', JSON.stringify(state.videoOssList));
// #endif
// #ifndef H5
uni.setStorageSync('videoOssList', state.videoOssList);
// #endif
}
},
setVideoList(state, data) {
// console.log(state)
// console.log(data)
if (data) {
state.videoOssList = data;
// #ifdef H5
window.sessionStorage.setItem('videoList', JSON.stringify(state.videoList));
// #endif
// #ifndef H5
uni.setStorageSync('videoList', state.videoList);
// #endif
}
},
//储存一路健康用户信息
setHealthMes(state, data) {
console.log(data)
if (data) {
state.HealthMes = Object.assign({}, state.HealthMes, data);
// #ifdef H5
window.sessionStorage.setItem('HealthMes', JSON.stringify(state.HealthMes));
// #endif
// #ifndef H5
uni.setStorageSync('HealthMes', state.HealthMes);
// #endif
}
},
// 退出APP
emptyUserInfo(state) {
state.userInfo = {};
// #ifdef H5
window.sessionStorage.removeItem("userInfo");
// #endif
// #ifndef H5
uni.removeStorageSync("userInfo");
// #endif
},
};
export const actions = {
};

1
taimed Submodule

Submodule taimed added at 23cb7534ac

13
uni.promisify.adaptor.js Normal file
View File

@@ -0,0 +1,13 @@
uni.addInterceptor({
returnValue (res) {
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
return res;
}
return new Promise((resolve, reject) => {
res.then((res) => {
if (!res) return resolve(res)
return res[0] ? reject(res[0]) : resolve(res[1])
});
});
},
});

77
uni.scss Normal file
View File

@@ -0,0 +1,77 @@
@import '@/uni_modules/uview-ui/theme.scss';
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16px;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;

View File

@@ -0,0 +1,12 @@
// 本文件用于使用JQL语法操作项目关联的uniCloud空间的数据库方便开发调试和远程数据库管理
// 编写clientDB的js API也支持常规js语法比如var可以对云数据库进行增删改查操作。不支持uniCloud-db组件写法
// 可以全部运行也可以选中部分代码运行。点击工具栏上的运行按钮或者按下【F5】键运行代码
// 如果文档中存在多条JQL语句只有最后一条语句生效
// 如果混写了普通js最后一条语句需是数据库操作语句
// 此处代码运行不受DB Schema的权限控制移植代码到实际业务中注意在schema中配好permission
// 不支持clientDB的action
// 数据库查询有最大返回条数限制详见https://uniapp.dcloud.net.cn/uniCloud/cf-database.html#limit
// 详细JQL语法请参考https://uniapp.dcloud.net.cn/uniCloud/jql.html
// 下面示例查询uni-id-users表的所有数据
db.collection('uni-id-users').get();

View File

@@ -0,0 +1,6 @@
## 0.0.32022-11-11
- 修复 config 方法获取根节点为数组格式配置时错误的转化为了对象的Bug
## 0.0.22021-04-16
- 修改插件package信息
## 0.0.12021-03-15
- 初始化项目

View File

@@ -0,0 +1,81 @@
{
"id": "uni-config-center",
"displayName": "uni-config-center",
"version": "0.0.3",
"description": "uniCloud 配置中心",
"keywords": [
"配置",
"配置中心"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "",
"type": "unicloud-template-function"
},
"directories": {
"example": "../../../scripts/dist"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "u",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "u"
}
}
}
}
}

View File

@@ -0,0 +1,93 @@
# 为什么使用uni-config-center
实际开发中很多插件需要配置文件才可以正常运行,如果每个插件都单独进行配置的话就会产生下面这样的目录结构
```bash
cloudfunctions
└─────common 公共模块
├─plugin-a // 插件A对应的目录
│ ├─index.js
│ ├─config.json // plugin-a对应的配置文件
│ └─other-file.cert // plugin-a依赖的其他文件
└─plugin-b // plugin-b对应的目录
├─index.js
└─config.json // plugin-b对应的配置文件
```
假设插件作者要发布一个项目模板,里面使用了很多需要配置的插件,无论是作者发布还是用户使用都是一个大麻烦。
uni-config-center就是用了统一管理这些配置文件的使用uni-config-center后的目录结构如下
```bash
cloudfunctions
└─────common 公共模块
├─plugin-a // 插件A对应的目录
│ └─index.js
├─plugin-b // plugin-b对应的目录
│ └─index.js
└─uni-config-center
├─index.js // config-center入口文件
├─plugin-a
│ ├─config.json // plugin-a对应的配置文件
│ └─other-file.cert // plugin-a依赖的其他文件
└─plugin-b
└─config.json // plugin-b对应的配置文件
```
使用uni-config-center后的优势
- 配置文件统一管理,分离插件主体和配置信息,更新插件更方便
- 支持对config.json设置schema插件使用者在HBuilderX内编写config.json文件时会有更好的提示后续HBuilderX会提供支持
# 用法
在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖请参考[使用公共模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common)
```js
const createConfig = require('uni-config-center')
const uniIdConfig = createConfig({
pluginId: 'uni-id', // 插件id
defaultConfig: { // 默认配置
tokenExpiresIn: 7200,
tokenExpiresThreshold: 600,
},
customMerge: function(defaultConfig, userConfig) { // 自定义默认配置和用户配置的合并规则,不设置的情况侠会对默认配置和用户配置进行深度合并
// defaudltConfig 默认配置
// userConfig 用户配置
return Object.assign(defaultConfig, userConfig)
}
})
// 以如下配置为例
// {
// "tokenExpiresIn": 7200,
// "passwordErrorLimit": 6,
// "bindTokenToDevice": false,
// "passwordErrorRetryTime": 3600,
// "app-plus": {
// "tokenExpiresIn": 2592000
// },
// "service": {
// "sms": {
// "codeExpiresIn": 300
// }
// }
// }
// 获取配置
uniIdConfig.config() // 获取全部配置注意uni-config-center内不存在对应插件目录时会返回空对象
uniIdConfig.config('tokenExpiresIn') // 指定键值获取配置返回7200
uniIdConfig.config('service.sms.codeExpiresIn') // 指定键值获取配置返回300
uniIdConfig.config('tokenExpiresThreshold', 600) // 指定键值获取配置如果不存在则取传入的默认值返回600
// 获取文件绝对路径
uniIdConfig.resolve('custom-token.js') // 获取uni-config-center/uni-id/custom-token.js文件的路径
// 引用文件require
uniIDConfig.requireFile('custom-token.js') // 使用require方式引用uni-config-center/uni-id/custom-token.js文件。文件不存在时返回undefined文件内有其他错误导致require失败时会抛出错误。
// 判断是否包含某文件
uniIDConfig.hasFile('custom-token.js') // 配置目录是否包含某文件true: 文件存在false: 文件不存在
```

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
{
"name": "uni-config-center",
"version": "0.0.3",
"description": "配置中心",
"main": "index.js",
"keywords": [],
"author": "DCloud",
"license": "Apache-2.0",
"origin-plugin-dev-name": "uni-config-center",
"origin-plugin-version": "0.0.3",
"plugin-dev-name": "uni-config-center",
"plugin-version": "0.0.3"
}

View File

@@ -0,0 +1,28 @@
## 1.0.32023-01-16
- 修复 不关联服务空间报错的问题
## 1.0.22023-01-14
- 新增 属性 `format` 可用于格式化显示选项内容
## 1.0.12022-12-06
- 修复 当where变化时数据不会自动更新的问题
## 0.1.92022-09-05
- 修复 微信小程序下拉框出现后选择会点击到蒙板后面的输入框
## 0.1.82022-08-29
- 修复 点击的位置不准确
## 0.1.72022-08-12
- 新增 支持 disabled 属性
## 0.1.62022-07-06
- 修复 pc端宽度异常的bug
## 0.1.5
- 修复 pc端宽度异常的bug
## 0.1.42022-07-05
- 优化 显示样式
## 0.1.32022-06-02
- 修复 localdata 赋值不生效的 bug
- 新增 支持 uni.scss 修改颜色
- 新增 支持选项禁用(数据选项设置 disabled: true 即禁用)
## 0.1.22022-05-08
- 修复 当 value 为 0 时选择不生效的 bug
## 0.1.12022-05-07
- 新增 记住上次的选项(仅 collection 存在时有效)
## 0.1.02022-04-22
- 初始化

View File

@@ -0,0 +1,467 @@
<template>
<view class="uni-stat__select">
<span v-if="label" class="uni-label-text hide-on-phone">{{label + ''}}</span>
<view class="uni-stat-box" :class="{'uni-stat__actived': current}">
<view class="uni-select" :class="{'uni-select--disabled':disabled}">
<view class="uni-select__input-box" @click="toggleSelector">
<view v-if="current" class="uni-select__input-text">{{current}}</view>
<view v-else class="uni-select__input-text uni-select__input-placeholder">{{typePlaceholder}}</view>
<uni-icons v-if="current && clear" type="clear" color="#c0c4cc" size="24" @click="clearVal" />
<uni-icons v-else :type="showSelector? 'top' : 'bottom'" size="14" color="#999" />
</view>
<view class="uni-select--mask" v-if="showSelector" @click="toggleSelector" />
<view class="uni-select__selector" v-if="showSelector">
<view class="uni-popper__arrow"></view>
<scroll-view scroll-y="true" class="uni-select__selector-scroll">
<view class="uni-select__selector-empty" v-if="mixinDatacomResData.length === 0">
<text>{{emptyTips}}</text>
</view>
<view v-else class="uni-select__selector-item" v-for="(item,index) in mixinDatacomResData" :key="index"
@click="change(item)">
<text :class="{'uni-select__selector__disabled': item.disable}">{{formatItemName(item)}}</text>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
/**
* DataChecklist 数据选择器
* @description 通过数据渲染的下拉框组件
* @tutorial https://uniapp.dcloud.io/component/uniui/uni-data-select
* @property {String} value 默认值
* @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
* @property {Boolean} clear 是否可以清空已选项
* @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
* @property {String} label 左侧标题
* @property {String} placeholder 输入框的提示文字
* @property {Boolean} disabled 是否禁用
* @event {Function} change 选中发生变化触发
*/
export default {
name: "uni-stat-select",
mixins: [uniCloud.mixinDatacom || {}],
data() {
return {
showSelector: false,
current: '',
mixinDatacomResData: [],
apps: [],
channels: []
};
},
props: {
localdata: {
type: Array,
default () {
return []
}
},
value: {
type: [String, Number],
default: ''
},
modelValue: {
type: [String, Number],
default: ''
},
label: {
type: String,
default: ''
},
placeholder: {
type: String,
default: '请选择'
},
emptyTips: {
type: String,
default: '无选项'
},
clear: {
type: Boolean,
default: true
},
defItem: {
type: Number,
default: 0
},
disabled: {
type: Boolean,
default: false
},
// 格式化输出 用法 field="_id as value, version as text, uni_platform as label" format="{label} - {text}"
format: {
type: String,
default: ''
},
},
created() {
this.last = `${this.collection}_last_selected_option_value`
if (this.collection && !this.localdata.length) {
this.query();
}
},
computed: {
typePlaceholder() {
const text = {
'opendb-stat-app-versions': '版本',
'opendb-app-channels': '渠道',
'opendb-app-list': '应用'
}
const common = this.placeholder
const placeholder = text[this.collection]
return placeholder ?
common + placeholder :
common
}
},
watch: {
localdata: {
immediate: true,
handler(val, old) {
if (Array.isArray(val) && old !== val) {
this.mixinDatacomResData = val
}
}
},
// #ifndef VUE3
value() {
this.initDefVal()
},
// #endif
// #ifdef VUE3
modelValue() {
this.initDefVal()
},
// #endif
mixinDatacomResData: {
immediate: true,
handler(val) {
if (val.length) {
this.initDefVal()
}
}
}
},
methods: {
// 执行数据库查询
query(){
this.mixinDatacomEasyGet();
},
// 监听查询条件变更事件
onMixinDatacomPropsChange(){
if (this.collection) {
this.query()
}
},
initDefVal() {
let defValue = ''
if ((this.value || this.value === 0) && !this.isDisabled(this.value)) {
defValue = this.value
} else if ((this.modelValue || this.modelValue === 0) && !this.isDisabled(this.modelValue)) {
defValue = this.modelValue
} else {
let strogeValue
if (this.collection) {
strogeValue = uni.getStorageSync(this.last)
}
if (strogeValue || strogeValue === 0) {
defValue = strogeValue
} else {
let defItem = ''
if (this.defItem > 0 && this.defItem <= this.mixinDatacomResData.length) {
defItem = this.mixinDatacomResData[this.defItem - 1].value
}
defValue = defItem
}
if (defValue || defValue === 0) {
this.emit(defValue)
}
}
const def = this.mixinDatacomResData.find(item => item.value === defValue)
this.current = def ? this.formatItemName(def) : ''
},
/**
* @param {[String, Number]} value
* 判断用户给的 value 是否同时为禁用状态
*/
isDisabled(value) {
let isDisabled = false;
this.mixinDatacomResData.forEach(item => {
if (item.value === value) {
isDisabled = item.disable
}
})
return isDisabled;
},
clearVal() {
this.emit('')
if (this.collection) {
uni.removeStorageSync(this.last)
}
},
change(item) {
if (!item.disable) {
this.showSelector = false
this.current = this.formatItemName(item)
this.emit(item.value)
}
},
emit(val) {
this.$emit('change', val)
this.$emit('input', val)
this.$emit('update:modelValue', val)
if (this.collection) {
uni.setStorageSync(this.last, val)
}
},
toggleSelector() {
if (this.disabled) {
return
}
this.showSelector = !this.showSelector
},
formatItemName(item) {
let {
text,
value,
channel_code
} = item
channel_code = channel_code ? `(${channel_code})` : ''
if (this.format) {
// 格式化输出
let str = "";
str = this.format;
for (let key in item) {
str = str.replace(new RegExp(`{${key}}`,"g"),item[key]);
}
return str;
} else {
return this.collection.indexOf('app-list') > 0 ?
`${text}(${value})` :
(
text ?
text :
`未命名${channel_code}`
)
}
}
}
}
</script>
<style lang="scss">
$uni-base-color: #6a6a6a !default;
$uni-main-color: #333 !default;
$uni-secondary-color: #909399 !default;
$uni-border-3: #e5e5e5;
/* #ifndef APP-NVUE */
@media screen and (max-width: 500px) {
.hide-on-phone {
display: none;
}
}
/* #endif */
.uni-stat__select {
display: flex;
align-items: center;
// padding: 15px;
cursor: pointer;
width: 100%;
flex: 1;
box-sizing: border-box;
}
.uni-stat-box {
width: 100%;
flex: 1;
}
.uni-stat__actived {
width: 100%;
flex: 1;
// outline: 1px solid #2979ff;
}
.uni-label-text {
font-size: 14px;
font-weight: bold;
color: $uni-base-color;
margin: auto 0;
margin-right: 5px;
}
.uni-select {
font-size: 14px;
border: 1px solid $uni-border-3;
box-sizing: border-box;
border-radius: 4px;
padding: 0 5px;
padding-left: 10px;
position: relative;
/* #ifndef APP-NVUE */
display: flex;
user-select: none;
/* #endif */
flex-direction: row;
align-items: center;
border-bottom: solid 1px $uni-border-3;
width: 100%;
flex: 1;
height: 35px;
&--disabled {
background-color: #f5f7fa;
cursor: not-allowed;
}
}
.uni-select__label {
font-size: 16px;
// line-height: 22px;
height: 35px;
padding-right: 10px;
color: $uni-secondary-color;
}
.uni-select__input-box {
height: 35px;
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
}
.uni-select__input {
flex: 1;
font-size: 14px;
height: 22px;
line-height: 22px;
}
.uni-select__input-plac {
font-size: 14px;
color: $uni-secondary-color;
}
.uni-select__selector {
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
position: absolute;
top: calc(100% + 12px);
left: 0;
width: 100%;
background-color: #FFFFFF;
border: 1px solid #EBEEF5;
border-radius: 6px;
box-shadow: 0px 0px 3px 0px rgba(0, 82, 79, 0.65);
z-index: 3;
padding: 4px 0;
}
.uni-select__selector-scroll {
/* #ifndef APP-NVUE */
max-height: 200px;
box-sizing: border-box;
/* #endif */
}
.uni-select__selector-empty,
.uni-select__selector-item {
/* #ifndef APP-NVUE */
display: flex;
cursor: pointer;
/* #endif */
line-height: 35px;
font-size: 14px;
text-align: center;
/* border-bottom: solid 1px $uni-border-3; */
padding: 0px 10px;
}
.uni-select__selector-item:hover {
background-color: #f9f9f9;
}
.uni-select__selector-empty:last-child,
.uni-select__selector-item:last-child {
/* #ifndef APP-NVUE */
border-bottom: none;
/* #endif */
}
.uni-select__selector__disabled {
opacity: 0.4;
cursor: default;
}
/* picker 弹出层通用的指示小三角 */
.uni-popper__arrow,
.uni-popper__arrow::after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 6px;
}
.uni-popper__arrow {
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
top: -6px;
left: 10%;
margin-right: 3px;
border-top-width: 0;
border-bottom-color: #EBEEF5;
}
.uni-popper__arrow::after {
content: " ";
top: 1px;
margin-left: -6px;
border-top-width: 0;
border-bottom-color: #fff;
}
.uni-select__input-text {
// width: 280px;
width: 100%;
color: $uni-main-color;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
}
.uni-select__input-placeholder {
color: $uni-base-color;
font-size: 12px;
}
.uni-select--mask {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
</style>

View File

@@ -0,0 +1,85 @@
{
"id": "uni-data-select",
"displayName": "uni-data-select 下拉框选择器",
"version": "1.0.3",
"description": "通过数据驱动的下拉框选择器",
"keywords": [
"uni-ui",
"select",
"uni-data-select",
"下拉框",
"下拉选"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.1.1"
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": ["uni-load-more"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "u",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More