Merge branch 'main' of http://sl.vrgon.com:3000/JiXinHui/YingXingAI
This commit is contained in:
commit
9eeb8eadac
|
@ -0,0 +1,2 @@
|
|||
# 忽略 unpackage 文件夹
|
||||
/unpackage/
|
151
App.vue
151
App.vue
|
@ -1,31 +1,29 @@
|
|||
<script>
|
||||
import router from "./static/common/js/router";
|
||||
import config from "./static/common/js/config.js"
|
||||
import config from "./static/common/js/config.js";
|
||||
|
||||
var jweixin = require("jweixin-module");
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
}
|
||||
};
|
||||
},
|
||||
globalData: {},
|
||||
created() {
|
||||
|
||||
},
|
||||
created() {},
|
||||
onLaunch() {
|
||||
if (typeof window.entryUrl === 'undefined' || window.entryUrl === '') {
|
||||
window.entryUrl = location.href.split('#')[0]
|
||||
if (typeof window.entryUrl === "undefined" || window.entryUrl === "") {
|
||||
window.entryUrl = location.href.split("#")[0];
|
||||
}
|
||||
router.initApp(this);
|
||||
// 处理项目加载时白名单不生效异常问题
|
||||
let isUrl = this._route.fullPath.split('?')[0]
|
||||
let notNeed = config.whiteList.includes(isUrl)
|
||||
let isUrl = this._route.fullPath.split("?")[0];
|
||||
let notNeed = config.whiteList.includes(isUrl);
|
||||
if (notNeed) {
|
||||
uni.navigateTo({
|
||||
url: this._route.fullPath,
|
||||
});
|
||||
return
|
||||
return;
|
||||
}
|
||||
var that = this;
|
||||
uni.getSystemInfo({
|
||||
|
@ -36,7 +34,18 @@ export default {
|
|||
}
|
||||
},
|
||||
});
|
||||
return
|
||||
|
||||
if (!that.vuex_token) {
|
||||
this.$u.vuex("vuex_user", "");
|
||||
this.$u.vuex("vuex_token", "");
|
||||
uni.clearStorage();
|
||||
uni.reLaunch({
|
||||
url: "/pages/login/login/index",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
if (!that.vuex_user.isFill) {
|
||||
this.$u.vuex("vuex_msgList", "");
|
||||
this.$u.vuex("vuex_user", "");
|
||||
|
@ -51,10 +60,8 @@ export default {
|
|||
uni.navigateTo({
|
||||
url: "/pages/login/roleSelection",
|
||||
});
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
// onShow(){
|
||||
// console.log('onShow')
|
||||
|
@ -64,12 +71,12 @@ export default {
|
|||
var that = this;
|
||||
if (this.isWechat()) {
|
||||
const isiOS = !!navigator.userAgent.match(
|
||||
/\(i[^;]+;( U;)? CPU.+Mac OS X/
|
||||
/\(i[^;]+;( U;)? CPU.+Mac OS X/
|
||||
); //ios终端
|
||||
// 进行签名的时候 Android 不用使用之前的链接, ios 需要
|
||||
const signLink = isiOS
|
||||
? window.entryUrl
|
||||
: window.location.href.split("#")[0];
|
||||
? window.entryUrl
|
||||
: window.location.href.split("#")[0];
|
||||
//获取当前url然后传递给后台获取授权和签名信息,后台需要解码才能使用
|
||||
// const url =encodeURIComponent(signLink);
|
||||
const url = signLink;
|
||||
|
@ -100,14 +107,14 @@ export default {
|
|||
type: "gcj02", // 默认为wgs84的gps坐标,如果要返 回直接给openLocation用的火星坐标,可传入'gcj02'
|
||||
success: (res) => {
|
||||
uni.hideLoading();
|
||||
that.$u.vuex('vuex_userLocation', res)
|
||||
that.$u.vuex("vuex_userLocation", res);
|
||||
|
||||
var data = {
|
||||
userId: that.vuex_user.id,
|
||||
longitude: res.longitude + "",
|
||||
latitude: res.latitude + "",
|
||||
};
|
||||
that.$u.api.upPosition(data)
|
||||
that.$u.api.upPosition(data);
|
||||
},
|
||||
fail: function (res) {
|
||||
uni.hideLoading();
|
||||
|
@ -126,16 +133,15 @@ export default {
|
|||
isHighAccuracy: true,
|
||||
highAccuracyExpireTime: 3000,
|
||||
success: (res) => {
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
this.$u.vuex('vuex_userLocation', res)
|
||||
this.$u.vuex("vuex_userLocation", res);
|
||||
var data = {
|
||||
userId: this.vuex_user.id,
|
||||
longitude: res.longitude + "",
|
||||
latitude: res.latitude + "",
|
||||
};
|
||||
this.$u.api.upPosition(data)
|
||||
this.$u.api.upPosition(data);
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.hideLoading();
|
||||
|
@ -160,75 +166,76 @@ export default {
|
|||
setTimeout(() => {
|
||||
try {
|
||||
that.$connection
|
||||
.start()
|
||||
.then(() => {
|
||||
// console.log(that.$connection.connection.transport.webSocket._webSocket.url)
|
||||
// that.connectionId = that.$connection.connection.transport.url.split(
|
||||
// "=")[1]
|
||||
that.connectionId = that.$connection.connection.transport.webSocket._webSocket.url.split(
|
||||
"=")[1]
|
||||
that.CharLogin()
|
||||
})
|
||||
.catch((e) => {
|
||||
//重试
|
||||
that.$connection.sto
|
||||
console.log("websocket连接失败", e);
|
||||
return start(5000);
|
||||
});
|
||||
.start()
|
||||
.then(() => {
|
||||
// console.log(that.$connection.connection.transport.webSocket._webSocket.url)
|
||||
// that.connectionId = that.$connection.connection.transport.url.split(
|
||||
// "=")[1]
|
||||
that.connectionId =
|
||||
that.$connection.connection.transport.webSocket._webSocket.url.split(
|
||||
"="
|
||||
)[1];
|
||||
that.CharLogin();
|
||||
})
|
||||
.catch((e) => {
|
||||
//重试
|
||||
that.$connection.sto;
|
||||
console.log("websocket连接失败", e);
|
||||
return start(5000);
|
||||
});
|
||||
} catch (e) {
|
||||
//重试
|
||||
return start(5000);
|
||||
}
|
||||
}, ms);
|
||||
})(0)
|
||||
})(0);
|
||||
//接收消息
|
||||
this.$connection.on("ReceiveMessage", (user, message, type) => {
|
||||
|
||||
if (this._route.fullPath.indexOf('dialogBox') < 0) {
|
||||
if (this._route.fullPath.indexOf("dialogBox") < 0) {
|
||||
var tab = this.vuex_tabbar;
|
||||
tab[1].isDot = true;
|
||||
this.$u.vuex('vuex_tabbar', tab);
|
||||
var msgList = this.vuex_tabbar
|
||||
var msgList = this.vuex_msgList
|
||||
this.$u.vuex("vuex_tabbar", tab);
|
||||
var msgList = this.vuex_tabbar;
|
||||
var msgList = this.vuex_msgList;
|
||||
// 管理员对普通用户
|
||||
if (type == 4) {
|
||||
user = 'admin'
|
||||
user = "admin";
|
||||
}
|
||||
if (type == 3) {
|
||||
user += 'user'
|
||||
user += "user";
|
||||
}
|
||||
if (msgList.indexOf(user) < 0) {
|
||||
msgList += (user + ',');
|
||||
msgList += user + ",";
|
||||
}
|
||||
this.$u.vuex('vuex_msgList', msgList)
|
||||
this.$u.vuex("vuex_msgList", msgList);
|
||||
}
|
||||
});
|
||||
//接收系统消息
|
||||
this.$connection.on("SystemMessage", (title, content, time) => {
|
||||
if (this._route.fullPath.indexOf('sysList') < 0) {
|
||||
if (this._route.fullPath.indexOf("sysList") < 0) {
|
||||
var tab = this.vuex_tabbar;
|
||||
tab[1].isDot = true;
|
||||
this.$u.vuex('vuex_tabbar', tab);
|
||||
var msgList = this.vuex_tabbar
|
||||
var msgList = this.vuex_msgList
|
||||
if (msgList.indexOf('SystemMessage') < 0) {
|
||||
msgList += 'SystemMessage,';
|
||||
this.$u.vuex("vuex_tabbar", tab);
|
||||
var msgList = this.vuex_tabbar;
|
||||
var msgList = this.vuex_msgList;
|
||||
if (msgList.indexOf("SystemMessage") < 0) {
|
||||
msgList += "SystemMessage,";
|
||||
}
|
||||
this.$u.vuex('vuex_msgList', msgList)
|
||||
this.$u.vuex("vuex_msgList", msgList);
|
||||
}
|
||||
});
|
||||
//接收互动消息
|
||||
this.$connection.on("InteractMessage", (data, type) => {
|
||||
if (this._route.fullPath.indexOf('interactionList') < 0) {
|
||||
if (this._route.fullPath.indexOf("interactionList") < 0) {
|
||||
var tab = this.vuex_tabbar;
|
||||
tab[1].isDot = true;
|
||||
this.$u.vuex('vuex_tabbar', tab);
|
||||
var msgList = this.vuex_tabbar
|
||||
var msgList = this.vuex_msgList
|
||||
if (msgList.indexOf('InteractMessage') < 0) {
|
||||
msgList += 'InteractMessage,';
|
||||
this.$u.vuex("vuex_tabbar", tab);
|
||||
var msgList = this.vuex_tabbar;
|
||||
var msgList = this.vuex_msgList;
|
||||
if (msgList.indexOf("InteractMessage") < 0) {
|
||||
msgList += "InteractMessage,";
|
||||
}
|
||||
this.$u.vuex('vuex_msgList', msgList)
|
||||
this.$u.vuex("vuex_msgList", msgList);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -236,23 +243,20 @@ export default {
|
|||
//绑定用户账号和connectionId
|
||||
if (this.vuex_user.id) {
|
||||
this.$connection
|
||||
.invoke("login", this.connectionId, this.vuex_user.id)
|
||||
.then((res) => {
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
});
|
||||
.invoke("login", this.connectionId, this.vuex_user.id)
|
||||
.then((res) => {})
|
||||
.catch((err) => {});
|
||||
//初始化获取定位
|
||||
// this.getLocation()
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.CharLogin()
|
||||
}, 1000)
|
||||
this.CharLogin();
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.charLink()
|
||||
this.charLink();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -305,7 +309,7 @@ uni-modal .uni-modal__btn:after {
|
|||
|
||||
uni-modal .uni-modal__btn_default {
|
||||
background: #e6f6ff;
|
||||
color: #3CB5FB !important;
|
||||
color: #3cb5fb !important;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
|
@ -322,7 +326,6 @@ uni-modal .uni-modal__btn_primary {
|
|||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
|
||||
uni-modal .uni-modal {
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
|
@ -357,8 +360,8 @@ uni-page-body {
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
"Microsoft Yahei", sans-serif;
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
"Microsoft Yahei", sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
// max-width: 1536rpx;
|
||||
|
|
|
@ -100,7 +100,11 @@ const install = (Vue, vm) => {
|
|||
|
||||
/** 首页ai对话 */
|
||||
// 发送消息
|
||||
let SendMessageApi = (params = {}) => vm.$u.post('api/ChatAI/CreateChat', params);
|
||||
let SendMessageApi = (params = {}) => vm.$u.post('api/ChatAI/CreateChat', params, {showLoading: false});
|
||||
// 获取历史对话列表
|
||||
let GetConversationPage = (params = {}) => vm.$u.get('api/ChatAI/GetConversationPage', params);
|
||||
// 获取对话详情
|
||||
let GetConversationDetail = (params = {}) => vm.$u.get('api/ChatAI/GetHistoricalConversations', params);
|
||||
|
||||
/** 登录 */
|
||||
// 获取图形验证码
|
||||
|
@ -157,7 +161,9 @@ const install = (Vue, vm) => {
|
|||
SendMessageApi,
|
||||
GetCaptcha,
|
||||
GetStuVerifyCode,
|
||||
StuLogin
|
||||
StuLogin,
|
||||
GetConversationPage,
|
||||
GetConversationDetail
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ const install = (Vue, vm) => {
|
|||
// baseUrl: 'http://115.238.47.235:8993',
|
||||
// 如果将此值设置为true,拦截回调中将会返回服务端返回的所有数据response,而不是response.data
|
||||
// 设置为true后,就需要在this.$u.http.interceptor.response进行多一次的判断,请打印查看具体值
|
||||
// originalData: true,
|
||||
originalData: true,
|
||||
// 设置自定义头部content-type
|
||||
// header: {
|
||||
// 'content-type': 'xxx'
|
||||
|
@ -31,9 +31,13 @@ const install = (Vue, vm) => {
|
|||
// 方式四,如果token放在了Storage本地存储中,拦截是每次请求都执行的,所以哪怕您重新登录修改了Storage,下一次的请求将会是最新值
|
||||
// const token = uni.getStorageSync('token');
|
||||
// config.header.token = token;
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
|
||||
// 注释 7/15
|
||||
// uni.showLoading({
|
||||
// title: '请求中...'
|
||||
// });
|
||||
// 注释
|
||||
|
||||
// setTimeout(function () {
|
||||
// uni.hideLoading();
|
||||
// }, 2000);
|
||||
|
@ -42,11 +46,20 @@ const install = (Vue, vm) => {
|
|||
}
|
||||
// 响应拦截,判断状态码是否通过
|
||||
Vue.prototype.$u.http.interceptor.response = (res) => {
|
||||
uni.hideLoading();
|
||||
// uni.hideLoading();
|
||||
|
||||
// 检查是否为401未授权错误
|
||||
if (res.statusCode === 401) {
|
||||
handleAuthError(vm);
|
||||
return false;
|
||||
}
|
||||
|
||||
return res.data;
|
||||
|
||||
if (res.succeed == true || res.success == true) {
|
||||
// return res.data || res;
|
||||
return res;
|
||||
} else {
|
||||
} else {
|
||||
// uni.showToast({
|
||||
// title: res.error,
|
||||
// duration: 2000,
|
||||
|
@ -55,13 +68,31 @@ const install = (Vue, vm) => {
|
|||
// uni.navigateTo({
|
||||
// url: "/pages/login/login/login",
|
||||
// });
|
||||
return res;
|
||||
// return false;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提取处理401错误的函数
|
||||
function handleAuthError(vm) {
|
||||
vm.$u.vuex("vuex_user", "");
|
||||
vm.$u.vuex("vuex_token", "");
|
||||
uni.clearStorage();
|
||||
|
||||
// 显示提示
|
||||
uni.showToast({
|
||||
title: '登录已过期,请重新登录!',
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
});
|
||||
|
||||
// 延迟跳转到登录页
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/login/index'
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
install
|
||||
}
|
||||
|
|
|
@ -60,8 +60,12 @@ export default {
|
|||
.phone-popup {
|
||||
width: 600rpx;
|
||||
padding: 60rpx 0;
|
||||
background: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
background-image: url("/static/common/images/images_bg_dialog.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 630rpx 100rpx;
|
||||
background-position: -20rpx 0;
|
||||
|
||||
|
||||
.phone-title {
|
||||
text-align: center;
|
||||
|
|
|
@ -0,0 +1,270 @@
|
|||
<template>
|
||||
<u-popup v-model="showPopup" width="550rpx">
|
||||
<view class="drawer-container">
|
||||
<view class="drawer-header">
|
||||
<text class="drawer-title" @click="handleCreateConversation">
|
||||
<u-icon
|
||||
class="drawer-title-icon"
|
||||
name="plus"
|
||||
size="32rpx"
|
||||
color="#666666"
|
||||
></u-icon>
|
||||
新建对话
|
||||
</text>
|
||||
</view>
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="chat-history-list"
|
||||
:scroll-into-view="scrollToView"
|
||||
:show-scrollbar="false"
|
||||
scroll-with-animation="true"
|
||||
>
|
||||
<!-- 使用新的数据结构渲染聊天历史 -->
|
||||
<view
|
||||
v-for="(group, groupIndex) in chatHistoryList3"
|
||||
:key="'group-' + group.id + groupIndex"
|
||||
>
|
||||
<!-- 日期标题 -->
|
||||
<view class="chat-day">
|
||||
<text class="day-text">{{ group.id }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 该日期下的对话列表 -->
|
||||
<view
|
||||
class="chat-item"
|
||||
v-for="(item, index) in group.conversation"
|
||||
:key="'conv-' + groupIndex + '-' + index"
|
||||
:id="'chat-item-' + item.id"
|
||||
:class="{
|
||||
'chat-item-active': item.isActiveChat,
|
||||
}"
|
||||
@click="selectChatItem(groupIndex, index, item.id)"
|
||||
>
|
||||
<!-- currentActiveGroup === groupIndex &&
|
||||
currentActiveIndex === index, -->
|
||||
<text class="chat-text">{{ item.title }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 添加底部空白区域 -->
|
||||
<view class="bottom-space"></view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="drawer-footer">
|
||||
<view class="user-info">
|
||||
<image
|
||||
class="user-avatar"
|
||||
src="/static/common/images/avatar.png"
|
||||
></image>
|
||||
<text class="user-name">{{ userName || "晓德塔," }}</text>
|
||||
</view>
|
||||
<view class="settings">
|
||||
<u-icon name="setting" size="40rpx" color="#999"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ChatHistory",
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
chatHistoryList3: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
activeIndex: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
userName: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showPopup: false,
|
||||
currentActiveGroup: -1,
|
||||
currentActiveIndex: -1,
|
||||
activeItemId: "", // 存储当前激活项的ID
|
||||
scrollToView: "", // 用于scroll-into-view属性
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal) {
|
||||
this.showPopup = newVal;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
showPopup(val) {
|
||||
if (val !== this.show) {
|
||||
this.$emit("update:show", val);
|
||||
}
|
||||
},
|
||||
// 监听聊天历史数据变化,找到激活项并滚动
|
||||
chatHistoryList3: {
|
||||
handler() {
|
||||
this.$nextTick(() => {
|
||||
this.scrollToActiveItem();
|
||||
});
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 滚动到激活的聊天项
|
||||
scrollToActiveItem() {
|
||||
// 查找激活的聊天项
|
||||
let activeItemFound = false;
|
||||
|
||||
for (
|
||||
let groupIndex = 0;
|
||||
groupIndex < this.chatHistoryList3.length;
|
||||
groupIndex++
|
||||
) {
|
||||
const group = this.chatHistoryList3[groupIndex];
|
||||
for (let index = 0; index < group.conversation.length; index++) {
|
||||
const item = group.conversation[index];
|
||||
if (item.isActiveChat) {
|
||||
activeItemFound = true;
|
||||
this.activeItemId = `chat-item-${item.id}`;
|
||||
// 设置scrollToView的值,使scroll-view自动滚动到该元素
|
||||
this.scrollToView = this.activeItemId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (activeItemFound) break;
|
||||
}
|
||||
},
|
||||
|
||||
selectChatItem(groupIndex, index, conversationId) {
|
||||
// this.currentActiveGroup = groupIndex;
|
||||
// this.currentActiveIndex = index;
|
||||
|
||||
// 向父组件发送选中的对话信息
|
||||
this.$emit("select-conversation", {
|
||||
conversationId,
|
||||
});
|
||||
},
|
||||
|
||||
handleCreateConversation() {
|
||||
this.$emit("create-conversation");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.drawer-container {
|
||||
padding: 32rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
background-color: #ffffff;
|
||||
|
||||
.drawer-header {
|
||||
padding: 0 32rpx;
|
||||
height: 140rpx;
|
||||
line-height: 120rpx;
|
||||
|
||||
.drawer-title {
|
||||
font-family: DouyinSans;
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
color: #666666;
|
||||
|
||||
.drawer-title-icon {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-history-list {
|
||||
flex: 1;
|
||||
height: calc(100vh - 360rpx);
|
||||
padding-bottom: 20rpx;
|
||||
|
||||
.chat-day {
|
||||
display: flex;
|
||||
margin: 20rpx 0 20rpx 30rpx;
|
||||
|
||||
.day-text {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
font-family: PingFang SC;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-item {
|
||||
padding: 24rpx 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 4rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.chat-text {
|
||||
font-size: 28rpx;
|
||||
color: #303030;
|
||||
font-family: PingFang SC;
|
||||
}
|
||||
|
||||
&-active {
|
||||
background-color: #4f6aff;
|
||||
box-shadow: 0 2rpx 8rpx rgba(79, 106, 255, 0.3);
|
||||
|
||||
.chat-text {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-space {
|
||||
height: 30rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.drawer-footer {
|
||||
margin-top: 20rpx;
|
||||
height: 130rpx;
|
||||
border: 1rpx solid #eeeeee;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 30rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.user-avatar {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
font-family: DouyinSans;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.settings {
|
||||
padding: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,114 @@
|
|||
<template>
|
||||
<!-- 完善信息 -->
|
||||
<u-popup
|
||||
v-model="showPopup"
|
||||
mode="center"
|
||||
border-radius="16"
|
||||
closeable
|
||||
close-icon-color="#999999"
|
||||
close-icon-pos="top-right"
|
||||
>
|
||||
<view class="perfect-info-popup">
|
||||
<view class="perfect-info-title">提示</view>
|
||||
<view class="perfect-info-content">
|
||||
<view class="perfect-info-content-text">请完善个人信息,便于老师更准确的回答</view>
|
||||
</view>
|
||||
<view class="perfect-info-button">
|
||||
<u-button class="confirm-button" type="primary" @click="toPerfectInfo"
|
||||
>去完善</u-button
|
||||
>
|
||||
<u-button class="cancel-button" type="default" @click="closePopup"
|
||||
>下次再说</u-button
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PerfectInfo",
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showPopup: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal) {
|
||||
this.showPopup = newVal;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
showPopup(val) {
|
||||
if (val !== this.show) {
|
||||
this.$emit("update:show", val);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
closePopup() {
|
||||
this.showPopup = false;
|
||||
this.$emit("update:show", false);
|
||||
},
|
||||
toPerfectInfo() {
|
||||
this.showPopup = false;
|
||||
this.$emit("update:show", false);
|
||||
this.$router.push("/pages/home/userInfo/index");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.perfect-info-popup {
|
||||
width: 600rpx;
|
||||
padding: 60rpx 0;
|
||||
border-radius: 16rpx;
|
||||
background-image: url("/static/common/images/images_bg_dialog.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 630rpx 100rpx;
|
||||
background-position: -20rpx 0;
|
||||
|
||||
.perfect-info-title {
|
||||
text-align: center;
|
||||
font-family: DouyinSans;
|
||||
font-weight: bold;
|
||||
font-size: 40rpx;
|
||||
color: #477bfb;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.perfect-info-content {
|
||||
margin-bottom: 100rpx;
|
||||
text-align: center;
|
||||
font-family: PingFang SC;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
||||
&-text {
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.perfect-info-button {
|
||||
padding: 0 40rpx;
|
||||
|
||||
.confirm-button {
|
||||
background-color: #477BFB;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -9,9 +9,56 @@ import { marked } from 'marked';
|
|||
import hljs from 'highlight.js';
|
||||
import mpHtml from '@/node_modules/mp-html/dist/uni-app/components/mp-html/mp-html.vue';
|
||||
|
||||
// 自定义渲染器,修改列表的渲染方式
|
||||
const renderer = new marked.Renderer();
|
||||
|
||||
// 重写粗体渲染方法,确保粗体文本不会导致不当换行
|
||||
renderer.strong = function(text) {
|
||||
// 确保文本周围没有不必要的空格
|
||||
const trimmedText = text.trim();
|
||||
return `<strong class="custom-strong" style="font-weight:900 !important;display:inline !important;white-space:normal !important;word-break:normal !important;">${trimmedText}</strong>`;
|
||||
};
|
||||
|
||||
// 重写列表项渲染方法 - 使用特殊的包装来确保内容在一行
|
||||
renderer.listitem = function(text) {
|
||||
return `<li class="custom-list-item"><div class="list-item-wrapper" style="text-align:left !important;letter-spacing:normal !important;word-spacing:normal !important;text-justify:none !important;">${text}</div></li>`;
|
||||
};
|
||||
|
||||
// 重写有序列表渲染方法
|
||||
renderer.list = function(body, ordered) {
|
||||
const type = ordered ? 'ol' : 'ul';
|
||||
const className = ordered ? 'custom-ordered-list' : 'custom-unordered-list';
|
||||
return `<${type} class="${className}">${body}</${type}>`;
|
||||
};
|
||||
|
||||
// 重写段落渲染方法,确保换行正确
|
||||
renderer.paragraph = function(text) {
|
||||
return `<p class="custom-paragraph">${text}</p>`;
|
||||
};
|
||||
|
||||
// 重写链接渲染方法,确保链接文本正常显示
|
||||
renderer.link = function(href, title, text) {
|
||||
return `<a href="${href}" title="${title || ''}" style="display:inline !important;white-space:normal !important;word-break:break-all !important;letter-spacing:normal !important;word-spacing:normal !important;text-align:left !important;">${text}</a>`;
|
||||
};
|
||||
|
||||
// 重写表格渲染方法,添加表格容器使其可滚动
|
||||
renderer.table = function(header, body) {
|
||||
return `<div class="table-container"><table class="custom-table">
|
||||
<thead>${header}</thead>
|
||||
<tbody>${body}</tbody>
|
||||
</table></div>`;
|
||||
};
|
||||
|
||||
// 重写表格单元格渲染方法
|
||||
renderer.tablecell = function(content, flags) {
|
||||
const type = flags.header ? 'th' : 'td';
|
||||
const align = flags.align ? ` style="text-align:${flags.align}"` : '';
|
||||
return `<${type}${align}>${content}</${type}>`;
|
||||
};
|
||||
|
||||
// 配置marked
|
||||
marked.use({
|
||||
renderer: new marked.Renderer(),
|
||||
renderer: renderer,
|
||||
highlight: function(code, lang) {
|
||||
try {
|
||||
return hljs.highlightAuto(code, [lang]).value;
|
||||
|
@ -54,15 +101,351 @@ export default {
|
|||
renderedContent() {
|
||||
if (!this.content) return '';
|
||||
try {
|
||||
// 添加自定义样式
|
||||
const styleTag = this.customStyle ?
|
||||
`<style>${this.customStyle}</style>` : '';
|
||||
// 添加自定义样式,确保内容自动换行和列表正确显示
|
||||
const styleTag = `<style>
|
||||
* {
|
||||
max-width: 100% !important;
|
||||
word-break: normal !important;
|
||||
overflow-wrap: break-word !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
/* 段落样式修复 */
|
||||
.custom-paragraph, p {
|
||||
display: block !important;
|
||||
white-space: normal !important;
|
||||
margin: 10rpx 0 !important;
|
||||
width: 100% !important;
|
||||
line-height: 1.6 !important;
|
||||
text-align: left !important; /* 改为左对齐,不要两端对齐 */
|
||||
}
|
||||
|
||||
/* 解决粗体文本和普通文本换行问题 */
|
||||
.custom-strong, strong, b {
|
||||
display: inline !important;
|
||||
font-weight: 900 !important;
|
||||
white-space: normal !important;
|
||||
word-break: normal !important;
|
||||
overflow-wrap: break-word !important;
|
||||
vertical-align: baseline !important;
|
||||
position: static !important;
|
||||
float: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* 专门用于列表项内容包装的容器 */
|
||||
.list-item-wrapper {
|
||||
display: inline-block !important;
|
||||
width: 100% !important;
|
||||
white-space: normal !important;
|
||||
/* 关键属性:防止内部元素分列 */
|
||||
table-layout: fixed !important;
|
||||
word-break: normal !important;
|
||||
text-align: left !important;
|
||||
text-justify: none !important;
|
||||
letter-spacing: normal !important;
|
||||
word-spacing: normal !important;
|
||||
text-align-last: left !important;
|
||||
}
|
||||
|
||||
/* 内联元素修复 */
|
||||
span, a, em, strong, .custom-strong, b {
|
||||
display: inline !important;
|
||||
white-space: normal !important;
|
||||
vertical-align: baseline !important;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
/* 确保内部不会有奇怪的换行 */
|
||||
word-break: keep-all !important;
|
||||
}
|
||||
|
||||
/* 特别针对粗体文本 */
|
||||
.custom-strong, strong, b {
|
||||
font-weight: bold !important;
|
||||
display: inline !important;
|
||||
vertical-align: baseline !important;
|
||||
position: static !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
border: none !important;
|
||||
float: none !important;
|
||||
width: auto !important;
|
||||
word-break: keep-all !important;
|
||||
word-wrap: normal !important;
|
||||
line-height: inherit !important;
|
||||
color: inherit !important; /* 确保颜色正确继承 */
|
||||
}
|
||||
|
||||
/* 专门修复mp-html组件生成的列表结构 */
|
||||
div[data-v-7e5387f] {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
/* 处理列表编号所在的容器 - 重要修复 */
|
||||
div[data-v-7e5387f] {
|
||||
display: inline !important;
|
||||
white-space: nowrap !important; /* 防止编号和首个字符分开 */
|
||||
}
|
||||
|
||||
/* 首行缩进优化(确保列表项不会被意外截断) */
|
||||
div div {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
/* 有序列表样式 */
|
||||
.custom-ordered-list, ol {
|
||||
display: block !important;
|
||||
counter-reset: item !important;
|
||||
padding-left: 0 !important;
|
||||
margin: 10rpx 0 !important;
|
||||
width: 100% !important;
|
||||
list-style-type: none !important;
|
||||
}
|
||||
|
||||
/* 无序列表样式 */
|
||||
.custom-unordered-list, ul {
|
||||
display: block !important;
|
||||
padding-left: 0 !important;
|
||||
margin: 10rpx 0 !important;
|
||||
width: 100% !important;
|
||||
list-style-type: none !important;
|
||||
}
|
||||
|
||||
/* 针对mp-html生成的列表标记容器 */
|
||||
div[style*="undefined"] {
|
||||
display: inline !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
/* 对列表项第一个元素特殊处理 */
|
||||
h4 {
|
||||
display: inline !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* 列表项共用样式 */
|
||||
.custom-list-item, ol li, ul li {
|
||||
display: flex !important;
|
||||
padding-left: 0 !important;
|
||||
margin-bottom: 8rpx !important;
|
||||
width: 100% !important;
|
||||
position: relative !important;
|
||||
/* 确保内容在一行显示 */
|
||||
flex-wrap: nowrap !important;
|
||||
align-items: flex-start !important; /* 顶部对齐 */
|
||||
}
|
||||
|
||||
/* 列表项内容样式 */
|
||||
.custom-list-item > *:not(ol):not(ul),
|
||||
ol li > *:not(ol):not(ul),
|
||||
ul li > *:not(ol):not(ul) {
|
||||
flex: 1 !important;
|
||||
display: inline !important;
|
||||
white-space: normal !important;
|
||||
word-break: normal !important;
|
||||
width: auto !important;
|
||||
/* 确保文本不会被分列 */
|
||||
column-count: 1 !important;
|
||||
column-width: auto !important;
|
||||
column-span: all !important;
|
||||
text-align: left !important; /* 确保文本左对齐 */
|
||||
justify-content: flex-start !important; /* 左对齐 */
|
||||
text-justify: none !important; /* 禁用两端对齐 */
|
||||
letter-spacing: normal !important; /* 正常字间距 */
|
||||
word-spacing: normal !important; /* 正常词间距 */
|
||||
}
|
||||
|
||||
/* 列表项内的p标签特殊处理 */
|
||||
ol li p, ul li p, .custom-list-item p {
|
||||
display: inline !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
width: auto !important;
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
/* 有序列表项编号 */
|
||||
.custom-ordered-list > .custom-list-item {
|
||||
counter-increment: item !important;
|
||||
}
|
||||
|
||||
.custom-ordered-list > .custom-list-item::before,
|
||||
ol > li::before {
|
||||
content: counter(item)"." !important;
|
||||
min-width: 40rpx !important;
|
||||
width: 40rpx !important;
|
||||
font-weight: bold !important;
|
||||
text-align: right !important;
|
||||
margin-right: 8rpx !important;
|
||||
padding-right: 0 !important;
|
||||
flex-shrink: 0 !important;
|
||||
align-self: flex-start !important; /* 顶部对齐 */
|
||||
padding-top: 1rpx !important; /* 微调垂直位置 */
|
||||
}
|
||||
|
||||
/* 无序列表项标记 */
|
||||
.custom-unordered-list > .custom-list-item::before,
|
||||
ul > li::before {
|
||||
content: "-" !important;
|
||||
min-width: 40rpx !important;
|
||||
width: 40rpx !important;
|
||||
font-weight: bold !important;
|
||||
text-align: center !important;
|
||||
margin-right: 8rpx !important;
|
||||
padding-right: 0 !important;
|
||||
flex-shrink: 0 !important;
|
||||
align-self: flex-start !important; /* 顶部对齐 */
|
||||
padding-top: 1rpx !important; /* 微调垂直位置 */
|
||||
}
|
||||
|
||||
/* 代码块样式 */
|
||||
pre, code {
|
||||
white-space: pre-wrap !important;
|
||||
word-wrap: break-word !important;
|
||||
word-break: break-all !important;
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
|
||||
/* 禁用可能导致问题的CSS特性 */
|
||||
* {
|
||||
column-count: 1 !important;
|
||||
column-gap: 0 !important;
|
||||
column-rule: none !important;
|
||||
column-span: all !important;
|
||||
column-width: auto !important;
|
||||
columns: auto !important;
|
||||
}
|
||||
|
||||
${this.customStyle || ''}
|
||||
</style>`;
|
||||
|
||||
// 渲染Markdown为HTML
|
||||
const htmlContent = marked(this.content);
|
||||
// 对Markdown内容进行预处理,修复可能导致问题的模式
|
||||
let processedContent = this.content;
|
||||
|
||||
// 将Markdown内容分解为段落,分别处理每个段落
|
||||
const paragraphs = processedContent.split('\n\n');
|
||||
const processedParagraphs = paragraphs.map(paragraph => {
|
||||
// 处理一个段落内的粗体文本
|
||||
return paragraph.replace(/\*\*([^*]+?)\*\*/g, (match, content) => {
|
||||
// 返回无缝拼接的HTML粗体标签
|
||||
return `<strong style="font-weight:900 !important;display:inline !important;">${content}</strong>`;
|
||||
});
|
||||
});
|
||||
|
||||
// 重新组合处理后的段落
|
||||
processedContent = processedParagraphs.join('\n\n');
|
||||
|
||||
// 使用marked处理剩余的Markdown语法
|
||||
let htmlContent = marked(processedContent);
|
||||
|
||||
// 后处理HTML,确保任何遗漏的粗体标记也能被处理
|
||||
htmlContent = htmlContent
|
||||
// 处理任何遗漏的**标记
|
||||
.replace(/\*\*([^*]+?)\*\*/g, (match, content) => {
|
||||
return `<strong style="font-weight:900 !important;display:inline !important;">${content}</strong>`;
|
||||
});
|
||||
|
||||
// 处理HTML,确保所有文本元素都有正确的显示属性
|
||||
let processedHtml = htmlContent;
|
||||
|
||||
// 处理表格,确保表格正确显示
|
||||
processedHtml = processedHtml.replace(/<table([^>]*)>/g, (match, attrs) => {
|
||||
return `<div class="table-container"><table${attrs || ''} class="custom-table">`;
|
||||
});
|
||||
|
||||
processedHtml = processedHtml.replace(/<\/table>/g, '</table></div>');
|
||||
|
||||
// 将所有段落包装在特殊div中,防止段落间的换行问题
|
||||
processedHtml = processedHtml.replace(/<p([^>]*)>(.*?)<\/p>/gs, (match, attrs, content) => {
|
||||
// 确保段落内容连续显示,不被换行打断
|
||||
return `<p${attrs} style="white-space:normal !important;word-break:normal !important;overflow-wrap:break-word !important;">${content}</p>`;
|
||||
});
|
||||
|
||||
// 确保强制使用行内样式
|
||||
processedHtml = processedHtml.replace(
|
||||
/<strong/g,
|
||||
'<strong style="font-weight:900 !important;display:inline !important;white-space:normal !important;word-break:normal !important;overflow-wrap:break-word !important;color:inherit !important;"'
|
||||
);
|
||||
|
||||
// 处理可能的HTML转义问题
|
||||
processedHtml = processedHtml
|
||||
.replace(/<strong/g, '<strong')
|
||||
.replace(/<\/strong>/g, '</strong>');
|
||||
|
||||
// 添加强制粗体样式覆盖
|
||||
processedHtml = `
|
||||
<style>
|
||||
strong, .custom-strong, b {
|
||||
font-weight: 900 !important;
|
||||
display: inline !important;
|
||||
color: inherit !important;
|
||||
white-space: normal !important;
|
||||
word-break: normal !important;
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
p, div, span {
|
||||
white-space: normal !important;
|
||||
word-break: normal !important;
|
||||
overflow-wrap: break-word !important;
|
||||
text-align: left !important; /* 左对齐 */
|
||||
text-justify: none !important; /* 禁用两端对齐 */
|
||||
}
|
||||
/* 关键样式:确保文本流不被打断 */
|
||||
p strong, p b, strong, b {
|
||||
display: inline !important;
|
||||
white-space: normal !important;
|
||||
}
|
||||
/* 针对段落内部元素的处理 */
|
||||
p > * {
|
||||
display: inline !important;
|
||||
}
|
||||
/* 链接样式 */
|
||||
a {
|
||||
display: inline !important;
|
||||
white-space: normal !important;
|
||||
word-break: break-all !important;
|
||||
letter-spacing: normal !important; /* 正常字间距 */
|
||||
word-spacing: normal !important; /* 正常词间距 */
|
||||
text-align: left !important; /* 左对齐 */
|
||||
}
|
||||
/* 表格样式 */
|
||||
table {
|
||||
border-collapse: collapse !important;
|
||||
width: 100% !important;
|
||||
margin: 16rpx 0 !important;
|
||||
table-layout: fixed !important;
|
||||
border: 1px solid #e0e0e0 !important;
|
||||
overflow-x: auto !important;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #e0e0e0 !important;
|
||||
padding: 12rpx !important;
|
||||
text-align: left !important;
|
||||
word-break: break-word !important;
|
||||
white-space: normal !important;
|
||||
font-size: 28rpx !important;
|
||||
}
|
||||
th {
|
||||
background-color: #f5f5f5 !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
/* 禁用所有可能导致文本被拉伸的样式 */
|
||||
* {
|
||||
text-align-last: left !important;
|
||||
text-justify: none !important;
|
||||
text-align: left !important;
|
||||
letter-spacing: normal !important;
|
||||
word-spacing: normal !important;
|
||||
}
|
||||
</style>
|
||||
` + processedHtml;
|
||||
|
||||
// 返回带样式的HTML
|
||||
return styleTag + htmlContent;
|
||||
return styleTag + processedHtml;
|
||||
} catch (error) {
|
||||
console.error('Markdown渲染错误:', error);
|
||||
return `<p style="color: red;">Markdown渲染错误: ${error.message}</p>`;
|
||||
|
@ -77,5 +460,306 @@ export default {
|
|||
|
||||
.markdown-container {
|
||||
padding: 20rpx;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
/* 全局样式 */
|
||||
.markdown-container >>> * {
|
||||
max-width: 100% !important;
|
||||
white-space: normal !important;
|
||||
word-break: normal !important;
|
||||
overflow-wrap: break-word !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
/* 段落样式 */
|
||||
.markdown-container >>> .custom-paragraph,
|
||||
.markdown-container >>> p {
|
||||
display: block !important;
|
||||
/* margin: 10rpx 0 !important; */
|
||||
width: 100% !important;
|
||||
line-height: 1.6 !important;
|
||||
text-align: left !important; /* 改为左对齐,不要两端对齐 */
|
||||
}
|
||||
|
||||
/* 专门用于列表项内容包装的容器 */
|
||||
.markdown-container >>> .list-item-wrapper {
|
||||
display: inline-block !important;
|
||||
width: 100% !important;
|
||||
white-space: normal !important;
|
||||
/* 关键属性:防止内部元素分列 */
|
||||
table-layout: fixed !important;
|
||||
word-break: normal !important;
|
||||
text-align: left !important;
|
||||
text-justify: none !important;
|
||||
letter-spacing: normal !important;
|
||||
word-spacing: normal !important;
|
||||
text-align-last: left !important;
|
||||
}
|
||||
|
||||
/* 内联元素修复 */
|
||||
.markdown-container >>> span,
|
||||
.markdown-container >>> a,
|
||||
.markdown-container >>> em,
|
||||
.markdown-container >>> strong,
|
||||
.markdown-container >>> .custom-strong,
|
||||
.markdown-container >>> b {
|
||||
display: inline !important;
|
||||
white-space: normal !important;
|
||||
vertical-align: baseline !important;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
/* 确保内部不会有奇怪的换行 */
|
||||
/* 下面不注释的话会有奇怪的换行 */
|
||||
/* word-break: keep-all !important; */
|
||||
line-height: inherit !important;
|
||||
}
|
||||
|
||||
/* 特别针对粗体文本 */
|
||||
.markdown-container >>> .custom-strong,
|
||||
.markdown-container >>> strong,
|
||||
.markdown-container >>> b {
|
||||
font-weight: 900 !important;
|
||||
display: inline !important;
|
||||
vertical-align: baseline !important;
|
||||
position: static !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
border: none !important;
|
||||
float: none !important;
|
||||
width: auto !important;
|
||||
white-space: normal !important;
|
||||
word-break: normal !important;
|
||||
overflow-wrap: break-word !important;
|
||||
word-wrap: normal !important;
|
||||
line-height: inherit !important;
|
||||
color: inherit !important; /* 确保颜色正确继承 */
|
||||
font-size: inherit !important; /* 确保字体大小正确继承 */
|
||||
font-family: inherit !important; /* 确保字体系列正确继承 */
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* 专门修复mp-html组件生成的列表结构 */
|
||||
.markdown-container >>> div[data-v-7e5387f] {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
/* 处理列表编号所在的容器 - 重要修复 */
|
||||
.markdown-container >>> div[data-v-7e5387f] {
|
||||
display: inline !important;
|
||||
white-space: nowrap !important; /* 防止编号和首个字符分开 */
|
||||
}
|
||||
|
||||
/* 首行缩进优化(确保列表项不会被意外截断) */
|
||||
.markdown-container >>> div div {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
/* 有序列表样式 */
|
||||
.markdown-container >>> .custom-ordered-list,
|
||||
.markdown-container >>> ol {
|
||||
display: block !important;
|
||||
counter-reset: item !important;
|
||||
padding-left: 0 !important;
|
||||
margin: 10rpx 0 !important;
|
||||
width: 100% !important;
|
||||
list-style-type: none !important;
|
||||
}
|
||||
|
||||
/* 无序列表样式 */
|
||||
.markdown-container >>> .custom-unordered-list,
|
||||
.markdown-container >>> ul {
|
||||
display: block !important;
|
||||
padding-left: 0 !important;
|
||||
margin: 10rpx 0 !important;
|
||||
width: 100% !important;
|
||||
list-style-type: none !important;
|
||||
}
|
||||
|
||||
/* 针对mp-html生成的列表标记容器 */
|
||||
.markdown-container >>> div[style*="undefined"] {
|
||||
display: inline !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
/* 对列表项第一个元素特殊处理 */
|
||||
.markdown-container >>> h4 {
|
||||
display: inline !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* 列表项共用样式 */
|
||||
.markdown-container >>> .custom-list-item,
|
||||
.markdown-container >>> ol li,
|
||||
.markdown-container >>> ul li {
|
||||
display: flex !important;
|
||||
padding-left: 0 !important;
|
||||
margin-bottom: 8rpx !important;
|
||||
width: 100% !important;
|
||||
position: relative !important;
|
||||
/* 确保内容在一行显示 */
|
||||
flex-wrap: nowrap !important;
|
||||
align-items: flex-start !important; /* 顶部对齐 */
|
||||
}
|
||||
|
||||
/* 列表项内容样式 */
|
||||
.markdown-container >>> .custom-list-item > *:not(ol):not(ul),
|
||||
.markdown-container >>> ol li > *:not(ol):not(ul),
|
||||
.markdown-container >>> ul li > *:not(ol):not(ul) {
|
||||
flex: 1 !important;
|
||||
display: inline !important;
|
||||
white-space: normal !important;
|
||||
word-break: normal !important;
|
||||
width: auto !important;
|
||||
/* 确保文本不会被分列 */
|
||||
column-count: 1 !important;
|
||||
column-width: auto !important;
|
||||
column-span: all !important;
|
||||
text-align: left !important; /* 确保文本左对齐 */
|
||||
justify-content: flex-start !important; /* 左对齐 */
|
||||
text-justify: none !important; /* 禁用两端对齐 */
|
||||
letter-spacing: normal !important; /* 正常字间距 */
|
||||
word-spacing: normal !important; /* 正常词间距 */
|
||||
}
|
||||
|
||||
/* 列表项内的p标签特殊处理 */
|
||||
.markdown-container >>> ol li p,
|
||||
.markdown-container >>> ul li p,
|
||||
.markdown-container >>> .custom-list-item p {
|
||||
display: inline !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
width: auto !important;
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
/* 有序列表项编号 */
|
||||
.markdown-container >>> .custom-ordered-list > .custom-list-item::before,
|
||||
.markdown-container >>> ol > li::before {
|
||||
counter-increment: item !important;
|
||||
content: counter(item)"." !important;
|
||||
min-width: 40rpx !important;
|
||||
width: 40rpx !important;
|
||||
font-weight: bold !important;
|
||||
text-align: right !important;
|
||||
margin-right: 8rpx !important;
|
||||
padding-right: 0 !important;
|
||||
flex-shrink: 0 !important;
|
||||
align-self: flex-start !important; /* 顶部对齐 */
|
||||
/* padding-top: 1rpx !important; 微调垂直位置 */
|
||||
}
|
||||
|
||||
/* 无序列表项标记 */
|
||||
.markdown-container >>> .custom-unordered-list > .custom-list-item::before,
|
||||
.markdown-container >>> ul > li::before {
|
||||
content: "-" !important;
|
||||
min-width: 40rpx !important;
|
||||
width: 40rpx !important;
|
||||
font-weight: bold !important;
|
||||
text-align: center !important;
|
||||
margin-right: 8rpx !important;
|
||||
padding-right: 0 !important;
|
||||
flex-shrink: 0 !important;
|
||||
align-self: flex-start !important; /* 顶部对齐 */
|
||||
/* padding-top: 1rpx !important; 微调垂直位置 */
|
||||
}
|
||||
|
||||
/* 禁用可能导致问题的CSS特性 */
|
||||
.markdown-container >>> * {
|
||||
column-count: 1 !important;
|
||||
column-gap: 0 !important;
|
||||
column-rule: none !important;
|
||||
column-span: all !important;
|
||||
column-width: auto !important;
|
||||
columns: auto !important;
|
||||
}
|
||||
|
||||
/* 代码块样式 */
|
||||
.markdown-container >>> pre,
|
||||
.markdown-container >>> code {
|
||||
white-space: pre-wrap !important;
|
||||
word-break: break-all !important;
|
||||
overflow-wrap: break-word !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
/* 表格样式 */
|
||||
.markdown-container >>> table {
|
||||
border-collapse: collapse !important;
|
||||
width: 100% !important;
|
||||
margin: 0 !important;
|
||||
table-layout: fixed !important; /* 使用固定表格布局 */
|
||||
border: 1px solid #e0e0e0 !important;
|
||||
font-size: 24rpx !important; /* 稍微减小字体大小,适应移动端 */
|
||||
overflow-x: visible !important; /* 移除溢出隐藏 */
|
||||
}
|
||||
|
||||
.markdown-container >>> table th,
|
||||
.markdown-container >>> table td {
|
||||
border: 1px solid #e0e0e0 !important;
|
||||
padding: 8rpx 10rpx !important; /* 减小内边距 */
|
||||
text-align: left !important;
|
||||
word-break: break-word !important; /* 确保长文本会自动换行 */
|
||||
white-space: normal !important;
|
||||
vertical-align: middle !important;
|
||||
min-width: 80rpx !important; /* 设置最小宽度 */
|
||||
max-width: none !important; /* 移除最大宽度限制 */
|
||||
width: auto !important; /* 使列宽自动调整 */
|
||||
overflow-wrap: break-word !important; /* 确保长单词会换行 */
|
||||
}
|
||||
|
||||
.markdown-container >>> table th {
|
||||
background-color: #f5f5f5 !important;
|
||||
font-weight: bold !important;
|
||||
color: #333333 !important;
|
||||
}
|
||||
|
||||
.markdown-container >>> table tr:nth-child(even) {
|
||||
background-color: #fafafa !important;
|
||||
}
|
||||
|
||||
.markdown-container >>> table tr:hover {
|
||||
background-color: #f0f0f0 !important;
|
||||
}
|
||||
|
||||
/* 表格容器 - 移除水平滚动 */
|
||||
.markdown-container >>> .table-container {
|
||||
width: 100% !important;
|
||||
overflow-x: visible !important; /* 移除水平滚动 */
|
||||
margin: 16rpx 0 30rpx !important; /* 增加底部边距,与下方内容分开 */
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* 表格整体显示 */
|
||||
.markdown-container >>> .custom-table {
|
||||
width: 100% !important;
|
||||
table-layout: fixed !important; /* 固定布局 */
|
||||
overflow: visible !important; /* 显示所有内容 */
|
||||
}
|
||||
|
||||
/* 表格标题 */
|
||||
.markdown-container >>> table caption {
|
||||
font-weight: bold !important;
|
||||
padding: 10rpx !important;
|
||||
caption-side: top !important;
|
||||
text-align: center !important;
|
||||
color: #333333 !important;
|
||||
}
|
||||
|
||||
/* 分隔线样式优化 */
|
||||
.markdown-container >>> hr {
|
||||
display: block !important;
|
||||
height: 2rpx !important;
|
||||
border: 0 !important;
|
||||
border-top: 2rpx solid #e0e0e0 !important;
|
||||
margin: 24rpx 0 !important; /* 增加上下边距 */
|
||||
padding: 0 !important;
|
||||
clear: both !important;
|
||||
background-color: #e0e0e0 !important;
|
||||
}
|
||||
</style>
|
|
@ -129,7 +129,7 @@
|
|||
},
|
||||
"h5" : {
|
||||
"devServer" : {
|
||||
"port" : 8080,
|
||||
"port" : 8088,
|
||||
"disableHostCheck" : true,
|
||||
// "proxy" : {
|
||||
// "/api" : {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,7 +21,7 @@
|
|||
<image
|
||||
class="avatar-image"
|
||||
:src="
|
||||
userInfo.avatar || '/static/common/images/avatar_default.png'
|
||||
userInfo.avatar || '/static/common/images/avatar_default.jpg'
|
||||
"
|
||||
mode="aspectFill"
|
||||
@click="chooseAvatar"
|
||||
|
@ -35,17 +35,22 @@
|
|||
<view class="info-item">
|
||||
<text class="item-label">姓名</text>
|
||||
<view class="item-content">
|
||||
<text>{{ userInfo.name }}</text>
|
||||
<input
|
||||
class="item-input"
|
||||
v-model="userInfo.name"
|
||||
placeholder="请输入姓名"
|
||||
placeholder-style="color: #CCCCCC;"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="info-item">
|
||||
<text class="item-label">性别</text>
|
||||
<view class="item-content" @click="openPicker('gender')">
|
||||
<text class="placeholder-text" v-if="!userInfo.gender"
|
||||
<text class="placeholder-text" v-if="!userInfo.genderText"
|
||||
>请选择性别</text
|
||||
>
|
||||
<text v-else>{{ userInfo.gender }}</text>
|
||||
<text v-else>{{ userInfo.genderText }}</text>
|
||||
<text class="arrow-icon">></text>
|
||||
</view>
|
||||
</view>
|
||||
|
@ -106,9 +111,26 @@
|
|||
</u-button>
|
||||
</div>
|
||||
|
||||
<!-- 性别选择器 -->
|
||||
<u-select
|
||||
v-model="showGenderSelect"
|
||||
mode="single-column"
|
||||
:list="genderList"
|
||||
@confirm="confirmGender"
|
||||
></u-select>
|
||||
|
||||
<!-- 归属地选择器 -->
|
||||
<u-picker
|
||||
v-model="showRegionSelect"
|
||||
mode="single-column"
|
||||
:list="regionList"
|
||||
@confirm="confirmRegion"
|
||||
></u-picker>
|
||||
|
||||
<!-- 选择器弹窗 -->
|
||||
<u-picker
|
||||
v-model="showPicker"
|
||||
mode="selector"
|
||||
:columns="pickerColumns"
|
||||
@confirm="onPickerConfirm"
|
||||
@cancel="showPicker = false"
|
||||
|
@ -122,8 +144,8 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
userInfo: {
|
||||
avatar: "/static/common/images/avatar_default.png",
|
||||
name: "杨翼",
|
||||
avatar: "",
|
||||
name: "",
|
||||
gender: "",
|
||||
region: "",
|
||||
examYear: "",
|
||||
|
@ -145,6 +167,33 @@ export default {
|
|||
"机械工程",
|
||||
],
|
||||
},
|
||||
|
||||
// 性别选择器
|
||||
showGenderSelect: false,
|
||||
genderList: [
|
||||
{
|
||||
label: "男",
|
||||
value: "0",
|
||||
},
|
||||
{
|
||||
label: "女",
|
||||
value: "1",
|
||||
},
|
||||
],
|
||||
|
||||
// 归属地选择器
|
||||
showRegionSelect: false,
|
||||
regionList: [
|
||||
{
|
||||
label: "北京",
|
||||
value: "0",
|
||||
},
|
||||
{
|
||||
label: "上海",
|
||||
value: "1",
|
||||
},
|
||||
|
||||
],
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
|
@ -175,6 +224,11 @@ export default {
|
|||
});
|
||||
},
|
||||
openPicker(type) {
|
||||
if (type === "gender") {
|
||||
this.showGenderSelect = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentPicker = type;
|
||||
this.pickerColumns = [this.pickerData[type]];
|
||||
this.showPicker = true;
|
||||
|
@ -197,6 +251,14 @@ export default {
|
|||
}
|
||||
this.showPicker = false;
|
||||
},
|
||||
|
||||
// 确认性别
|
||||
confirmGender(e) {
|
||||
console.log("确认性别", e[0].value);
|
||||
this.userInfo.gender = e[0].value;
|
||||
this.userInfo.genderText = e[0].label;
|
||||
this.showGenderSelect = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -37,14 +37,14 @@
|
|||
|
||||
<view class="form-content">
|
||||
<view class="form-item">
|
||||
<text class="form-label"
|
||||
<view class="form-label"
|
||||
><image
|
||||
class="image_icon"
|
||||
src="/static/common/images/icon_phoneNumber.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
手机号</text
|
||||
>
|
||||
<text>手机号</text>
|
||||
</view>
|
||||
<view class="input-wrapper">
|
||||
<input
|
||||
type="number"
|
||||
|
@ -59,13 +59,14 @@
|
|||
</view>
|
||||
|
||||
<view class="form-item" v-if="isTeacher && loginType === 'psd'">
|
||||
<text class="form-label"
|
||||
<view class="form-label"
|
||||
><image
|
||||
class="image_icon"
|
||||
src="/static/common/images/icon_password.png"
|
||||
mode="scaleToFill"
|
||||
/>密码</text
|
||||
>
|
||||
/>
|
||||
<text>密码</text>
|
||||
</view>
|
||||
<view class="input-wrapper">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -81,14 +82,14 @@
|
|||
</view>
|
||||
|
||||
<view class="form-item" v-if="loginType === 'code'">
|
||||
<text class="form-label">
|
||||
<view class="form-label">
|
||||
<image
|
||||
class="image_icon"
|
||||
src="/static/common/images/icon_verificationCode.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
图形验证码</text
|
||||
>
|
||||
<text>图形验证码</text>
|
||||
</view>
|
||||
<view class="input-wrapper">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -111,14 +112,14 @@
|
|||
</view>
|
||||
|
||||
<view class="form-item" v-if="loginType === 'code'">
|
||||
<text class="form-label">
|
||||
<view class="form-label">
|
||||
<image
|
||||
class="image_icon"
|
||||
src="/static/common/images/icon_verificationCode.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
验证码</text
|
||||
>
|
||||
<text>验证码</text>
|
||||
</view>
|
||||
<view class="input-wrapper">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -236,6 +237,7 @@ export default {
|
|||
title: res.error || "发送失败",
|
||||
type: "error",
|
||||
});
|
||||
this.refreshCaptcha();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -331,25 +333,27 @@ export default {
|
|||
|
||||
// 登录
|
||||
login() {
|
||||
const res = {
|
||||
data: {
|
||||
token:
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zaWQiOiJiNTI2OWVkMS01YmM4LTExZjAtOWE4OS0wMDE2M2UyZDJkZDMiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbiIsIlVzZXJJbmZvIjoie1wiSWRcIjpcImI1MjY5ZWQxLTViYzgtMTFmMC05YTg5LTAwMTYzZTJkMmRkM1wiLFwiTmFtZVwiOlwi6J-56ICB5biIXCIsXCJQaG9uZU51bWJlclwiOlwiMTM1ODg4ODg4ODhcIixcIlNleFwiOjEsXCJBY2NvdW50VHlwZVwiOjJ9IiwibmJmIjoxNzUyMjIxMzI0LCJleHAiOjE3NTIzMDc3MjR9.fFQPIfzbjsa3lBf37qGzSg9leHQVFwVyl0cwvwevhd8",
|
||||
},
|
||||
};
|
||||
// const res = {
|
||||
// data: {
|
||||
// // token:
|
||||
// // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbiIsIlVzZXJJbmZvIjoie1wiSWRcIjpcImI1MjY5ZWQxLTViYzgtMTFmMC05YTg5LTAwMTYzZTJkMmRkM1wiLFwiTmFtZVwiOlwi6J-56ICB5biIXCIsXCJQaG9uZU51bWJlclwiOlwiMTM1ODg4ODg4ODhcIixcIlNleFwiOjEsXCJBY2NvdW50VHlwZVwiOjJ9IiwibmJmIjoxNzUyMTE4ODU0LCJleHAiOjE3NTIyMDUyNTR9.aF0Q-X3ebIld7RIKMMW68tXjmmR4OO08dXLAtHWuuwc",
|
||||
// token:
|
||||
// "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJVc2VyIiwiVXNlckluZm8iOiJ7XCJJZFwiOlwiNTljNzIxNmMtMTRhZS00NmRmLTkxYTItNGYzMjFlZjM2YjQ5XCIsXCJOYW1lXCI6XCIxNzMzNTM3NDg4N1wiLFwiUGhvbmVOdW1iZXJcIjpcIjE3MzM1Mzc0ODg3XCIsXCJTZXhcIjoyLFwiQWNjb3VudFR5cGVcIjowfSIsIm5iZiI6MTc1MjExMDcwOSwiZXhwIjoxNzUyMTk3MTA5fQ.VDv2KjGq3s3BbZxZjB3P-BaeDU_1vIdqFEWGGvdpIxU",
|
||||
// },
|
||||
// };
|
||||
|
||||
const token = res.data.token;
|
||||
// 解析获取用户信息
|
||||
const userInfo = getUserInfoFromJWT(token);
|
||||
// 保存登录后得到的用户数据
|
||||
this.$u.vuex("vuex_token", token);
|
||||
this.$u.vuex("vuex_user", userInfo);
|
||||
// const token = res.data.token;
|
||||
// // 解析获取用户信息
|
||||
// const userInfo = getUserInfoFromJWT(token);
|
||||
// // 保存登录后得到的用户数据
|
||||
// this.$u.vuex("vuex_token", token);
|
||||
// this.$u.vuex("vuex_user", userInfo);
|
||||
|
||||
// 跳转至首页
|
||||
uni.reLaunch({
|
||||
url: "/pages/home/index/index",
|
||||
});
|
||||
return;
|
||||
// // 跳转至首页
|
||||
// uni.reLaunch({
|
||||
// url: "/pages/home/index/index",
|
||||
// });
|
||||
// return;
|
||||
|
||||
// 校验手机号
|
||||
if (!this.validatePhone()) {
|
||||
|
@ -454,7 +458,7 @@ export default {
|
|||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
|
||||
background-image: url(/static/common/images/images_bg.png);
|
||||
background-image: url("@/static/common/images/images_bg.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 50%;
|
||||
|
@ -553,9 +557,8 @@ export default {
|
|||
margin-bottom: 32rpx;
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
position: relative;
|
||||
// padding-left: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: PingFang SC;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
@ -565,7 +568,6 @@ export default {
|
|||
.image_icon {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
vertical-align: text-top;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
|
@ -1,6 +1,7 @@
|
|||
export default {
|
||||
//不需要登录的页面,白名单
|
||||
whiteList: [
|
||||
"/pages/login/login/index",
|
||||
"/pages/login/login/login",
|
||||
"/pages/login/register/register",
|
||||
"/pages/login/confirmPwd/confirmPwd",
|
||||
|
@ -14,5 +15,5 @@ export default {
|
|||
'/pages/login/recognitionResult/recognitionFailed'
|
||||
],
|
||||
//登录页
|
||||
loginPage:"/pages/login/login/login"
|
||||
loginPage:"/pages/login/login/index"
|
||||
}
|
|
@ -1,56 +1,58 @@
|
|||
import config from "./config.js"
|
||||
const initApp = function(vm) {
|
||||
/**
|
||||
* 页面跳转拦截器
|
||||
*/
|
||||
let that = vm;
|
||||
let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"];
|
||||
list.forEach(item => { //用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器
|
||||
uni.addInterceptor(item, {
|
||||
invoke(e) { // 调用前拦截
|
||||
//获取用户的token
|
||||
// console.log(e)
|
||||
const token = that.vuex_token,
|
||||
//获取要跳转的页面路径(url去掉"?"和"?"后的参数)
|
||||
url = e.url.split('?')[0];
|
||||
let notNeed = config.whiteList.includes(url)
|
||||
// 如果在whiteList里面就不需要登录
|
||||
// console.log(notNeed)
|
||||
import config from "./config.js";
|
||||
const initApp = function (vm) {
|
||||
/**
|
||||
* 页面跳转拦截器
|
||||
*/
|
||||
let that = vm;
|
||||
let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"];
|
||||
list.forEach((item) => {
|
||||
//用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器
|
||||
uni.addInterceptor(item, {
|
||||
invoke(e) {
|
||||
// 调用前拦截
|
||||
//获取用户的token
|
||||
// console.log(e)
|
||||
const token = that.vuex_token,
|
||||
//获取要跳转的页面路径(url去掉"?"和"?"后的参数)
|
||||
url = e.url.split("?")[0];
|
||||
let notNeed = config.whiteList.includes(url);
|
||||
// 如果在whiteList里面就不需要登录
|
||||
// console.log(notNeed)
|
||||
|
||||
if (notNeed) {
|
||||
return e
|
||||
} else {
|
||||
//需要登录
|
||||
if (token == '') {
|
||||
// uni.showToast({
|
||||
// title: '请先登录',
|
||||
// icon: 'none'
|
||||
// })
|
||||
// uni.navigateTo({
|
||||
// url: config.loginPage
|
||||
// })
|
||||
uni.navigateTo({
|
||||
url: '/'
|
||||
})
|
||||
return false
|
||||
} else {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
fail(err) { // 失败回调拦截
|
||||
console.log(err)
|
||||
// if (Debug) {
|
||||
// uni.showModal({
|
||||
// content: JSON.stringify(err),
|
||||
// showCancel: false
|
||||
// });
|
||||
// }
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
if (notNeed) {
|
||||
return e;
|
||||
} else {
|
||||
//需要登录
|
||||
if (token == "") {
|
||||
// uni.showToast({
|
||||
// title: '请先登录',
|
||||
// icon: 'none'
|
||||
// })
|
||||
// uni.navigateTo({
|
||||
// url: config.loginPage
|
||||
// })
|
||||
uni.navigateTo({
|
||||
url: "/pages/login/login/index",
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
},
|
||||
fail(err) {
|
||||
// 失败回调拦截
|
||||
console.log(err);
|
||||
// if (Debug) {
|
||||
// uni.showModal({
|
||||
// content: JSON.stringify(err),
|
||||
// showCancel: false
|
||||
// });
|
||||
// }
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
export default {
|
||||
initApp: initApp
|
||||
}
|
||||
initApp: initApp,
|
||||
};
|
||||
|
|
|
@ -13,7 +13,8 @@ try {
|
|||
}
|
||||
|
||||
// 需要永久存储,且下次APP启动需要取出的,在state中的变量名
|
||||
let saveStateKeys = ['vuex_user', 'vuex_token', 'vuex_msgList', 'vuex_glyType', 'vuex_userLocation','vuex_userInfo','vuex_user_hobby','vuex_teacherInfo'];
|
||||
// let saveStateKeys = ['vuex_user', 'vuex_token', 'vuex_msgList', 'vuex_glyType', 'vuex_userLocation','vuex_userInfo','vuex_user_hobby'];
|
||||
let saveStateKeys = ['vuex_user', 'vuex_token'];
|
||||
|
||||
// 保存变量到本地存储中
|
||||
const saveLifeData = function (key, value) {
|
||||
|
|
|
@ -26,6 +26,9 @@ class Request {
|
|||
options.header = Object.assign({}, this.config.header, options.header);
|
||||
options.method = options.method || this.config.method;
|
||||
|
||||
// 从请求选项中获取showLoading参数,如果未定义,则使用全局配置
|
||||
const showLoading = options.header.showLoading !== undefined ? options.header.showLoading : this.config.showLoading;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
options.complete = (response) => {
|
||||
// 请求返回后,隐藏loading(如果请求返回快的话,可能会没有loading)
|
||||
|
@ -81,7 +84,7 @@ class Request {
|
|||
// 是否显示loading
|
||||
// 加一个是否已有timer定时器的判断,否则有两个同时请求的时候,后者会清除前者的定时器id
|
||||
// 而没有清除前者的定时器,导致前者超时,一直显示loading
|
||||
if(this.config.showLoading && !this.config.timer) {
|
||||
if(showLoading && !this.config.timer) {
|
||||
this.config.timer = setTimeout(() => {
|
||||
uni.showLoading({
|
||||
title: this.config.loadingText,
|
||||
|
|
|
@ -4,8 +4,8 @@ module.exports = {
|
|||
devServer: {
|
||||
// 调试时允许内网穿透,让外网的人访问到本地调试的H5页面
|
||||
disableHostCheck: true,
|
||||
port: '8080',
|
||||
port: '8088',
|
||||
}
|
||||
},
|
||||
//productionSourceMap: false,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue