初始化
This commit is contained in:
parent
f9418c40b9
commit
631525e44e
|
|
@ -0,0 +1,434 @@
|
|||
<script>
|
||||
import router from "./static/common/js/router";
|
||||
import config from "./static/common/js/config.js"
|
||||
|
||||
var jweixin = require("jweixin-module");
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
}
|
||||
},
|
||||
globalData: {},
|
||||
created() {
|
||||
|
||||
},
|
||||
onLaunch() {
|
||||
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)
|
||||
if (notNeed) {
|
||||
uni.navigateTo({
|
||||
url: this._route.fullPath,
|
||||
});
|
||||
return
|
||||
}
|
||||
var that = this;
|
||||
uni.getSystemInfo({
|
||||
success: function (res) {
|
||||
// 根据 model 进行判断
|
||||
if (res.model.indexOf("iPhone") >= 0) {
|
||||
that.$u.vuex("vuex_iPhone", true);
|
||||
}
|
||||
},
|
||||
});
|
||||
if (!that.vuex_user.isFill) {
|
||||
this.$u.vuex("vuex_msgList", "");
|
||||
this.$u.vuex("vuex_user", "");
|
||||
this.$u.vuex("vuex_token", "");
|
||||
this.$u.vuex("vuex_userInfo", "");
|
||||
uni.clearStorage();
|
||||
this.$u.route({
|
||||
url: "/pages/login/login/login",
|
||||
});
|
||||
return;
|
||||
|
||||
uni.navigateTo({
|
||||
url: "/pages/login/roleSelection",
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
// onShow(){
|
||||
// console.log('onShow')
|
||||
// },
|
||||
methods: {
|
||||
getLocation() {
|
||||
var that = this;
|
||||
if (this.isWechat()) {
|
||||
const isiOS = !!navigator.userAgent.match(
|
||||
/\(i[^;]+;( U;)? CPU.+Mac OS X/
|
||||
); //ios终端
|
||||
// 进行签名的时候 Android 不用使用之前的链接, ios 需要
|
||||
const signLink = isiOS
|
||||
? window.entryUrl
|
||||
: window.location.href.split("#")[0];
|
||||
//获取当前url然后传递给后台获取授权和签名信息,后台需要解码才能使用
|
||||
// const url =encodeURIComponent(signLink);
|
||||
const url = signLink;
|
||||
const data = {
|
||||
url: url,
|
||||
};
|
||||
this.$u.api.GetInfoMation(data).then((res) => {
|
||||
jweixin.config({
|
||||
debug: false,
|
||||
appId: res.appId,
|
||||
timestamp: res.timestamp,
|
||||
nonceStr: res.noncestr,
|
||||
signature: res.signature,
|
||||
jsApiList: [
|
||||
//这里是需要用到的接口名称
|
||||
"getLocation", //获取位置
|
||||
"openLocation", //打开位置
|
||||
],
|
||||
});
|
||||
|
||||
// jweixin.config 执行失败时调用
|
||||
jweixin.error((err) => {
|
||||
uni.hideLoading();
|
||||
console.log("授权失败,您可能无法使用部分功能", err);
|
||||
});
|
||||
jweixin.ready(function () {
|
||||
jweixin.getLocation({
|
||||
type: "gcj02", // 默认为wgs84的gps坐标,如果要返 回直接给openLocation用的火星坐标,可传入'gcj02'
|
||||
success: (res) => {
|
||||
uni.hideLoading();
|
||||
that.$u.vuex('vuex_userLocation', res)
|
||||
|
||||
var data = {
|
||||
userId: that.vuex_user.id,
|
||||
longitude: res.longitude + "",
|
||||
latitude: res.latitude + "",
|
||||
};
|
||||
that.$u.api.upPosition(data)
|
||||
},
|
||||
fail: function (res) {
|
||||
uni.hideLoading();
|
||||
console.log(res, "err");
|
||||
},
|
||||
complete: function (res) {
|
||||
uni.hideLoading();
|
||||
console.log(res, "is");
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
uni.getLocation({
|
||||
type: "gcj02 ",
|
||||
isHighAccuracy: true,
|
||||
highAccuracyExpireTime: 3000,
|
||||
success: (res) => {
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
this.$u.vuex('vuex_userLocation', res)
|
||||
var data = {
|
||||
userId: this.vuex_user.id,
|
||||
longitude: res.longitude + "",
|
||||
latitude: res.latitude + "",
|
||||
};
|
||||
this.$u.api.upPosition(data)
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.hideLoading();
|
||||
console.log("地理位置获取失败", err);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
isWechat() {
|
||||
var ua = window.navigator.userAgent.toLowerCase();
|
||||
if (ua.match(/micromessenger/i) == "micromessenger") {
|
||||
// console.log(‘是微信客户端’)
|
||||
return true;
|
||||
} else {
|
||||
// console.log(‘不是微信客户端’)
|
||||
return false;
|
||||
}
|
||||
},
|
||||
charLink() {
|
||||
var that = this;
|
||||
(function start(ms) {
|
||||
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);
|
||||
});
|
||||
} catch (e) {
|
||||
//重试
|
||||
return start(5000);
|
||||
}
|
||||
}, ms);
|
||||
})(0)
|
||||
//接收消息
|
||||
this.$connection.on("ReceiveMessage", (user, message, type) => {
|
||||
|
||||
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
|
||||
// 管理员对普通用户
|
||||
if (type == 4) {
|
||||
user = 'admin'
|
||||
}
|
||||
if (type == 3) {
|
||||
user += 'user'
|
||||
}
|
||||
if (msgList.indexOf(user) < 0) {
|
||||
msgList += (user + ',');
|
||||
}
|
||||
this.$u.vuex('vuex_msgList', msgList)
|
||||
}
|
||||
});
|
||||
//接收系统消息
|
||||
this.$connection.on("SystemMessage", (title, content, time) => {
|
||||
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_msgList', msgList)
|
||||
}
|
||||
});
|
||||
//接收互动消息
|
||||
this.$connection.on("InteractMessage", (data, type) => {
|
||||
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_msgList', msgList)
|
||||
}
|
||||
});
|
||||
},
|
||||
CharLogin() {
|
||||
//绑定用户账号和connectionId
|
||||
if (this.vuex_user.id) {
|
||||
this.$connection
|
||||
.invoke("login", this.connectionId, this.vuex_user.id)
|
||||
.then((res) => {
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
});
|
||||
//初始化获取定位
|
||||
this.getLocation()
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.CharLogin()
|
||||
}, 1000)
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.charLink()
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "uview-ui/index.scss";
|
||||
@import "common/demo.scss";
|
||||
|
||||
.u-tabbar__content__item__button {
|
||||
top: 0.07rem !important;
|
||||
}
|
||||
|
||||
.u-navbar-placeholder,
|
||||
.u-navbar-inner {
|
||||
height: 0.44rem !important;
|
||||
}
|
||||
|
||||
.u-tabbar__content__item__text {
|
||||
font-size: 20rpx !important;
|
||||
}
|
||||
|
||||
.u-tabbar__content__item__button .u-icon__img {
|
||||
width: 44rpx !important;
|
||||
height: 44rpx !important;
|
||||
}
|
||||
|
||||
.u-size-mini {
|
||||
font-size: 0.12rem !important;
|
||||
}
|
||||
|
||||
uni-modal .uni-modal__hd {
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
uni-modal .uni-modal__bd {
|
||||
padding-top: 20rpx;
|
||||
// font-weight: bold;
|
||||
font-size: 34rpx;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
uni-modal .uni-modal__btn {
|
||||
border-radius: 16rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
uni-modal .uni-modal__btn:after {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
uni-modal .uni-modal__btn_default {
|
||||
background: #e6f6ff;
|
||||
color: #3CB5FB !important;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
uni-modal .uni-modal__ft {
|
||||
line-height: 80rpx;
|
||||
}
|
||||
|
||||
uni-modal .uni-modal__ft:after {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
uni-modal .uni-modal__btn_primary {
|
||||
background: #3cb5fb;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
|
||||
uni-modal .uni-modal {
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
|
||||
.u-tabbar__content {
|
||||
height: 0.5rem !important;
|
||||
}
|
||||
|
||||
.phone .u-tabbar__content {
|
||||
padding-bottom: 0.14rem;
|
||||
}
|
||||
|
||||
.u-tabs-scorll-flex .u-tabs-item {
|
||||
transition: all 0.1s;
|
||||
font-size: 0.15rem !important;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "pingfang";
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 200rpx;
|
||||
}
|
||||
|
||||
uni-page-body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
"Microsoft Yahei", sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
// max-width: 1536rpx;
|
||||
margin: 0 auto;
|
||||
background-color: #f6f7fa;
|
||||
}
|
||||
|
||||
view,
|
||||
image,
|
||||
text {
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#app {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.justify-start {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-end {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.justify-evenly {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.justify-around {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.justify-between {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.items-start {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.items-end {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 www.uviewui.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# 校柚(H5)
|
||||
|
||||
#### Description
|
||||
校柚(H5)
|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
|
||||
#### Installation
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Instructions
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Contribution
|
||||
|
||||
1. Fork the repository
|
||||
2. Create Feat_xxx branch
|
||||
3. Commit your code
|
||||
4. Create Pull Request
|
||||
|
||||
|
||||
#### Gitee Feature
|
||||
|
||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,86 @@
|
|||
/* #ifndef APP-NVUE */
|
||||
view,
|
||||
text {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
/* start--演示页面使用的统一样式--start */
|
||||
.u-demo {
|
||||
padding: 25px 20px;
|
||||
}
|
||||
|
||||
.u-demo-wrap {
|
||||
border-width: 1px;
|
||||
border-color: #ddd;
|
||||
border-style: dashed;
|
||||
background-color: rgb(250, 250, 250);
|
||||
padding: 20px 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.u-demo-area {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.u-no-demo-here {
|
||||
color: $u-tips-color;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.u-demo-result-line {
|
||||
border-width: 1px;
|
||||
border-color: #ddd;
|
||||
border-style: dashed;
|
||||
padding: 5px 20px;
|
||||
margin-top: 30px;
|
||||
border-radius: 5px;
|
||||
background-color: rgb(240, 240, 240);
|
||||
color: $u-content-color;
|
||||
font-size: 16px;
|
||||
/* #ifndef APP-NVUE */
|
||||
word-break: break-word;
|
||||
display: inline-block;
|
||||
/* #endif */
|
||||
text-align: left;
|
||||
|
||||
}
|
||||
|
||||
.u-demo-title,
|
||||
.u-config-title {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.u-config-item {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.u-config-title {
|
||||
margin-top: 20px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.u-item-title {
|
||||
position: relative;
|
||||
font-size: 15px;
|
||||
padding-left: 8px;
|
||||
line-height: 1;
|
||||
margin-bottom: 11px;
|
||||
}
|
||||
|
||||
.u-item-title:after {
|
||||
position: absolute;
|
||||
width: 4px;
|
||||
top: -1px;
|
||||
height: 16px;
|
||||
/* #ifndef APP-NVUE */
|
||||
content: '';
|
||||
/* #endif */
|
||||
left: 0;
|
||||
border-radius: 10px;
|
||||
background-color: $u-content-color;
|
||||
}
|
||||
/* end--演示页面使用的统一样式--end */
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
// 此处第二个参数vm,就是我们在页面使用的this,你可以通过vm获取vuex等操作
|
||||
const install = (Vue, vm) => {
|
||||
// 登录
|
||||
let LoginApp = (params = {}) => vm.$u.post('api/Token/LoginApp', params)
|
||||
// 注册
|
||||
let RegisterUser = (params = {}) => vm.$u.post('api/Token/RegisterUser', params);
|
||||
// 基础资料以及保存用户头像
|
||||
let saveUserInfo = (params = {}) => vm.$u.post('app/User/UploadingFormFileHead', params);
|
||||
// 更新用户定位信息
|
||||
let upPosition = (params = {}) => vm.$u.post('app/Position/InsertPosition', params);
|
||||
// 获取用户当前定位信息
|
||||
let getPosition = (params = {}) => vm.$u.get('app/Position/GetPositionByUser', {
|
||||
userId: vm.vuex_user.id
|
||||
});
|
||||
// 获取所有学校
|
||||
let GetAllSchool = (params = {}) => vm.$u.get('app/User/GetSchoolList', params);
|
||||
//获取首页地图信息
|
||||
let HomeMap = (params = {}) => vm.$u.get('/app/User/HomeMap', params);
|
||||
//修改密码
|
||||
let ChangePassword = (params = {}) => vm.$u.post('app/User/ChangePassword', params);
|
||||
//修改密码
|
||||
let myChangePassword = (params = {}) => vm.$u.post('app/My/ChangePassword', params);
|
||||
// 获取搜索页面相关信息
|
||||
let SearchInfo = (params = {}) => vm.$u.get('app/User/SearchRelevant', params);
|
||||
//获取搜索结果页面
|
||||
let getSearch = (params = {}) => vm.$u.get('app/User/GetSearchList', params);
|
||||
// 获取用户信息
|
||||
let getUserInfo = (params = {}) => vm.$u.get('app/User/HomePage', params);
|
||||
// 获取校友帮帮列表
|
||||
let GetHelpList = (params = {}) => vm.$u.get('app/HelpArticle/GetHelpArticleListByKey', params);
|
||||
// 获取学校资讯
|
||||
let GetSchoolList = (params = {}) => vm.$u.get('app/AlumnRange/AlumnRangeSchool', params);
|
||||
//获取最新的用户信息(更新用户数据)
|
||||
let getUser = (params = {}) => vm.$u.get('app/User/GetUser', {userId: vm.vuex_user.id}).then(res => {
|
||||
vm.$u.get('/app/User/GetUserSchool').then(ress => {
|
||||
// res.isAttestationGLY = ress.isAttestationGLY
|
||||
// res.isAttestationJZG = ress.isAttestationJZG
|
||||
// res.isAttestationQY = ress.isAttestationQY
|
||||
// res.isAttestationXY = res.isAttestationXY
|
||||
// res.isAttestationZXS = ress.isAttestationZXS
|
||||
res.schoolId = ress.items.schoolId
|
||||
vm.$u.vuex('vuex_user', {...res.user,...res.userExtension})
|
||||
vm.$u.vuex('vuex_user_hobby', res.lableList)
|
||||
})
|
||||
})
|
||||
//获取用户消息列表
|
||||
let getcharList = (params = {}) => vm.$u.get('app/Chat/GetUserMessageList', params);
|
||||
//获取用户获取关注列表
|
||||
let getFollowList = (params = {}) => vm.$u.get('app/Chat/GetFollowList', {id: vm.vuex_user.id});
|
||||
// 获取系统消息列表
|
||||
let getSysList = (params = {}) => vm.$u.get('app/Chat/GetSystemMessageList', {id: vm.vuex_user.id});
|
||||
//获取管理消息列表
|
||||
let getAdminList = (params = {}) => vm.$u.get('app/Chat/GetManageMessageList', {schoolId: vm.vuex_user.id});
|
||||
//获取互动信息列表
|
||||
let getinteractionList = (params) => vm.$u.get('app/Chat/GetInterMessageList', {id: vm.vuex_user.id, type: params});
|
||||
//校友找找推荐列表
|
||||
let getAlumnSearch = (params = {}) => vm.$u.get('app/AlumnRange/AlumnSearch', params);
|
||||
//获取聊天记录
|
||||
let getChatRecord = (params = {}) => vm.$u.get('app/Chat/GetChatRecord', params);
|
||||
//校友找找列表
|
||||
let AlumnSearchList = (params = {}) => vm.$u.get('app/AlumnRange/AlumnSearchList', params);
|
||||
// 初始化的数据调用微信接口返回参数
|
||||
let GetInfoMation = (params = {}) => vm.$u.get('api/Token/GetInfoMation', params);
|
||||
// 回复绑定
|
||||
let toBind = (params = {}) => vm.$u.get('app/Chat/ReplyBind', params);
|
||||
//我的资讯
|
||||
let MyAlumnRange = (params = {}) => vm.$u.get('app/My/MyAlumnRange', params);
|
||||
// 解除绑定
|
||||
let colseBind = (params = {}) => vm.$u.get('app/Chat/UnbindReply', params);
|
||||
// 删除评论
|
||||
let DelateComment = (params = {}) => vm.$u.get('app/AlumnRange/DelateComment', params);
|
||||
let userVerify = (params = {}) => vm.$u.post('api/Token/IsIdentityCard', params)
|
||||
|
||||
// 获取人脸验证token
|
||||
let getAPIToken = (params = {}) => vm.$u.post('app/My/GetVerifyToken', params)
|
||||
// 查询人脸核验结果
|
||||
let getVerifyInfo = (params = {}) => vm.$u.post('app/My/GetDetailInfo?VerifyToken=' + params)
|
||||
// 根据身份证获取信息
|
||||
let getInfoByCard = (params = {}) => vm.$u.get('app/User/GetCardByPreConfiguredUser', params);
|
||||
// 更新身份信息
|
||||
let updateCard = (params = {}) => vm.$u.post('api/Token/UpdateCard', params)
|
||||
|
||||
//【手机端】添加心愿
|
||||
let PushWishDan = (params = {}) => vm.$u.post("app/My/PushWishDan", params)
|
||||
|
||||
//【手机端】获取个人心愿列表
|
||||
let GetWishListAsync_mobile = (params = {}) => vm.$u.get("app/My/GetWishListAsync_mobile", params)
|
||||
//【手机端】删除心愿 删除=失效
|
||||
let DeleteWish = (params = {}) => vm.$u.post("app/My/DeleteWish", params)
|
||||
//【管理端】获取当前是否开启匿名 开启true 关闭false
|
||||
let CheckNM = (params = {}) => vm.$u.get("/app/My/CheckNM", params)
|
||||
|
||||
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
|
||||
vm.$u.api = {
|
||||
LoginApp,
|
||||
RegisterUser,
|
||||
saveUserInfo,
|
||||
upPosition,
|
||||
getPosition,
|
||||
GetAllSchool,
|
||||
HomeMap,
|
||||
ChangePassword,
|
||||
myChangePassword,
|
||||
SearchInfo,
|
||||
getSearch,
|
||||
getUserInfo,
|
||||
GetHelpList,
|
||||
GetSchoolList,
|
||||
getUser,
|
||||
getcharList,
|
||||
getFollowList,
|
||||
getSysList,
|
||||
getAdminList,
|
||||
getinteractionList,
|
||||
getAlumnSearch,
|
||||
getChatRecord,
|
||||
AlumnSearchList,
|
||||
GetInfoMation,
|
||||
toBind,
|
||||
colseBind,
|
||||
MyAlumnRange,
|
||||
DelateComment,
|
||||
userVerify,
|
||||
GetWishListAsync_mobile,
|
||||
DeleteWish,
|
||||
CheckNM,
|
||||
PushWishDan,
|
||||
getAPIToken,
|
||||
getVerifyInfo,
|
||||
getInfoByCard,
|
||||
updateCard
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
install
|
||||
}
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
// 此处第二个参数vm,就是我们在页面使用的this,你可以通过vm获取vuex等操作
|
||||
const install = (Vue, vm) => {
|
||||
// 获取行业下所有子行业和标签
|
||||
let GetLableList = (params = {}) => vm.$u.get('app/User/GetLableList', params)
|
||||
// 获取兴趣标签
|
||||
let GetInterestLable = (params = {}) => vm.$u.get('app/User/GetInterestLable', params)
|
||||
// 修改个人资料
|
||||
let UpdateUser = (params = {}) => vm.$u.post('app/User/UpdateUser', params);
|
||||
// 获取所有工作领域
|
||||
let GetWorkFile = (params = {}) => vm.$u.get('app/User/GetWorkFileList', params);
|
||||
// 我的页面
|
||||
let MyPage = (params = {}) => vm.$u.get('app/My/MyPage', params);
|
||||
// 我的教育经历
|
||||
let MyEducations = (params = {}) => vm.$u.get('app/My/MyEducations', params);
|
||||
// 添加教育经历
|
||||
let AddEducation = (params = {}) => vm.$u.post('app/My/AddEducation', params);
|
||||
// 提交校友认证
|
||||
let SubmitAttestationXY = (params = {}) => vm.$u.post('app/My/SubmitAttestationXY', params);
|
||||
// 选择已认证的教育经历 返回学校ID
|
||||
let SelectEducation = (params = {}) => vm.$u.post('app/My/SelectEducation', params);
|
||||
// 我的发布
|
||||
let Publishs = (params = {}) => vm.$u.get('app/My/Publish', params);
|
||||
//用户发布学校资讯
|
||||
let InsertJournaArticle = (params = {}) => vm.$u.post('app/AlumnRange/InsertJournaArticle', params);
|
||||
//用户发布帮帮资讯
|
||||
let InsertHelpArticle = (params = {}) => vm.$u.post('app/AlumnRange/InsertHelpArticle', params);
|
||||
//管理员认证
|
||||
let AttestationGLY = (params = {}) => vm.$u.get('app/My/AttestationGLY', params);
|
||||
//提交管理员认证
|
||||
let SubmitAttestationGLY = (params = {}) => vm.$u.post('app/My/SubmitAttestationGLY', params);
|
||||
//教职工认证
|
||||
let AttestationJZG = (params = {}) => vm.$u.get('app/My/AttestationJZG', params);
|
||||
//提交教职工认证
|
||||
let SubmitAttestationJZG = (params = {}) => vm.$u.post('app/My/SubmitAttestationJZG', params);
|
||||
//基础资料以及教职工认证
|
||||
let UpdateUserJZG = (params = {}) => vm.$u.post("app/User/UpdateUserJZG", params)
|
||||
|
||||
//企业认证
|
||||
let AttestationQY = (params = {}) => vm.$u.get('app/My/AttestationQY', params);
|
||||
//提交企业认证
|
||||
let SubmitAttestationQY = (params = {}) => vm.$u.post('app/My/SubmitAttestationQY', params);
|
||||
//定位、推荐、消息设置
|
||||
let Setting = (params = {}) => vm.$u.post('app/My/Setting', params);
|
||||
//获取当前登录用户
|
||||
let GetUser = (params = {}) => vm.$u.get('app/User/GetUser', params);
|
||||
//获取所有标签
|
||||
let GetSign = (params = {}) => vm.$u.get('app/AlumnRange/GetSign', params);
|
||||
//关注或取关
|
||||
let InsertOrDelFollow = (params = {}) => vm.$u.post('app/Follow/InsertOrDelFollow', params);
|
||||
//评论
|
||||
let InsertComment = (params = {}) => vm.$u.post('app/AlumnRange/InsertComment', params);
|
||||
//获取文章评论信息
|
||||
let GetJournaArticle = (params = {}) => vm.$u.get('app/AlumnRange/GetJournaArticle', params);
|
||||
//获取评论详细信息
|
||||
let GetComment = (params = {}) => vm.$u.get('app/AlumnRange/GetComment', params);
|
||||
//添加收藏(0资讯,1帮帮)
|
||||
let LikeCollect = (params = {}) => vm.$u.get('app/AlumnRange/LikeCollect', params);
|
||||
//点赞(0资讯,1帮帮,2评论) 或取消点赞
|
||||
let LikeHe = (params = {}) => vm.$u.get('app/AlumnRange/LikeHe', params);
|
||||
//用户转发帮帮资讯
|
||||
let ForwardHelpArticle = (params = {}) => vm.$u.post('app/AlumnRange/ForwardHelpArticle', params);
|
||||
//获取用户当前学校信息(未认证为空,未选中默认选择最新认证学校)
|
||||
let GetUserSchool = (params = {}) => vm.$u.get('app/User/GetUserSchool', params);
|
||||
//我的收藏
|
||||
let Collection = (params = {}) => vm.$u.get('app/My/Collection', params)
|
||||
//查看用户发布信息
|
||||
let UserHelp = (params = {}) => vm.$u.get('app/User/UserHelp', params)
|
||||
//审核列表
|
||||
let AuditList = (params = {}) => vm.$u.get('app/My/AuditList', params)
|
||||
//审核详情
|
||||
let AuditDeatil = (params = {}) => vm.$u.get('app/My/AuditDeatil', params)
|
||||
//审核
|
||||
let Audit = (params = {}) => vm.$u.post('app/My/Audit', params);
|
||||
//获取手机验证码
|
||||
let GetPhoneValidateCode = (params = {}) => vm.$u.post('api/Token/GetPhoneValidateCode', params)
|
||||
// 获取验证码
|
||||
let Captcha = (params = {}) => vm.$u.get('api/Token/Captcha', params)
|
||||
//根据页面类型获取手机验证码
|
||||
let GetAppValidateCode = (params = {}) => vm.$u.post('api/Token/GetAppValidateCode', params)
|
||||
//验证码是否正确
|
||||
let IsPhoneCode = (params = {}) => vm.$u.get('api/Token/IsPhoneCode', params)
|
||||
//学校资讯
|
||||
let AlumnRangeSchool = (params = {}) => vm.$u.get('app/AlumnRange/AlumnRangeSchool', params)
|
||||
//意见反馈
|
||||
let SubmitFeedback = (params = {}) => vm.$u.post('app/My/SubmitFeedback', params)
|
||||
//获取学校学院列表
|
||||
let GetCollegeList = (params = {}) => vm.$u.get('app/User/GetCollegeList', params)
|
||||
//获取专业列表
|
||||
let GetMajorList = (params = {}) => vm.$u.get('app/User/GetMajorList', params)
|
||||
//获取当前学校是否认证信息
|
||||
let GetUserApproval = (params = {}) => vm.$u.get('app/User/GetUserApproval', params)
|
||||
// 删除未认证教育经历
|
||||
let DeleteEducation = (params = {}) => vm.$u.get('app/My/DeleteEducation', params)
|
||||
// 删除文章
|
||||
let DelateArticle = (params = {}) => vm.$u.get('app/AlumnRange/DelateArticle', params)
|
||||
// 取消收藏
|
||||
let CancleCollect = (params = {}) => vm.$u.get('app/My/CancleCollect', params)
|
||||
//忘记密码
|
||||
let ForgotPassword = (params = {}) => vm.$u.post('admin/User/ForgotPassword', params)
|
||||
//手机申请返校预约
|
||||
let AddReturnSchoolApi = (params = {}) => vm.$u.post('app/ReturnSchoolPrebook/AddReturnSchool', params);
|
||||
// 返校预约列表 - 待审核
|
||||
let SelectReturnSchoolList_dshApi = (params = {}) => vm.$u.get('app/ReturnSchoolPrebook/SelectReturnSchoolList_dsh', params)
|
||||
// 返校预约列表 - 传状态
|
||||
let SelectReturnSchoolList_typeApi = (params = {}) => vm.$u.get('app/ReturnSchoolPrebook/SelectReturnSchoolList_type', params)
|
||||
// 获取返校预约设置
|
||||
let SelectInfoSetApi = (params = {}) => vm.$u.get('/app/ReturnSchoolPrebook/SelectInfoSet', params)
|
||||
// 获取返校预约设置 没token
|
||||
let SelectInfoSetNoTokenApi = (params = {}) => vm.$u.get('/app/Share/SelectInfoSet', params)
|
||||
// 返校预约详情
|
||||
let SelectReturnSchoolInfoApi = (params = {}) => vm.$u.post('app/ReturnSchoolPrebook/SelectReturnSchoolInfo', params);
|
||||
// 返校预约详情 没token
|
||||
let SelectReturnSchoolInfoNotokenApi = (params = {}) => vm.$u.post('/app/Share/SelectReturnSchoolInfo', params);
|
||||
// 取消返校预约
|
||||
let DelReturnSchoolInfoApi = (params = {}) => vm.$u.post('app/ReturnSchoolPrebook/DelReturnSchoolInfo', params);
|
||||
// 核验二维码
|
||||
let SaveReturnSchoolInfoApi = (params = {}) => vm.$u.post('app/ReturnSchoolPrebook/SaveReturnSchoolInfo', params);
|
||||
// 核验二维码 没token
|
||||
let SaveReturnSchoolInfoNoTokenApi = (params = {}) => vm.$u.post('app/Share/SaveReturnSchoolInfo', params);
|
||||
// 获取二维码
|
||||
let SaveReturnSchoolVerifyApi = (params = {}) => vm.$u.post('app/ReturnSchoolPrebook/SaveReturnSchoolVerify', params);
|
||||
// 获取二维码 没token
|
||||
let SaveReturnSchoolVerifyNoTokenApi = (params = {}) => vm.$u.post('app/Share/SaveReturnSchoolVerify', params);
|
||||
// 添加工作经历
|
||||
let AddWordInfoApi = (params = {}) => vm.$u.post('/app/User/AddWordInfo', params);
|
||||
// 修改工作经历
|
||||
let UpdateWorkInfoApi = (params = {}) => vm.$u.post('/app/User/UpdateWorkInfo', params);
|
||||
// 删除工作经历
|
||||
let DelWorkInfoApi = (params = {}) => vm.$u.post('/app/User/DelWorkInfo', params);
|
||||
// 添加项目经历
|
||||
let AddProjectInfoApi = (params = {}) => vm.$u.post('/app/User/AddProjectInfo', params);
|
||||
// 修改项目经历
|
||||
let UpdateProjectInfoApi = (params = {}) => vm.$u.post('/app/User/UpdateProjectInfo', params);
|
||||
// 删除项目经历
|
||||
let DelProjectInfoApi = (params = {}) => vm.$u.post('/app/User/DelProjectInfo', params);
|
||||
// 制作简历界面
|
||||
let ResumeUserApi = (params = {}) => vm.$u.get('/app/User/ResumeUser', params);
|
||||
// 附件简历列表
|
||||
let GetUserFileApi = (params = {}) => vm.$u.get('/app/User/GetUserFile', params);
|
||||
// 删除附件
|
||||
let DelUserFileApi = (params = {}) => vm.$u.post('/app/User/DelUserFile', params);
|
||||
// 设置展示简历
|
||||
let UpdateUserFileApi = (params = {}) => vm.$u.post('/app/User/UpdateUserFile', params);
|
||||
// 获取学校ID
|
||||
let GetUserSchoolApi = (params = {}) => vm.$u.get('/app/User/GetUserSchool', params);
|
||||
// 获取已预约的日期
|
||||
let GetDateTimeReturnApi = (params = {}) => vm.$u.get('/app/ReturnSchoolPrebook/GetDateTimeReturn', params);
|
||||
// 选择教职工认证
|
||||
let SelectJZGApi = (params = {}) => vm.$u.post('/app/My/SelectJZG', params);
|
||||
|
||||
let ForgotPasswordValidate = (params = {}) => vm.$u.post('/admin/User/ForgotPasswordValidate', params);
|
||||
//忘记密码-验证验证码
|
||||
|
||||
// 删除
|
||||
let DeleteJZGApi = (params = {}) => vm.$u.get('/app/My/DeleteJZG', params);
|
||||
// 返回判断用户身份信息
|
||||
let SelectUserTypeApi = (params = {}) => vm.$u.get('/app/My/SelectUserType', params);
|
||||
// 更新切换用户身份UserType
|
||||
let UpdateUserTypeApi = (params = {}) => vm.$u.get('/app/My/UpdateUserType', params);
|
||||
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.apiList(因为vm就是this,也即this.$u.apiList)下
|
||||
vm.$u.apiList = {
|
||||
Captcha,
|
||||
GetInterestLable,
|
||||
GetLableList,
|
||||
SelectUserTypeApi,
|
||||
UpdateUserTypeApi,
|
||||
ForgotPasswordValidate,
|
||||
DeleteJZGApi,
|
||||
SelectJZGApi,
|
||||
GetDateTimeReturnApi,
|
||||
AddReturnSchoolApi,
|
||||
GetUserSchoolApi,
|
||||
UpdateUserFileApi,
|
||||
DelUserFileApi,
|
||||
AddWordInfoApi,
|
||||
GetUserFileApi,
|
||||
DelWorkInfoApi,
|
||||
UpdateProjectInfoApi,
|
||||
DelProjectInfoApi,
|
||||
AddProjectInfoApi,
|
||||
UpdateWorkInfoApi,
|
||||
ResumeUserApi,
|
||||
SaveReturnSchoolVerifyApi,
|
||||
SelectInfoSetApi,
|
||||
SelectInfoSetNoTokenApi,
|
||||
SelectReturnSchoolList_dshApi,
|
||||
SelectReturnSchoolList_typeApi,
|
||||
SelectReturnSchoolInfoApi,
|
||||
SaveReturnSchoolInfoNoTokenApi,
|
||||
SaveReturnSchoolVerifyNoTokenApi,
|
||||
SelectReturnSchoolInfoNotokenApi,
|
||||
DelReturnSchoolInfoApi,
|
||||
SaveReturnSchoolInfoApi,
|
||||
UpdateUser,
|
||||
GetWorkFile,
|
||||
MyPage,
|
||||
MyEducations,
|
||||
AddEducation,
|
||||
SubmitAttestationXY,
|
||||
SelectEducation,
|
||||
Publishs,
|
||||
InsertJournaArticle,
|
||||
InsertHelpArticle,
|
||||
AttestationGLY,
|
||||
SubmitAttestationGLY,
|
||||
AttestationJZG,
|
||||
SubmitAttestationJZG,
|
||||
AttestationQY,
|
||||
SubmitAttestationQY,
|
||||
Setting,
|
||||
GetUser,
|
||||
GetSign,
|
||||
InsertOrDelFollow,
|
||||
InsertComment,
|
||||
GetJournaArticle,
|
||||
GetComment,
|
||||
LikeCollect,
|
||||
LikeHe,
|
||||
ForwardHelpArticle,
|
||||
GetUserSchool,
|
||||
Collection,
|
||||
UserHelp,
|
||||
AuditList,
|
||||
AuditDeatil,
|
||||
ForwardHelpArticle,
|
||||
Audit,
|
||||
GetPhoneValidateCode,
|
||||
AlumnRangeSchool,
|
||||
IsPhoneCode,
|
||||
SubmitFeedback,
|
||||
GetCollegeList,
|
||||
GetMajorList,
|
||||
GetUserApproval,
|
||||
DeleteEducation,
|
||||
DelateArticle,
|
||||
CancleCollect,
|
||||
GetAppValidateCode,
|
||||
ForgotPassword,
|
||||
UpdateUserJZG
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
install
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// 这里的vm,就是我们在vue文件里面的this,所以我们能在这里获取vuex的变量,比如存放在里面的token
|
||||
// 同时,我们也可以在此使用getApp().globalData,如果你把token放在getApp().globalData的话,也是可以使用的
|
||||
const install = (Vue, vm) => {
|
||||
Vue.prototype.$u.http.setConfig({
|
||||
// baseUrl: 'https://xy.apps.service.zheke.com',
|
||||
// imgUrl: 'https://xy.apps.service.zheke.com/',
|
||||
baseUrl: 'http://sl.vrgon.com:8003',
|
||||
imgUrl: 'http://sl.vrgon.com:8003/',
|
||||
// imgUrl:'http://115.238.47.235:8987/',
|
||||
// baseUrl: 'http://115.238.47.235:8993',
|
||||
// 如果将此值设置为true,拦截回调中将会返回服务端返回的所有数据response,而不是response.data
|
||||
// 设置为true后,就需要在this.$u.http.interceptor.response进行多一次的判断,请打印查看具体值
|
||||
// originalData: true,
|
||||
// 设置自定义头部content-type
|
||||
// header: {
|
||||
// 'content-type': 'xxx'
|
||||
// }
|
||||
});
|
||||
// 请求拦截,配置Token等参数
|
||||
Vue.prototype.$u.http.interceptor.request = (config) => {
|
||||
|
||||
// config.header.Token = 'xxxxxx';
|
||||
// 方式一,存放在vuex的token,假设 ,见:https://uviewui.com/components/globalVariable.html
|
||||
config.header.Authorization = 'Bearer ' + vm.vuex_token;
|
||||
// 方式二,如果没有使用uView封装的vuex方法,那么需要使用$store.state获取
|
||||
// config.header.token = vm.$store.state.token;
|
||||
|
||||
// 方式三,如果token放在了globalData,通过getApp().globalData获取
|
||||
// config.header.token = getApp().globalData.username;
|
||||
|
||||
// 方式四,如果token放在了Storage本地存储中,拦截是每次请求都执行的,所以哪怕您重新登录修改了Storage,下一次的请求将会是最新值
|
||||
// const token = uni.getStorageSync('token');
|
||||
// config.header.token = token;
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
// setTimeout(function () {
|
||||
// uni.hideLoading();
|
||||
// }, 2000);
|
||||
|
||||
return config;
|
||||
}
|
||||
// 响应拦截,判断状态码是否通过
|
||||
Vue.prototype.$u.http.interceptor.response = (res) => {
|
||||
uni.hideLoading();
|
||||
if (res.succeed == true || res.success == true) {
|
||||
return res.data || res;
|
||||
} else {
|
||||
// uni.showToast({
|
||||
// title: res.error,
|
||||
// duration: 2000,
|
||||
// icon: 'none'
|
||||
// });
|
||||
// uni.navigateTo({
|
||||
// url: "/pages/login/login/login",
|
||||
// });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
install
|
||||
}
|
||||
|
|
@ -0,0 +1,585 @@
|
|||
module.exports = {
|
||||
list: [{
|
||||
"letter": "A",
|
||||
"data": [{
|
||||
"name": "阿拉斯加",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "阿拉斯加ABA13588889999"
|
||||
},
|
||||
{
|
||||
"name": "阿克苏",
|
||||
"mobile": "0551-4386721",
|
||||
"keyword": "阿克苏AKESU0551-4386721"
|
||||
},
|
||||
{
|
||||
"name": "阿拉善",
|
||||
"mobile": "4008009100",
|
||||
"keyword": "阿拉善ALASHAN4008009100"
|
||||
},
|
||||
{
|
||||
"name": "阿勒泰",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "阿勒泰ALETAI13588889999"
|
||||
},
|
||||
{
|
||||
"name": "阿里",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "阿里ALI13588889999"
|
||||
},
|
||||
{
|
||||
"name": "安阳",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "13588889999安阳ANYANG"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "B",
|
||||
"data": [{
|
||||
"name": "白城",
|
||||
"mobile": "该主子没有留电话~",
|
||||
"keyword": "白城BAICHENG"
|
||||
},
|
||||
{
|
||||
"name": "白山",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "白山BAISHAN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "白银",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "白银BAIYIN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "保定",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "保定BAODING13588889999"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "C",
|
||||
"data": [{
|
||||
"name": "沧州",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "沧州CANGZHOU13588889999"
|
||||
},
|
||||
{
|
||||
"name": "长春",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "长春CHANGCHUN13588889999"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "D",
|
||||
"data": [{
|
||||
"name": "大理",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "大理DALI13588889999"
|
||||
},
|
||||
{
|
||||
"name": "大连",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "大连DALIAN13588889999"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "E",
|
||||
"data": [{
|
||||
"name": "鄂尔多斯",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "鄂尔多斯EERDUOSI13588889999"
|
||||
},
|
||||
{
|
||||
"name": "恩施",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "恩施ENSHI13588889999"
|
||||
},
|
||||
{
|
||||
"name": "鄂州",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "鄂州EZHOU13588889999"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "F",
|
||||
"data": [{
|
||||
"name": "防城港",
|
||||
"mobile": "该主子没有留电话~",
|
||||
"keyword": "防城港FANGCHENGGANG"
|
||||
},
|
||||
{
|
||||
"name": "抚顺",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "抚顺FUSHUN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "阜新",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "阜新FUXIN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "阜阳",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "阜阳FUYANG13588889999"
|
||||
},
|
||||
{
|
||||
"name": "抚州",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "抚州FUZHOU13588889999"
|
||||
},
|
||||
{
|
||||
"name": "福州",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "福州FUZHOU13588889999"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "G",
|
||||
"data": [{
|
||||
"name": "甘南",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "甘南GANNAN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "赣州",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "赣州GANZHOU13588889999"
|
||||
},
|
||||
{
|
||||
"name": "甘孜",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "甘孜GANZI13588889999"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "H",
|
||||
"data": [{
|
||||
"name": "哈尔滨",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "哈尔滨HAERBIN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "海北",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "海北HAIBEI13588889999"
|
||||
},
|
||||
{
|
||||
"name": "海东",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "海东HAIDONG13588889999"
|
||||
},
|
||||
{
|
||||
"name": "海口",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "海口HAIKOU13588889999"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "I",
|
||||
"data": [{
|
||||
"name": "ice",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "佳木斯JIAMUSI13588889999"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"letter": "J",
|
||||
"data": [{
|
||||
"name": "佳木斯",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "佳木斯JIAMUSI13588889999"
|
||||
},
|
||||
{
|
||||
"name": "吉安",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "吉安JIAN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "江门",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "江门JIANGMEN13588889999"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "K",
|
||||
"data": [{
|
||||
"name": "开封",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "开封KAIFENG13588889999"
|
||||
},
|
||||
{
|
||||
"name": "喀什",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "喀什KASHI13588889999"
|
||||
},
|
||||
{
|
||||
"name": "克拉玛依",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "克拉玛依KELAMAYI13588889999"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "L",
|
||||
"data": [{
|
||||
"name": "来宾",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "来宾LAIBIN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "兰州",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "兰州LANZHOU13588889999"
|
||||
},
|
||||
{
|
||||
"name": "拉萨",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "拉萨LASA13588889999"
|
||||
},
|
||||
{
|
||||
"name": "乐山",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "乐山LESHAN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "凉山",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "凉山LIANGSHAN13588889999"
|
||||
},
|
||||
{
|
||||
"name": "连云港",
|
||||
"mobile": "13588889999",
|
||||
"keyword": "连云港LIANYUNGANG13588889999"
|
||||
},
|
||||
{
|
||||
"name": "聊城",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "聊城LIAOCHENG18322223333"
|
||||
},
|
||||
{
|
||||
"name": "辽阳",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "辽阳LIAOYANG18322223333"
|
||||
},
|
||||
{
|
||||
"name": "辽源",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "辽源LIAOYUAN18322223333"
|
||||
},
|
||||
{
|
||||
"name": "丽江",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "丽江LIJIANG18322223333"
|
||||
},
|
||||
{
|
||||
"name": "临沧",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "临沧LINCANG18322223333"
|
||||
},
|
||||
{
|
||||
"name": "临汾",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "临汾LINFEN18322223333"
|
||||
},
|
||||
{
|
||||
"name": "临夏",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "临夏LINXIA18322223333"
|
||||
},
|
||||
{
|
||||
"name": "临沂",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "临沂LINYI18322223333"
|
||||
},
|
||||
{
|
||||
"name": "林芝",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "林芝LINZHI18322223333"
|
||||
},
|
||||
{
|
||||
"name": "丽水",
|
||||
"mobile": "18322223333",
|
||||
"keyword": "丽水LISHUI18322223333"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "M",
|
||||
"data": [{
|
||||
"name": "眉山",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "眉山MEISHAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "梅州",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "梅州MEIZHOU15544448888"
|
||||
},
|
||||
{
|
||||
"name": "绵阳",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "绵阳MIANYANG15544448888"
|
||||
},
|
||||
{
|
||||
"name": "牡丹江",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "牡丹江MUDANJIANG15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "N",
|
||||
"data": [{
|
||||
"name": "南昌",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "南昌NANCHANG15544448888"
|
||||
},
|
||||
{
|
||||
"name": "南充",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "南充NANCHONG15544448888"
|
||||
},
|
||||
{
|
||||
"name": "南京",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "南京NANJING15544448888"
|
||||
},
|
||||
{
|
||||
"name": "南宁",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "南宁NANNING15544448888"
|
||||
},
|
||||
{
|
||||
"name": "南平",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "南平NANPING15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "O",
|
||||
"data": [{
|
||||
"name": "欧阳",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "欧阳ouyang15544448888"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"letter": "P",
|
||||
"data": [{
|
||||
"name": "盘锦",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "盘锦PANJIN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "攀枝花",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "攀枝花PANZHIHUA15544448888"
|
||||
},
|
||||
{
|
||||
"name": "平顶山",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "平顶山PINGDINGSHAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "平凉",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "平凉PINGLIANG15544448888"
|
||||
},
|
||||
{
|
||||
"name": "萍乡",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "萍乡PINGXIANG15544448888"
|
||||
},
|
||||
{
|
||||
"name": "普洱",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "普洱PUER15544448888"
|
||||
},
|
||||
{
|
||||
"name": "莆田",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "莆田PUTIAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "濮阳",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "濮阳PUYANG15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "Q",
|
||||
"data": [{
|
||||
"name": "黔东南",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "黔东南QIANDONGNAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "黔南",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "黔南QIANNAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "黔西南",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "黔西南QIANXINAN15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "R",
|
||||
"data": [{
|
||||
"name": "日喀则",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "日喀则RIKAZE15544448888"
|
||||
},
|
||||
{
|
||||
"name": "日照",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "日照RIZHAO15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "S",
|
||||
"data": [{
|
||||
"name": "三门峡",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "三门峡SANMENXIA15544448888"
|
||||
},
|
||||
{
|
||||
"name": "三明",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "三明SANMING15544448888"
|
||||
},
|
||||
{
|
||||
"name": "三沙",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "三沙SANSHA15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "T",
|
||||
"data": [{
|
||||
"name": "塔城",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "塔城TACHENG15544448888"
|
||||
},
|
||||
{
|
||||
"name": "漯河",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "漯河TAHE15544448888"
|
||||
},
|
||||
{
|
||||
"name": "泰安",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "泰安TAIAN15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "W",
|
||||
"data": [{
|
||||
"name": "潍坊",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "潍坊WEIFANG15544448888"
|
||||
},
|
||||
{
|
||||
"name": "威海",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "威海WEIHAI15544448888"
|
||||
},
|
||||
{
|
||||
"name": "渭南",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "渭南WEINAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "文山",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "文山WENSHAN15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "X",
|
||||
"data": [{
|
||||
"name": "厦门",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "厦门XIAMEN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "西安",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "西安XIAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "湘潭",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "湘潭XIANGTAN15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "Y",
|
||||
"data": [{
|
||||
"name": "雅安",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "雅安YAAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "延安",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "延安YANAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "延边",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "延边YANBIAN15544448888"
|
||||
},
|
||||
{
|
||||
"name": "盐城",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "盐城YANCHENG15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "Z",
|
||||
"data": [{
|
||||
"name": "枣庄",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "枣庄ZAOZHUANG15544448888"
|
||||
},
|
||||
{
|
||||
"name": "张家界",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "张家界ZHANGJIAJIE15544448888"
|
||||
},
|
||||
{
|
||||
"name": "张家口",
|
||||
"mobile": "15544448888",
|
||||
"keyword": "张家口ZHANGJIAKOU15544448888"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "#",
|
||||
"data": [{
|
||||
"name": "其他.",
|
||||
"mobile": "16666666666",
|
||||
"keyword": "echo16666666666"
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
export default {
|
||||
// 可以以页面为单位来写,比如首页的内容,写在index字段,个人中心写在center,共同部分写在common部分
|
||||
components: {
|
||||
desc: 'Numerous components cover the various requirements of the development process, and the components are rich in functions and compatible with multiple terminals. Let you integrate quickly, out of the box'
|
||||
},
|
||||
js: {
|
||||
desc: 'Numerous intimate gadgets are a weapon that you can call upon during the development process, allowing you to dart in your hand and pierce the Yang with a hundred steps'
|
||||
},
|
||||
template: {
|
||||
desc: 'Collection of many commonly used pages and layouts, reducing the repetitive work of developers, allowing you to focus on logic and get twice the result with half the effort'
|
||||
},
|
||||
nav: {
|
||||
components: 'Components',
|
||||
js: 'JS',
|
||||
template: 'Template'
|
||||
},
|
||||
common: {
|
||||
intro: 'UI framework for rapid development of multiple platforms',
|
||||
title: 'uView UI',
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
export default {
|
||||
// 可以以页面为单位来写,比如首页的内容,写在index字段,个人中心写在center,共同部分写在common部分
|
||||
components: {
|
||||
desc: '众多组件覆盖开发过程的各个需求,组件功能丰富,多端兼容。让你快速集成,开箱即用'
|
||||
},
|
||||
js: {
|
||||
desc: '众多的贴心小工具,是你开发过程中召之即来的利器,让你飞镖在手,百步穿杨'
|
||||
},
|
||||
template: {
|
||||
desc: '收集众多的常用页面和布局,减少开发者的重复工作,让你专注逻辑,事半功倍'
|
||||
},
|
||||
nav: {
|
||||
components: '组件',
|
||||
js: '工具',
|
||||
template: '模板'
|
||||
},
|
||||
common: {
|
||||
intro: '多平台快速开发的UI框架',
|
||||
title: 'uView UI',
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
export const Debounce = (fn, wait) => {
|
||||
let delay = wait|| 500
|
||||
let timer
|
||||
return function () {
|
||||
let args = arguments;
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
|
||||
let callNow = !timer
|
||||
timer = setTimeout(() => {
|
||||
timer = null
|
||||
}, delay)
|
||||
if (callNow) fn.apply(this, args)
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,722 @@
|
|||
<template>
|
||||
<!-- 视频、图片 动态卡片 -->
|
||||
<view class="content-card">
|
||||
<!-- 用户信息 -->
|
||||
<view class="user-info">
|
||||
<image
|
||||
class="avatar"
|
||||
:src="cardData.user.avatar"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="user-detail">
|
||||
<text class="username">{{ cardData.user.name }}</text>
|
||||
<text class="user-meta">{{ cardData.user.meta }}</text>
|
||||
</view>
|
||||
<view class="follow-btn" @click="onFollow">
|
||||
<u-icon name="plus" color="#666" size="14"></u-icon>
|
||||
<text>关注</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 内容文本 -->
|
||||
<view class="content-text" @click="goContentDetail">
|
||||
{{ cardData.content }}
|
||||
</view>
|
||||
|
||||
<!-- 媒体内容 - 内部处理交互 -->
|
||||
<view class="media-content">
|
||||
<!-- 视频内容 -->
|
||||
<view v-if="isVideo" class="video-container" @click="handleVideoPlay">
|
||||
<image
|
||||
class="video-cover"
|
||||
:src="cardData.cover"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="video-overlay">
|
||||
<u-icon name="play-right" color="#fff" size="40"></u-icon>
|
||||
<text v-if="cardData.duration" class="video-duration">{{
|
||||
formatDuration(cardData.duration)
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 图片内容 -->
|
||||
<view v-else class="image-grid" :class="getImageLayoutClass()">
|
||||
<image
|
||||
v-for="(img, index) in cardData.images"
|
||||
:key="index"
|
||||
class="grid-image"
|
||||
:src="img"
|
||||
mode="aspectFill"
|
||||
@click="handleImagePreview(index)"
|
||||
></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 互动栏 - 内部处理交互 -->
|
||||
<view class="interaction-bar">
|
||||
<view
|
||||
class="action-item"
|
||||
v-for="(item, index) in actionButtons"
|
||||
:key="index"
|
||||
@click="handleAction(item.action)"
|
||||
>
|
||||
<image
|
||||
:src="item.icon"
|
||||
mode="aspectFill"
|
||||
style="width: 40rpx; height: 40rpx"
|
||||
></image>
|
||||
<text>{{ cardData.stats[item.stat] }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ContentCard",
|
||||
props: {
|
||||
cardData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({
|
||||
user: {
|
||||
avatar: "",
|
||||
name: "",
|
||||
meta: "",
|
||||
},
|
||||
content: "",
|
||||
// 可以是视频或图片
|
||||
type: "image", // 'image' 或 'video'
|
||||
images: [], // 图片数组
|
||||
cover: "", // 视频封面
|
||||
videoUrl: "", // 视频地址
|
||||
duration: 0, // 视频时长(秒)
|
||||
stats: {
|
||||
forward: 0,
|
||||
comment: 0,
|
||||
like: 0,
|
||||
favorite: 0,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 添加内部状态跟踪互动状态
|
||||
isLiked: false,
|
||||
isFavorited: false,
|
||||
isForwarded: false,
|
||||
videoContext: null,
|
||||
// 添加操作按钮配置
|
||||
actionButtons: [
|
||||
{
|
||||
icon: "/static/common/img/homepage/reply.png",
|
||||
action: "forward",
|
||||
stat: "forward"
|
||||
},
|
||||
{
|
||||
icon: "/static/common/img/homepage/comment.png",
|
||||
action: "comment",
|
||||
stat: "comment"
|
||||
},
|
||||
{
|
||||
icon: "/static/common/img/homepage/like.png",
|
||||
action: "like",
|
||||
stat: "like"
|
||||
},
|
||||
{
|
||||
icon: "/static/common/img/homepage/star.png",
|
||||
action: "favorite",
|
||||
stat: "favorite"
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isVideo() {
|
||||
return this.cardData.type === "video";
|
||||
},
|
||||
// 根据状态动态改变图标和颜色
|
||||
likeIcon() {
|
||||
return this.isLiked ? "heart-fill" : "heart";
|
||||
},
|
||||
likeColor() {
|
||||
return this.isLiked ? "#ff5252" : "#999";
|
||||
},
|
||||
favoriteIcon() {
|
||||
return this.isFavorited ? "star-fill" : "star";
|
||||
},
|
||||
favoriteColor() {
|
||||
return this.isFavorited ? "#ffb700" : "#999";
|
||||
},
|
||||
forwardIcon() {
|
||||
return this.isForwarded ? "arrow-right-fill" : "arrow-right";
|
||||
},
|
||||
forwardColor() {
|
||||
return this.isForwarded ? "#2979ff" : "#999";
|
||||
},
|
||||
commentColor() {
|
||||
return "#999"; // 评论按钮颜色无变化
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 处理关注点击
|
||||
onFollow() {
|
||||
this.$emit("follow", this.cardData.user);
|
||||
},
|
||||
|
||||
// 跳转详情页
|
||||
goContentDetail() {
|
||||
console.log("this.cardData", this.cardData);
|
||||
this.$u.route({
|
||||
url: "/pages/home/home/components/contentDetail/index",
|
||||
// params: {
|
||||
// card,
|
||||
// },
|
||||
});
|
||||
},
|
||||
|
||||
// 格式化视频时长
|
||||
formatDuration(seconds) {
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = Math.floor(seconds % 60);
|
||||
return `${minutes.toString().padStart(2, "0")}:${remainingSeconds
|
||||
.toString()
|
||||
.padStart(2, "0")}`;
|
||||
},
|
||||
|
||||
// 处理视频播放
|
||||
handleVideoPlay() {
|
||||
if (this.cardData.videoUrl) {
|
||||
// 记录播放历史
|
||||
this.savePlayHistory();
|
||||
|
||||
// 使用内置视频播放器播放
|
||||
try {
|
||||
// 先尝试使用内部视频播放器
|
||||
if (this.useInternalPlayer) {
|
||||
this.showVideoPlayer = true;
|
||||
this.$nextTick(() => {
|
||||
this.videoContext = uni.createVideoContext("video-player", this);
|
||||
this.videoContext.requestFullScreen();
|
||||
this.videoContext.play();
|
||||
});
|
||||
} else {
|
||||
// 否则跳转到专门的播放页面
|
||||
uni.navigateTo({
|
||||
url: `/pages/video/player?videoUrl=${encodeURIComponent(
|
||||
this.cardData.videoUrl
|
||||
)}&title=${encodeURIComponent(this.cardData.content)}`,
|
||||
});
|
||||
}
|
||||
|
||||
// 触发播放事件,让父组件可以进行额外处理
|
||||
this.$emit("video-play", {
|
||||
videoUrl: this.cardData.videoUrl,
|
||||
title: this.cardData.content,
|
||||
cover: this.cardData.cover,
|
||||
cardId: this.cardData.id,
|
||||
});
|
||||
|
||||
// 更新播放统计
|
||||
this.updateVideoStats();
|
||||
} catch (error) {
|
||||
console.error("视频播放失败:", error);
|
||||
uni.showToast({
|
||||
title: "视频播放失败,请稍后再试",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 处理图片预览
|
||||
handleImagePreview(index) {
|
||||
try {
|
||||
// 使用uni-app的图片预览API
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: this.cardData.images,
|
||||
longPressActions: {
|
||||
itemList: ["保存图片", "分享图片"],
|
||||
success: (res) => {
|
||||
const { tapIndex } = res;
|
||||
if (tapIndex === 0) {
|
||||
// 保存图片
|
||||
this.saveImage(this.cardData.images[index]);
|
||||
} else if (tapIndex === 1) {
|
||||
// 分享图片
|
||||
this.shareImage(this.cardData.images[index]);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 触发图片预览事件
|
||||
this.$emit("image-preview", {
|
||||
index,
|
||||
images: this.cardData.images,
|
||||
cardId: this.cardData.id,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("图片预览失败:", error);
|
||||
}
|
||||
},
|
||||
|
||||
// 保存图片
|
||||
saveImage(url) {
|
||||
uni.showLoading({ title: "正在保存..." });
|
||||
uni.downloadFile({
|
||||
url,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
uni.showToast({ title: "保存成功" });
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error("保存失败:", err);
|
||||
uni.showToast({ title: "保存失败", icon: "none" });
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: "下载图片失败", icon: "none" });
|
||||
},
|
||||
complete: () => {
|
||||
uni.hideLoading();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 分享图片
|
||||
shareImage(url) {
|
||||
// 根据平台实现不同的分享逻辑
|
||||
// #ifdef APP-PLUS
|
||||
plus.share.sendWithSystem({
|
||||
type: "image",
|
||||
pictures: [url],
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
// H5环境可能需要调用其他API
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
// 小程序环境使用小程序分享API
|
||||
uni.showToast({ title: "请使用右上角分享", icon: "none" });
|
||||
// #endif
|
||||
},
|
||||
|
||||
// 根据图片数量确定布局样式
|
||||
getImageLayoutClass() {
|
||||
const count = this.cardData.images.length;
|
||||
if (count === 1) return "single-image";
|
||||
if (count === 2) return "double-image";
|
||||
if (count === 3) return "triple-image";
|
||||
if (count === 4) return "four-image";
|
||||
if (count > 4) return "multi-image";
|
||||
return "";
|
||||
},
|
||||
|
||||
// 处理转发
|
||||
handleForward() {
|
||||
this.isForwarded = !this.isForwarded;
|
||||
|
||||
// 显示分享菜单
|
||||
uni.showShareMenu({
|
||||
withShareTicket: true,
|
||||
menus: ["shareAppMessage", "shareTimeline"],
|
||||
});
|
||||
|
||||
// 触发转发事件
|
||||
this.$emit("forward", {
|
||||
cardData: this.cardData,
|
||||
isForwarded: this.isForwarded,
|
||||
});
|
||||
|
||||
// 如果在APP中,可以调用原生分享
|
||||
// #ifdef APP-PLUS
|
||||
uni.share({
|
||||
provider: "weixin",
|
||||
scene: "WXSceneSession",
|
||||
type: 0,
|
||||
title: this.cardData.content,
|
||||
summary: this.cardData.content,
|
||||
imageUrl: this.isVideo ? this.cardData.cover : this.cardData.images[0],
|
||||
success: function (res) {
|
||||
console.log("分享成功:" + JSON.stringify(res));
|
||||
},
|
||||
fail: function (err) {
|
||||
console.log("分享失败:" + JSON.stringify(err));
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
|
||||
// 处理评论
|
||||
handleComment() {
|
||||
// 跳转到评论页面或打开评论弹窗
|
||||
this.$emit("comment", {
|
||||
cardData: this.cardData,
|
||||
});
|
||||
|
||||
// 这里可以实现自定义的评论交互
|
||||
uni.navigateTo({
|
||||
url: `/pages/comment/index?id=${this.cardData.id}&type=${this.cardData.type}`,
|
||||
});
|
||||
},
|
||||
|
||||
// 处理点赞
|
||||
handleLike() {
|
||||
// 切换点赞状态
|
||||
this.isLiked = !this.isLiked;
|
||||
|
||||
// 更新点赞数据
|
||||
const newStats = { ...this.cardData.stats };
|
||||
if (this.isLiked) {
|
||||
newStats.like += 1;
|
||||
} else {
|
||||
newStats.like = Math.max(0, newStats.like - 1);
|
||||
}
|
||||
|
||||
// 更新数据并触发事件
|
||||
this.$emit("like", {
|
||||
cardData: this.cardData,
|
||||
isLiked: this.isLiked,
|
||||
newStats,
|
||||
});
|
||||
|
||||
// 发送点赞请求到服务器
|
||||
this.updateLikeStatus();
|
||||
},
|
||||
|
||||
// 处理收藏
|
||||
handleFavorite() {
|
||||
// 切换收藏状态
|
||||
this.isFavorited = !this.isFavorited;
|
||||
|
||||
// 更新收藏数据
|
||||
const newStats = { ...this.cardData.stats };
|
||||
if (this.isFavorited) {
|
||||
newStats.favorite += 1;
|
||||
} else {
|
||||
newStats.favorite = Math.max(0, newStats.favorite - 1);
|
||||
}
|
||||
|
||||
// 更新数据并触发事件
|
||||
this.$emit("favorite", {
|
||||
cardData: this.cardData,
|
||||
isFavorited: this.isFavorited,
|
||||
newStats,
|
||||
});
|
||||
|
||||
// 发送收藏请求到服务器
|
||||
this.updateFavoriteStatus();
|
||||
},
|
||||
|
||||
// 更新点赞状态到服务器
|
||||
updateLikeStatus() {
|
||||
// 调用API更新点赞状态
|
||||
// 示例代码,根据实际API调整
|
||||
const url = this.isLiked ? "/api/like/add" : "/api/like/cancel";
|
||||
uni.request({
|
||||
url,
|
||||
method: "POST",
|
||||
data: {
|
||||
contentId: this.cardData.id,
|
||||
contentType: this.cardData.type,
|
||||
},
|
||||
success: (res) => {
|
||||
console.log("点赞状态更新成功", res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error("点赞状态更新失败", err);
|
||||
// 恢复原状态
|
||||
this.isLiked = !this.isLiked;
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 更新收藏状态到服务器
|
||||
updateFavoriteStatus() {
|
||||
// 调用API更新收藏状态
|
||||
// 示例代码,根据实际API调整
|
||||
const url = this.isFavorited
|
||||
? "/api/favorite/add"
|
||||
: "/api/favorite/cancel";
|
||||
uni.request({
|
||||
url,
|
||||
method: "POST",
|
||||
data: {
|
||||
contentId: this.cardData.id,
|
||||
contentType: this.cardData.type,
|
||||
},
|
||||
success: (res) => {
|
||||
console.log("收藏状态更新成功", res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error("收藏状态更新失败", err);
|
||||
// 恢复原状态
|
||||
this.isFavorited = !this.isFavorited;
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 记录视频播放历史
|
||||
savePlayHistory() {
|
||||
// 保存播放历史到本地存储或服务器
|
||||
try {
|
||||
const historyList = uni.getStorageSync("videoPlayHistory") || [];
|
||||
const now = new Date().getTime();
|
||||
|
||||
// 查找是否已有该视频记录
|
||||
const index = historyList.findIndex(
|
||||
(item) => item.id === this.cardData.id
|
||||
);
|
||||
|
||||
if (index > -1) {
|
||||
// 更新已有记录
|
||||
historyList[index].lastPlayTime = now;
|
||||
historyList[index].playCount += 1;
|
||||
} else {
|
||||
// 添加新记录
|
||||
historyList.push({
|
||||
id: this.cardData.id,
|
||||
title: this.cardData.content,
|
||||
cover: this.cardData.cover,
|
||||
lastPlayTime: now,
|
||||
playCount: 1,
|
||||
});
|
||||
}
|
||||
|
||||
// 保存回本地存储
|
||||
uni.setStorageSync("videoPlayHistory", historyList);
|
||||
} catch (e) {
|
||||
console.error("保存播放历史失败", e);
|
||||
}
|
||||
},
|
||||
|
||||
// 更新视频播放统计
|
||||
updateVideoStats() {
|
||||
// 调用API更新视频播放次数
|
||||
uni.request({
|
||||
url: "/api/video/view",
|
||||
method: "POST",
|
||||
data: {
|
||||
videoId: this.cardData.id,
|
||||
},
|
||||
success: (res) => {
|
||||
console.log("视频播放统计更新成功", res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error("视频播放统计更新失败", err);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 添加统一的操作处理方法
|
||||
handleAction(action) {
|
||||
switch(action) {
|
||||
case "forward":
|
||||
this.handleForward();
|
||||
break;
|
||||
case "comment":
|
||||
this.handleComment();
|
||||
break;
|
||||
case "like":
|
||||
this.handleLike();
|
||||
break;
|
||||
case "favorite":
|
||||
this.handleFavorite();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content-card {
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.user-detail {
|
||||
flex: 1;
|
||||
|
||||
.username {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
display: block;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.user-meta {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
display: block;
|
||||
line-height: 1.2;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.follow-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 30rpx;
|
||||
padding: 8rpx 16rpx;
|
||||
|
||||
text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.media-content {
|
||||
margin-bottom: 24rpx;
|
||||
width: 100%;
|
||||
|
||||
// 视频容器样式
|
||||
.video-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.video-cover {
|
||||
width: 100%;
|
||||
height: 400rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.video-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
|
||||
.video-duration {
|
||||
position: absolute;
|
||||
right: 16rpx;
|
||||
bottom: 16rpx;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
padding: 4rpx 8rpx;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 图片网格样式
|
||||
.image-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.grid-image {
|
||||
border-radius: 8rpx;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
&.single-image {
|
||||
.grid-image {
|
||||
width: 100%;
|
||||
max-height: 400rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.double-image {
|
||||
justify-content: space-between;
|
||||
|
||||
.grid-image {
|
||||
width: 49%;
|
||||
height: 240rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.triple-image {
|
||||
justify-content: space-between;
|
||||
|
||||
.grid-image {
|
||||
width: 31%;
|
||||
height: 180rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.four-image {
|
||||
justify-content: space-between;
|
||||
|
||||
.grid-image {
|
||||
width: 49%;
|
||||
height: 180rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.multi-image {
|
||||
justify-content: space-between;
|
||||
|
||||
.grid-image {
|
||||
width: 31%;
|
||||
height: 180rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.interaction-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 16rpx;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,698 @@
|
|||
<template>
|
||||
<view>
|
||||
<view
|
||||
class="flex-col Information"
|
||||
style="position: relative; height: 100%"
|
||||
@tap="btnShow = false"
|
||||
>
|
||||
<view class="flex-col">
|
||||
<template v-if="list.length <= 0">
|
||||
<view
|
||||
v-if="type != 2 && type != 3 && !noShowEmpty"
|
||||
style="height: 1rem"
|
||||
></view>
|
||||
<!-- <u-empty v-if="type != 2 && type != 3" text="暂无数据" mode="list"></u-empty> -->
|
||||
<no-data v-if="type != 2 && type != 3" text="暂无数据"></no-data>
|
||||
</template>
|
||||
<template v-else v-for="(item, index) in list">
|
||||
<view
|
||||
class="flex-col list-item"
|
||||
:class="{
|
||||
'border-radius': borderRadius,
|
||||
'border-noPadding': borderNoPadding,
|
||||
}"
|
||||
:key="index"
|
||||
>
|
||||
<view style="height: 0.1rem" v-if="item.isState"></view>
|
||||
<text class="shield" v-if="item.isState">
|
||||
<u-icon size="30" name="error-circle-fill"></u-icon
|
||||
>该信息已被管理员屏蔽
|
||||
</text>
|
||||
<view class="flex-row group_8 view">
|
||||
<u-avatar
|
||||
@click="toDetil(item.userId)"
|
||||
size="0.3rem"
|
||||
:src="$u.http.config.imgUrl + item.userHead"
|
||||
class="image_3"
|
||||
></u-avatar>
|
||||
<text class="text_8 text_43">{{ item.userName }}</text>
|
||||
<text class="text_9">{{ item.creationTime }}</text>
|
||||
<text class="text_11">{{ item.schoolName }}</text>
|
||||
<u-icon
|
||||
v-if="isDel"
|
||||
name="more-dot-fill"
|
||||
color="#ccc"
|
||||
size="40"
|
||||
style="position: absolute; right: 0"
|
||||
@click="showDelFn(item)"
|
||||
></u-icon>
|
||||
</view>
|
||||
<view class="flex-col group_9" @click="onDetails(item)">
|
||||
<text class="text_14" v-if="type != 2">{{
|
||||
item.title.length > 15
|
||||
? item.title.slice(0, 15) + "..."
|
||||
: item.title
|
||||
}}</text>
|
||||
<text class="text_14" v-else>{{ item.title }}</text>
|
||||
<template v-if="!item.isForward">
|
||||
<view v-if="!item.isDelete">
|
||||
<text class="text_15" v-if="type != 2">
|
||||
{{
|
||||
item.content.length > 50
|
||||
? item.content.slice(0, 50) + "..."
|
||||
: item.content
|
||||
}}
|
||||
</text>
|
||||
<text class="text_15" v-else>
|
||||
{{ item.content }}
|
||||
</text>
|
||||
<view
|
||||
class="imgList flex-col"
|
||||
v-if="item.imageUrl.indexOf('.') > 0"
|
||||
>
|
||||
<view class="flex-row">
|
||||
<image
|
||||
@click.stop="clickImg(v)"
|
||||
v-for="(v, i) in item.imageUrl.split(',')"
|
||||
:key="i"
|
||||
:src="v ? $u.http.config.imgUrl + v : ''"
|
||||
class="image_10"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-row" v-if="item.sysSignStr">
|
||||
<text
|
||||
class="text_16"
|
||||
v-for="(v, i) in item.sysSignStr.split(',')"
|
||||
@click.stop="onSign(v)"
|
||||
:key="i"
|
||||
>{{ v ? "#" + v : "" }}</text
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-else
|
||||
class="flex-row justify-between items-center delete-item"
|
||||
>
|
||||
<text class="item-text">哎呀,此页面已被发布者删除。</text>
|
||||
<u-icon
|
||||
class="icon-1"
|
||||
name="trash"
|
||||
color="black"
|
||||
size="50"
|
||||
@click="onDelCollet(item)"
|
||||
></u-icon>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view
|
||||
style="
|
||||
background: #f8f8f8;
|
||||
padding: 0.1rem;
|
||||
margin-top: 0.1rem;
|
||||
"
|
||||
class="flex-col group_9"
|
||||
>
|
||||
<text class="text_14" v-if="type != 2">{{
|
||||
item.forwardModel.forwardTitle.length > 15
|
||||
? item.forwardModel.forwardTitle.slice(0, 15) + "..."
|
||||
: item.forwardModel.forwardTitle
|
||||
}}</text>
|
||||
<text class="text_14" v-else>{{
|
||||
item.forwardModel.forwardTitle
|
||||
}}</text>
|
||||
<text class="text_15" v-if="type != 2">
|
||||
{{
|
||||
item.content.length > 50
|
||||
? item.content.slice(0, 50) + "..."
|
||||
: item.content
|
||||
}}
|
||||
</text>
|
||||
<text class="text_15" v-else>
|
||||
{{ item.content }}
|
||||
</text>
|
||||
<view
|
||||
class="imgList flex-col"
|
||||
v-if="item.forwardModel.forwardImageUrl.indexOf('.') > 0"
|
||||
>
|
||||
<view class="flex-row">
|
||||
<image
|
||||
style="width: 32%; height: 0auto"
|
||||
@click.stop="clickImg(v)"
|
||||
v-for="(
|
||||
v, i
|
||||
) in item.forwardModel.forwardImageUrl.split(',')"
|
||||
v-if="i < 9"
|
||||
:key="i"
|
||||
:src="v ? $u.http.config.imgUrl + v : ''"
|
||||
class="image_10"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-row" v-if="item.sysSignStr">
|
||||
<text
|
||||
@click.stop="onSign(v)"
|
||||
class="text_16"
|
||||
v-for="(v, i) in item.sysSignStr.split(',')"
|
||||
:key="i"
|
||||
>{{ v ? "#" + v : "" }}</text
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<view class="flex-row">
|
||||
<view class="flex-row group_21" v-if="type != 2 && type != 3">
|
||||
<view
|
||||
class="flex-row equal-division-item_1"
|
||||
@click="onForward(item)"
|
||||
v-if="!item.isForward && type != 0"
|
||||
>
|
||||
<image
|
||||
src="/static/common/img/homepage/reply.png"
|
||||
class="image_8"
|
||||
/>
|
||||
<text class="text_19">{{ item.forwardCount }}</text>
|
||||
</view>
|
||||
<view class="flex-row group_10" @click="onDetails(item)">
|
||||
<image
|
||||
src="/static/common/img/homepage/comment.png"
|
||||
class="image_7"
|
||||
/>
|
||||
<text class="text_18">{{ item.commentCount }}</text>
|
||||
</view>
|
||||
|
||||
<view class="flex-row group_20">
|
||||
<!-- <u-icon style="font-size:0.22rem;color:#b4b6bd" v-if="item.isCllect == false"
|
||||
name="star" @click="onStar(item)"></u-icon> -->
|
||||
<image
|
||||
style="width: 42rpx; height: 42rpx"
|
||||
src="/static/common/img/homepage/star.png"
|
||||
v-if="item.isCllect == false"
|
||||
name="star"
|
||||
@click="onStar(item)"
|
||||
></image>
|
||||
<u-icon
|
||||
style="font-size: 40rpx; color: #ffc300"
|
||||
v-else
|
||||
name="star-fill"
|
||||
@click="onStar(item)"
|
||||
></u-icon>
|
||||
<text class="text_17">{{ item.collectCount }}</text>
|
||||
</view>
|
||||
<!--
|
||||
<view
|
||||
class="flex-row group_20"
|
||||
v-if="isDel"
|
||||
@tap="onDelete(item)"
|
||||
>
|
||||
<image
|
||||
src="/static/common/img/homepage/trash.png"
|
||||
style="width: 42rpx; height: 42rpx"
|
||||
/>
|
||||
</view>
|
||||
-->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<template v-if="bottom && list.length > 0">
|
||||
<view style="height: 0.46rem"></view>
|
||||
<u-divider
|
||||
style="bottom: 0.2rem; position: absolute; background: transparent"
|
||||
color="#6d6d6d"
|
||||
half-width="200"
|
||||
border-color="#6d6d6d"
|
||||
>
|
||||
{{ text ? text : "已经到底了" }}
|
||||
</u-divider>
|
||||
</template>
|
||||
<u-popup v-model="showDel" mode="bottom" :border-radius="40">
|
||||
<view class="popup-box">
|
||||
<view class="popup-btn" @click="delItem">删除</view>
|
||||
<view class="popup-line"></view>
|
||||
<view class="popup-btn" @click="showDel = false">取消</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<u-toast ref="uToast" />
|
||||
<u-top-tips ref="uTips" :navbar-height="0"></u-top-tips>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NoData from "components/NoData.vue";
|
||||
export default {
|
||||
name: "information",
|
||||
components: {
|
||||
NoData,
|
||||
},
|
||||
// list(array) 数据集 type(number)数据类型 bottom 是否显示 nolink控制是否进行转挑
|
||||
props: [
|
||||
"list",
|
||||
"type",
|
||||
"bottom",
|
||||
"text",
|
||||
"schoolId",
|
||||
"nolink",
|
||||
"route",
|
||||
"flag",
|
||||
"id",
|
||||
"isEllipsis",
|
||||
"isDel",
|
||||
"borderRadius",
|
||||
"borderNoPadding",
|
||||
"noShowEmpty",
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
isindex: -1,
|
||||
btnShow: false,
|
||||
state: false,
|
||||
currentRow: {},
|
||||
showDel: false,
|
||||
delRow: {},
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
onLoad() {
|
||||
this.state = true;
|
||||
},
|
||||
methods: {
|
||||
showDelFn(item) {
|
||||
this.delRow = item;
|
||||
this.showDel = true;
|
||||
},
|
||||
delItem() {
|
||||
this.showDel = false;
|
||||
this.$emit("onDelete", {
|
||||
type: this.delRow.type,
|
||||
id: this.delRow.id,
|
||||
});
|
||||
},
|
||||
//详情
|
||||
onDetails(item) {
|
||||
console.log(JSON.parse(JSON.stringify(item)), "item-JSON-");
|
||||
this.currentRow = item;
|
||||
uni.$off("echoList");
|
||||
uni.$on("echoList", (result) => {
|
||||
// console.log('echoList----')
|
||||
// 收藏
|
||||
if (result.type === "star") {
|
||||
console.log("%c%s", "color:red", "收藏回显");
|
||||
console.log(result, "result");
|
||||
this.currentRow.isCllect = result.data.isCllect;
|
||||
console.log(result.isCllect, "result.isCllect");
|
||||
if (result.data.isCllect === true) {
|
||||
this.currentRow.collectCount++;
|
||||
}
|
||||
if (result.data.isCllect === false) {
|
||||
this.currentRow.collectCount && this.currentRow.collectCount--;
|
||||
}
|
||||
}
|
||||
// 评价
|
||||
if (result.type === "evaluate") {
|
||||
console.log("%c%s", "color:red", "评价回显");
|
||||
console.log(result, "result");
|
||||
this.currentRow.commentCount = result.data.commentCount;
|
||||
}
|
||||
});
|
||||
// return
|
||||
if (this.nolink) {
|
||||
return;
|
||||
}
|
||||
if (item.isDelete) {
|
||||
return;
|
||||
}
|
||||
item.flag = this.flag;
|
||||
item.route = this.route;
|
||||
item.mytype = this.type;
|
||||
item.myschoolId = this.id;
|
||||
if (this.type == 3) {
|
||||
item.mytype = item.type;
|
||||
}
|
||||
// return
|
||||
this.$u.route({
|
||||
url: "pages/AlumniCircle/ArticleDetails/ArticleDetails",
|
||||
params: {
|
||||
data: JSON.stringify(item),
|
||||
isDel:this.isDel
|
||||
},
|
||||
});
|
||||
},
|
||||
toDetil(id) {
|
||||
this.$u.route({
|
||||
url: "/pages/AlumniCircle/userDetail/userDetail?id=" + id + "&type=4",
|
||||
});
|
||||
},
|
||||
//收藏
|
||||
onStar(item) {
|
||||
item.type = this.type;
|
||||
this.$emit("onStar", item);
|
||||
},
|
||||
//转发
|
||||
async onForward(item) {
|
||||
console.log(JSON.parse(JSON.stringify(item)), "item-JSON-");
|
||||
// return
|
||||
this.currentRow = item;
|
||||
uni.$off("echoList");
|
||||
uni.$on("echoList", (result) => {
|
||||
console.log("%c%s", "color:red", "echoList----");
|
||||
// 转发
|
||||
if (result.type === "forward") {
|
||||
console.log("%c%s", "color:red", "转发回显");
|
||||
console.log(result, "result");
|
||||
this.currentRow.forwardCount++;
|
||||
}
|
||||
});
|
||||
// 判断当前学校是否认证,未认证不可转发
|
||||
const req = {
|
||||
userId: this.vuex_user.id,
|
||||
};
|
||||
const res = await this.$u.apiList.MyPage(req);
|
||||
console.log(JSON.parse(JSON.stringify(res)), "res");
|
||||
const edcationList = res.edcationList;
|
||||
if (!edcationList.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "认证后可进行转发操作",
|
||||
type: "none",
|
||||
});
|
||||
}
|
||||
const findRow = edcationList.find((x) => x.isSelected === true);
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "认证后可进行转发操作",
|
||||
type: "none",
|
||||
});
|
||||
}
|
||||
if (this.schoolId) {
|
||||
item.schoolId = this.schoolId;
|
||||
}
|
||||
item.route = this.route;
|
||||
if (item.isForward) return;
|
||||
this.$u.route({
|
||||
url: "pages/AlumniCircle/forward/forward",
|
||||
params: {
|
||||
data: JSON.stringify(item),
|
||||
},
|
||||
});
|
||||
},
|
||||
//图片预览
|
||||
clickImg(item) {
|
||||
if (this.route == 3 || this.nolink) {
|
||||
item = this.$u.http.config.imgUrl + item;
|
||||
var images = [];
|
||||
images.push(item);
|
||||
uni.previewImage({
|
||||
// 图片路径必须是一个数组 => ['']
|
||||
current: 0,
|
||||
urls: images,
|
||||
});
|
||||
}
|
||||
this.$emit("clickImg", item);
|
||||
},
|
||||
onSign(v) {
|
||||
this.$emit("onSign", v);
|
||||
},
|
||||
//删除
|
||||
onDelete(item) {
|
||||
this.$emit("onDelete", {
|
||||
type: item.type,
|
||||
id: item.id,
|
||||
});
|
||||
},
|
||||
//删除收藏
|
||||
onDelCollet(item) {
|
||||
this.$emit("onDelCollet", item.collectId);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.btns {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 0.05rem #ccc;
|
||||
border-radius: 0.05rem;
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
white-space: nowrap;
|
||||
|
||||
.item {
|
||||
line-height: 2;
|
||||
padding: 0 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-divider-text {
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.Information {
|
||||
background-color: rgb(246, 247, 250);
|
||||
// margin-top: 0.1rem;
|
||||
|
||||
.list-item {
|
||||
padding: 0.18rem 0.2rem;
|
||||
background-color: rgb(255, 255, 255);
|
||||
margin-bottom: 0.1rem;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
// width: calc(100% - 50rpx);
|
||||
// margin: 0.1rem auto 0;
|
||||
// border-radius: 24rpx 24rpx 24rpx 24rpx;
|
||||
// border: 2rpx solid #F7F6F9;
|
||||
overflow: hidden;
|
||||
|
||||
.shield {
|
||||
position: absolute;
|
||||
top: 0.05rem;
|
||||
width: 100%;
|
||||
color: #ff9b00;
|
||||
left: 0.1rem;
|
||||
}
|
||||
|
||||
.view {
|
||||
margin-right: 0.051rem;
|
||||
}
|
||||
|
||||
.group_9 {
|
||||
// margin-right: 0.13rem;
|
||||
margin-top: 0.1rem;
|
||||
width: 100%;
|
||||
|
||||
.text_14 {
|
||||
align-self: flex-start;
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.16rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 2;
|
||||
width: 100%;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.text_15 {
|
||||
// margin-top: 0.11rem;
|
||||
color: rgb(73, 76, 87);
|
||||
font-size: 0.14rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.24rem;
|
||||
text-indent: 0.2rem;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.text_16 {
|
||||
margin-left: 0.04rem;
|
||||
margin-top: 0.12rem;
|
||||
align-self: flex-start;
|
||||
// color: rgb(44, 109, 255);
|
||||
color: #298bc3;
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
}
|
||||
|
||||
.group_21 {
|
||||
margin-top: 0.1rem;
|
||||
justify-content: space-between;
|
||||
width: 90%;
|
||||
margin: 0.1rem auto 0;
|
||||
|
||||
.group_20 {
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
// margin: 0.025rem 0;
|
||||
|
||||
.image_6 {
|
||||
flex-shrink: 0;
|
||||
width: 42rpx;
|
||||
height: 42rpx;
|
||||
}
|
||||
|
||||
.text_17 {
|
||||
margin-left: 5rpx;
|
||||
margin-top: 8rpx;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.11rem;
|
||||
}
|
||||
}
|
||||
|
||||
.group_10 {
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
align-self: center;
|
||||
|
||||
.image_7 {
|
||||
flex-shrink: 0;
|
||||
width: 42rpx;
|
||||
height: 42rpx;
|
||||
}
|
||||
|
||||
.text_18 {
|
||||
margin-left: 5rpx;
|
||||
margin-top: 8rpx;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.11rem;
|
||||
}
|
||||
}
|
||||
|
||||
.equal-division-item_1 {
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-self: center;
|
||||
|
||||
.image_8 {
|
||||
width: 42rpx;
|
||||
height: 42rpx;
|
||||
}
|
||||
|
||||
.text_19 {
|
||||
margin-left: 5rpx;
|
||||
margin-top: 8rpx;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.11rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.border-radius {
|
||||
border-radius: 24rpx;
|
||||
width: calc(100% - 48rpx);
|
||||
margin: 0.1rem auto 0;
|
||||
}
|
||||
|
||||
.border-noPadding {
|
||||
border-radius: 24rpx;
|
||||
margin: 0.1rem auto 0;
|
||||
}
|
||||
|
||||
.list-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.imgList {
|
||||
padding-top: 0.1rem;
|
||||
|
||||
.flex-row {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 33%;
|
||||
height: 1rem;
|
||||
margin: 0 0.5% 0.5% 0;
|
||||
}
|
||||
|
||||
image:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.delete-item {
|
||||
box-sizing: border-box;
|
||||
|
||||
.item-text {
|
||||
padding-top: 0.05rem;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.icon-1 {
|
||||
}
|
||||
}
|
||||
|
||||
.group_8 {
|
||||
height: 0.32rem;
|
||||
position: relative;
|
||||
|
||||
.image_3 {
|
||||
width: 0.3rem !important;
|
||||
height: 0.3rem !important;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.text_8 {
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
|
||||
.text_43 {
|
||||
position: absolute;
|
||||
left: 0.37rem;
|
||||
top: 0.02rem;
|
||||
}
|
||||
|
||||
.text_9 {
|
||||
color: rgb(184, 184, 184);
|
||||
font-size: 0.12rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.12rem;
|
||||
position: absolute;
|
||||
left: 0.37rem;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.text_11 {
|
||||
color: rgb(184, 184, 184);
|
||||
font-size: 0.12rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.12rem;
|
||||
position: absolute;
|
||||
left: 0.97rem;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.text_20 {
|
||||
position: absolute;
|
||||
left: 0.36rem;
|
||||
top: 0.02rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.popup-box {
|
||||
padding: 10rpx 0;
|
||||
.popup-btn {
|
||||
font-size: 34rpx;
|
||||
text-align: center;
|
||||
padding: 30rpx;
|
||||
}
|
||||
.popup-line {
|
||||
height: 20rpx;
|
||||
background: #f7f7f8;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
<template>
|
||||
<view class="empty-container">
|
||||
<image :src="getImage" class="empty-image" mode="widthFix"></image>
|
||||
<text class="empty-text">{{ text }}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 暂无数据
|
||||
import noDataDefault from "@/static/common/img/noData/no-data.png";
|
||||
// 暂无搜索
|
||||
import noDataSearch from "@/static/common/img/noData/no-search.png";
|
||||
// 暂无消息
|
||||
import noDataMessage from "@/static/common/img/noData/no-message.png";
|
||||
// 网络异常
|
||||
import errorNet from "@/static/common/img/noData/error-net.png";
|
||||
// 数据加载失败
|
||||
import errorData from "@/static/common/img/noData/error-data.png";
|
||||
// 维护中
|
||||
import maintenance from "@/static/common/img/noData/maintenance.png";
|
||||
// 暂无附件简历
|
||||
import noAttachmentResume from "@/static/common/img/noData/no-attachment-resume.png";
|
||||
// 暂无收藏
|
||||
import noCollection from "@/static/common/img/noData/no-collection.png";
|
||||
// 暂无评论
|
||||
import noComments from "@/static/common/img/noData/no-comments.png";
|
||||
// 暂无内容
|
||||
import noContent from "@/static/common/img/noData/no-content.png";
|
||||
// 暂无文件
|
||||
import noFile from "@/static/common/img/noData/no-file.png";
|
||||
// 暂无好友
|
||||
import noFriends from "@/static/common/img/noData/no-friends.png";
|
||||
// 暂无网络
|
||||
import noInternet from "@/static/common/img/noData/no-internet.png";
|
||||
// 暂无权限
|
||||
import noPermissions from "@/static/common/img/noData/no-permissions.png";
|
||||
// 暂无图片
|
||||
import noPicture from "@/static/common/img/noData/no-picture.png";
|
||||
|
||||
export default {
|
||||
name: "NoData",
|
||||
props: {
|
||||
// 图片类型
|
||||
type: {
|
||||
type: String,
|
||||
default: "default",
|
||||
},
|
||||
// 描述文字,默认值为"暂无数据"
|
||||
text: {
|
||||
type: String,
|
||||
default: "暂无数据",
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
getImage() {
|
||||
const imageMap = {
|
||||
default: noDataDefault,
|
||||
search: noDataSearch,
|
||||
message: noDataMessage,
|
||||
errorNet: errorNet,
|
||||
errorData: errorData,
|
||||
maintenance: maintenance,
|
||||
resume: noAttachmentResume,
|
||||
collection: noCollection,
|
||||
comments: noComments,
|
||||
content: noContent,
|
||||
file: noFile,
|
||||
friends: noFriends,
|
||||
internet: noInternet,
|
||||
permissions: noPermissions,
|
||||
picture: noPicture,
|
||||
};
|
||||
return imageMap[this.type] || imageMap.default;
|
||||
},
|
||||
},
|
||||
data: {
|
||||
/*
|
||||
<no-data type="default" text="暂无数据" />
|
||||
<no-data type="errorNet" text="网络错误" />
|
||||
<no-data type="search" text="暂无搜索内容" />
|
||||
<no-data type="errorData" text="数据加载失败" />
|
||||
<no-data type="message" text="暂无消息" />
|
||||
<no-data type="maintenance" text="系统维护中" />
|
||||
<no-data type="resume" text="暂无简历附件" />
|
||||
<no-data type="collection" text="暂无收藏" />
|
||||
<no-data type="comments" text="暂无评论" />
|
||||
<no-data type="content" text="暂无内容" />
|
||||
<no-data type="file" text="暂无文件" />
|
||||
<no-data type="friends" text="暂无好友" />
|
||||
<no-data type="internet" text="无网络连接" />
|
||||
<no-data type="permissions" text="暂无权限" />
|
||||
<no-data type="picture" text="暂无图片" /> */
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.empty-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-image {
|
||||
width: 400rpx;
|
||||
height: 400rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
<template>
|
||||
<view class="empty-container">
|
||||
<image :src="getImage" class="empty-image" mode="widthFix"></image>
|
||||
<!-- <text class="empty-text">{{ text }}</text> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 暂无数据
|
||||
import noDataDefault from "@/static/common/img/noDataNew/no-data.png";
|
||||
// 暂无搜索
|
||||
import noDataSearch from "@/static/common/img/noDataNew/no-search.png";
|
||||
// 暂无消息
|
||||
import noDataMessage from "@/static/common/img/noDataNew/no-message.png";
|
||||
// 网络异常
|
||||
import errorNet from "@/static/common/img/noDataNew/error-net.png";
|
||||
// 数据加载失败
|
||||
import errorData from "@/static/common/img/noDataNew/error-data.png";
|
||||
// 维护中
|
||||
import maintenance from "@/static/common/img/noDataNew/maintenance.png";
|
||||
// 暂无附件简历
|
||||
import noAttachmentResume from "@/static/common/img/noDataNew/no-attachment-resume.png";
|
||||
// 暂无收藏
|
||||
import noCollection from "@/static/common/img/noDataNew/no-collection.png";
|
||||
// 暂无评论
|
||||
import noComments from "@/static/common/img/noDataNew/no-comments.png";
|
||||
// 暂无内容
|
||||
import noContent from "@/static/common/img/noDataNew/no-content.png";
|
||||
// 暂无文件
|
||||
import noFile from "@/static/common/img/noDataNew/no-file.png";
|
||||
// 暂无好友
|
||||
import noFriends from "@/static/common/img/noDataNew/no-friends.png";
|
||||
// 暂无网络
|
||||
import noInternet from "@/static/common/img/noDataNew/no-internet.png";
|
||||
// 暂无权限
|
||||
import noPermissions from "@/static/common/img/noDataNew/no-permissions.png";
|
||||
// 暂无图片
|
||||
import noPicture from "@/static/common/img/noDataNew/no-picture.png";
|
||||
|
||||
export default {
|
||||
name: "NoData",
|
||||
props: {
|
||||
// 图片类型
|
||||
type: {
|
||||
type: String,
|
||||
default: "default",
|
||||
},
|
||||
// 描述文字,默认值为"暂无数据"
|
||||
text: {
|
||||
type: String,
|
||||
default: "暂无数据",
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
getImage() {
|
||||
const imageMap = {
|
||||
default: noDataDefault,
|
||||
search: noDataSearch,
|
||||
message: noDataMessage,
|
||||
errorNet: errorNet,
|
||||
errorData: errorData,
|
||||
maintenance: maintenance,
|
||||
resume: noAttachmentResume,
|
||||
collection: noCollection,
|
||||
comments: noComments,
|
||||
content: noContent,
|
||||
file: noFile,
|
||||
friends: noFriends,
|
||||
internet: noInternet,
|
||||
permissions: noPermissions,
|
||||
picture: noPicture,
|
||||
};
|
||||
return imageMap[this.type] || imageMap.default;
|
||||
},
|
||||
},
|
||||
data: {
|
||||
/*
|
||||
<no-data type="default" text="暂无数据" />
|
||||
<no-data type="errorNet" text="网络错误" />
|
||||
<no-data type="search" text="暂无搜索内容" />
|
||||
<no-data type="errorData" text="数据加载失败" />
|
||||
<no-data type="message" text="暂无消息" />
|
||||
<no-data type="maintenance" text="系统维护中" />
|
||||
<no-data type="resume" text="暂无简历附件" />
|
||||
<no-data type="collection" text="暂无收藏" />
|
||||
<no-data type="comments" text="暂无评论" />
|
||||
<no-data type="content" text="暂无内容" />
|
||||
<no-data type="file" text="暂无文件" />
|
||||
<no-data type="friends" text="暂无好友" />
|
||||
<no-data type="internet" text="无网络连接" />
|
||||
<no-data type="permissions" text="暂无权限" />
|
||||
<no-data type="picture" text="暂无图片" /> */
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.empty-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* padding: 20rpx; */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-image {
|
||||
width: 400rpx;
|
||||
height: 300rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
<template>
|
||||
<view>
|
||||
<!-- v-if="current==0&&vuex_user.isAttestationGLY&&vuex_user.isAttestationJZG&&(vuex_user.isAttestationXY||true) || current==1&&(vuex_user.isAttestationXY||true)" -->
|
||||
<view
|
||||
v-if="false"
|
||||
id="_drag_button"
|
||||
class="drag"
|
||||
:style="'left: ' + left + 'px; top:' + top + 'px;transform: translateY(-60%);'"
|
||||
@touchstart="touchstart"
|
||||
@touchmove.stop.prevent="touchmove"
|
||||
@touchend.stop="touchend"
|
||||
@click.stop.prevent="click"
|
||||
:class="{ transition: isDock && !isMove }"
|
||||
>
|
||||
<u-icon name="plus" size="50" color="#ccc"></u-icon>
|
||||
<!-- <text>{{ text }}</text> -->
|
||||
</view>
|
||||
<view
|
||||
id="_drag_button"
|
||||
class="drag"
|
||||
:style="'left: ' + left + 'px; top:' + (top + 0)+ 'px;transform: translateY(60%);'"
|
||||
@touchstart="touchstart"
|
||||
@touchmove.stop.prevent="touchmove"
|
||||
@touchend.stop="touchend"
|
||||
@click.stop.prevent="reload"
|
||||
:class="{ transition: isDock && !isMove }"
|
||||
>
|
||||
<u-icon name="reload" size="50" color="#ccc"></u-icon>
|
||||
<!-- <text>{{ text }}</text> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'drag-button',
|
||||
props: {
|
||||
current:{
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
isDock: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
existTabBar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
offsetWidth: 0,
|
||||
offsetHeight: 0,
|
||||
windowWidth: 0,
|
||||
windowHeight: 0,
|
||||
isMove: true,
|
||||
edge: 70,
|
||||
wrap:10,
|
||||
text: '公告' //此处自定义按钮文字(1-3个汉字)
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const sys = uni.getSystemInfoSync();
|
||||
|
||||
this.windowWidth = sys.windowWidth;
|
||||
this.windowHeight = sys.windowHeight;
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
this.existTabBar && (this.windowHeight -= 50);
|
||||
// #endif
|
||||
if (sys.windowTop) {
|
||||
this.windowHeight += sys.windowTop;
|
||||
}
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query
|
||||
.select('#_drag_button')
|
||||
.boundingClientRect(data => {
|
||||
this.width = data.width;
|
||||
this.height = data.height;
|
||||
this.offsetWidth = data.width / 2;
|
||||
this.offsetHeight = data.height / 2;
|
||||
this.left = this.windowWidth - this.width - this.wrap;
|
||||
this.top = ((this.windowHeight - this.height - this.edge) * 3) / 4;
|
||||
})
|
||||
.exec();
|
||||
},
|
||||
methods: {
|
||||
click() {
|
||||
this.$emit('btnClick');
|
||||
},
|
||||
reload(){
|
||||
this.$emit('reload');
|
||||
},
|
||||
touchstart(e) {
|
||||
this.$emit('btnTouchstart');
|
||||
},
|
||||
touchmove(e) {
|
||||
// 单指触摸
|
||||
if (e.touches.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.isMove = true;
|
||||
this.left = e.touches[0].clientX - this.offsetWidth ;
|
||||
|
||||
let clientY = e.touches[0].clientY - this.offsetHeight -(this.height);
|
||||
// #ifdef H5
|
||||
clientY += this.height;
|
||||
// #endif
|
||||
let edgeBottom = this.windowHeight - this.height - this.edge;
|
||||
// 上下触及边界
|
||||
if (clientY < this.edge) {
|
||||
this.top = this.edge;
|
||||
} else if (clientY > edgeBottom) {
|
||||
this.top = edgeBottom;
|
||||
} else {
|
||||
this.top = clientY;
|
||||
}
|
||||
},
|
||||
touchend(e) {
|
||||
if (this.isDock) {
|
||||
let edgeRigth = this.windowWidth - this.width - this.wrap;
|
||||
|
||||
if (this.left < this.windowWidth / 2 - this.offsetWidth) {
|
||||
this.left = this.wrap;
|
||||
} else {
|
||||
this.left = edgeRigth;
|
||||
}
|
||||
}
|
||||
|
||||
this.isMove = false;
|
||||
|
||||
this.$emit('btnTouchend');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.drag {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
// background-color: rgba(0, 0, 0, 0.5);
|
||||
background-color: #FFFFFF;
|
||||
box-shadow: 0 0 6upx rgba(0, 0, 0, 0.4);
|
||||
color: $uni-text-color-inverse;
|
||||
width: 80upx;
|
||||
height: 80upx;
|
||||
border-radius: 50%;
|
||||
font-size: $uni-font-size-sm;
|
||||
position: fixed;
|
||||
z-index: 99;
|
||||
|
||||
&.transition {
|
||||
transition: left 0.3s ease, top 0.3s ease;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,277 @@
|
|||
/**
|
||||
* covert canvas to image
|
||||
* and save the image file
|
||||
*/
|
||||
|
||||
var Canvas2Image = function () {
|
||||
|
||||
// check if support sth.
|
||||
var $support = function () {
|
||||
var canvas = document.createElement('canvas'),
|
||||
ctx = canvas.getContext('2d');
|
||||
|
||||
return {
|
||||
canvas: !!ctx,
|
||||
imageData: !!ctx.getImageData,
|
||||
dataURL: !!canvas.toDataURL,
|
||||
btoa: !!window.btoa
|
||||
};
|
||||
}();
|
||||
|
||||
var downloadMime = 'image/octet-stream';
|
||||
|
||||
function scaleCanvas (canvas, width, height) {
|
||||
var w = canvas.width,
|
||||
h = canvas.height;
|
||||
if (width == undefined) {
|
||||
width = w;
|
||||
}
|
||||
if (height == undefined) {
|
||||
height = h;
|
||||
}
|
||||
|
||||
var retCanvas = document.createElement('canvas');
|
||||
var retCtx = retCanvas.getContext('2d');
|
||||
retCanvas.width = width;
|
||||
retCanvas.height = height;
|
||||
retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
|
||||
return retCanvas;
|
||||
}
|
||||
|
||||
function getDataURL (canvas, type, width, height) {
|
||||
canvas = scaleCanvas(canvas, width, height);
|
||||
return canvas.toDataURL(type);
|
||||
}
|
||||
|
||||
function saveFile (strData,filename) {
|
||||
var save_link = document.createElement('a');
|
||||
save_link.href = strData;
|
||||
save_link.download = filename;
|
||||
var event = new MouseEvent('click',{"bubbles":false, "cancelable":false});
|
||||
save_link.dispatchEvent(event);
|
||||
|
||||
}
|
||||
|
||||
function genImage(strData) {
|
||||
var img = document.createElement('img');
|
||||
img.src = strData;
|
||||
return img;
|
||||
}
|
||||
function fixType (type) {
|
||||
type = type.toLowerCase().replace(/jpg/i, 'jpeg');
|
||||
var r = type.match(/png|jpeg|bmp|gif/)[0];
|
||||
return 'image/' + r;
|
||||
}
|
||||
function encodeData (data) {
|
||||
if (!window.btoa) { throw 'btoa undefined' }
|
||||
var str = '';
|
||||
if (typeof data == 'string') {
|
||||
str = data;
|
||||
} else {
|
||||
for (var i = 0; i < data.length; i ++) {
|
||||
str += String.fromCharCode(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return btoa(str);
|
||||
}
|
||||
function getImageData (canvas) {
|
||||
var w = canvas.width,
|
||||
h = canvas.height;
|
||||
return canvas.getContext('2d').getImageData(0, 0, w, h);
|
||||
}
|
||||
function makeURI (strData, type) {
|
||||
return 'data:' + type + ';base64,' + strData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create bitmap image
|
||||
* 按照规则生成图片响应头和响应体
|
||||
*/
|
||||
var genBitmapImage = function (oData) {
|
||||
|
||||
//
|
||||
// BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
|
||||
// BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
|
||||
//
|
||||
|
||||
var biWidth = oData.width;
|
||||
var biHeight = oData.height;
|
||||
var biSizeImage = biWidth * biHeight * 3;
|
||||
var bfSize = biSizeImage + 54; // total header size = 54 bytes
|
||||
|
||||
//
|
||||
// typedef struct tagBITMAPFILEHEADER {
|
||||
// WORD bfType;
|
||||
// DWORD bfSize;
|
||||
// WORD bfReserved1;
|
||||
// WORD bfReserved2;
|
||||
// DWORD bfOffBits;
|
||||
// } BITMAPFILEHEADER;
|
||||
//
|
||||
var BITMAPFILEHEADER = [
|
||||
// WORD bfType -- The file type signature; must be "BM"
|
||||
0x42, 0x4D,
|
||||
// DWORD bfSize -- The size, in bytes, of the bitmap file
|
||||
bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
|
||||
// WORD bfReserved1 -- Reserved; must be zero
|
||||
0, 0,
|
||||
// WORD bfReserved2 -- Reserved; must be zero
|
||||
0, 0,
|
||||
// DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
|
||||
54, 0, 0, 0
|
||||
];
|
||||
|
||||
//
|
||||
// typedef struct tagBITMAPINFOHEADER {
|
||||
// DWORD biSize;
|
||||
// LONG biWidth;
|
||||
// LONG biHeight;
|
||||
// WORD biPlanes;
|
||||
// WORD biBitCount;
|
||||
// DWORD biCompression;
|
||||
// DWORD biSizeImage;
|
||||
// LONG biXPelsPerMeter;
|
||||
// LONG biYPelsPerMeter;
|
||||
// DWORD biClrUsed;
|
||||
// DWORD biClrImportant;
|
||||
// } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
|
||||
//
|
||||
var BITMAPINFOHEADER = [
|
||||
// DWORD biSize -- The number of bytes required by the structure
|
||||
40, 0, 0, 0,
|
||||
// LONG biWidth -- The width of the bitmap, in pixels
|
||||
biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
|
||||
// LONG biHeight -- The height of the bitmap, in pixels
|
||||
biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
|
||||
// WORD biPlanes -- The number of planes for the target device. This value must be set to 1
|
||||
1, 0,
|
||||
// WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
|
||||
// has a maximum of 2^24 colors (16777216, Truecolor)
|
||||
24, 0,
|
||||
// DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
|
||||
0, 0, 0, 0,
|
||||
// DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
|
||||
biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
|
||||
// LONG biXPelsPerMeter, unused
|
||||
0,0,0,0,
|
||||
// LONG biYPelsPerMeter, unused
|
||||
0,0,0,0,
|
||||
// DWORD biClrUsed, the number of color indexes of palette, unused
|
||||
0,0,0,0,
|
||||
// DWORD biClrImportant, unused
|
||||
0,0,0,0
|
||||
];
|
||||
|
||||
var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
|
||||
|
||||
var aImgData = oData.data;
|
||||
|
||||
var strPixelData = '';
|
||||
var biWidth4 = biWidth<<2;
|
||||
var y = biHeight;
|
||||
var fromCharCode = String.fromCharCode;
|
||||
|
||||
do {
|
||||
var iOffsetY = biWidth4*(y-1);
|
||||
var strPixelRow = '';
|
||||
for (var x = 0; x < biWidth; x++) {
|
||||
var iOffsetX = x<<2;
|
||||
strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) +
|
||||
fromCharCode(aImgData[iOffsetY+iOffsetX+1]) +
|
||||
fromCharCode(aImgData[iOffsetY+iOffsetX]);
|
||||
}
|
||||
|
||||
for (var c = 0; c < iPadding; c++) {
|
||||
strPixelRow += String.fromCharCode(0);
|
||||
}
|
||||
|
||||
strPixelData += strPixelRow;
|
||||
} while (--y);
|
||||
|
||||
var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
|
||||
|
||||
return strEncoded;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* [saveAsImage]
|
||||
* @param {[obj]} canvas [canvasElement]
|
||||
* @param {[Number]} width [optional] png width
|
||||
* @param {[Number]} height [optional] png height
|
||||
* @param {[String]} type [image type]
|
||||
* @param {[String]} filename [image filename]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
var saveAsImage = function (canvas, width, height, type,filename) {
|
||||
if ($support.canvas && $support.dataURL) {
|
||||
if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
|
||||
if (type == undefined) { type = 'png'; }
|
||||
filename = filename == undefined||filename.length === 0 ?Date.now()+'.'+type: filename+'.'+type
|
||||
type = fixType(type);
|
||||
|
||||
if (/bmp/.test(type)) {
|
||||
var data = getImageData(scaleCanvas(canvas, width, height));
|
||||
var strData = genBitmapImage(data);
|
||||
|
||||
saveFile(makeURI(strData, downloadMimedownloadMime),filename);
|
||||
} else {
|
||||
var strData = getDataURL(canvas, type, width, height);
|
||||
saveFile(strData.replace(type, downloadMime),filename);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var convertToImage = function (canvas, width, height, type) {
|
||||
if ($support.canvas && $support.dataURL) {
|
||||
if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
|
||||
if (type == undefined) { type = 'png'; }
|
||||
type = fixType(type);
|
||||
|
||||
if (/bmp/.test(type)) {
|
||||
var data = getImageData(scaleCanvas(canvas, width, height));
|
||||
var strData = genBitmapImage(data);
|
||||
return genImage(makeURI(strData, 'image/bmp'));
|
||||
} else {
|
||||
var strData = getDataURL(canvas, type, width, height);
|
||||
return genImage(strData);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return {
|
||||
saveAsImage: saveAsImage,
|
||||
saveAsPNG: function (canvas, width, height, fileName) {
|
||||
return saveAsImage(canvas, width, height, 'png',fileName);
|
||||
},
|
||||
saveAsJPEG: function (canvas, width, height, fileName) {
|
||||
return saveAsImage(canvas, width, height, 'jpeg',fileName);
|
||||
},
|
||||
saveAsGIF: function (canvas, width, height, fileName) {
|
||||
return saveAsImage(canvas, width, height, 'gif',fileName);
|
||||
},
|
||||
saveAsBMP: function (canvas, width, height, fileName) {
|
||||
return saveAsImage(canvas, width, height, 'bmp',fileName);
|
||||
},
|
||||
|
||||
convertToImage: convertToImage,
|
||||
convertToPNG: function (canvas, width, height) {
|
||||
return convertToImage(canvas, width, height, 'png');
|
||||
},
|
||||
convertToJPEG: function (canvas, width, height) {
|
||||
return convertToImage(canvas, width, height, 'jpeg');
|
||||
},
|
||||
convertToGIF: function (canvas, width, height) {
|
||||
return convertToImage(canvas, width, height, 'gif');
|
||||
},
|
||||
convertToBMP: function (canvas, width, height) {
|
||||
return convertToImage(canvas, width, height, 'bmp');
|
||||
}
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
export default Canvas2Image
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,34 @@
|
|||
import html2canvas from '@/components/dyw-html2image/html2canvas.min.js'
|
||||
import canvas2Image from '@/components/dyw-html2image/canvas2image.js' // canvas源码不支持import导入,在源码的最后添加export default使得可以将canvas2image对象import进来
|
||||
|
||||
/**
|
||||
* html2image: 将canvas2iamge以及html2canvas结合,将html转化为image. 方便大家使用,也可以自己去下载这两个插件,单独使用。
|
||||
* @param {Object} element : html元素,如document.body, document.getElementById('elementId')
|
||||
* @param {Object} html2canvasObject : html2canvas所需要的参数, 具体参数可访问html2canvas网站: http://html2canvas.hertzen.com/configuration
|
||||
* @param {String} saveType :'download'和'src'两种类型,第一种直接下载(微信中不可直接下载,被拦截)第二种返回src,可放入image标签中使用 canvas转image: git地址: https://github.com/hongru/canvas2image
|
||||
* @param {String} imageName : 导出的图片命名, 只有type为'download'才会生效
|
||||
* @param {String} type: 图片的类型: png, jpeg,gif,bmp,四种类型
|
||||
* **/
|
||||
var htmlToCavas = function(element, html2canvasObject, saveType='src', type='png', imageName) {
|
||||
var result = new Promise(function(resolve, reject){
|
||||
html2canvas(element, html2canvasObject).then(canvas => {
|
||||
var imageWidth = canvas.width
|
||||
var imageHeight = canvas.height
|
||||
console.log(canvas.toDataURL('image/jpeg'))
|
||||
console.log('测试')
|
||||
if(saveType=== 'download'){
|
||||
canvas2Image.saveAsImage(canvas, imageWidth, imageHeight, imageName, type)
|
||||
resolve()
|
||||
} else if(saveType === 'src'){
|
||||
var result = canvas2Image.convertToImage(canvas, imageWidth, imageHeight,type)
|
||||
console.log(result)
|
||||
resolve(result)
|
||||
}
|
||||
}).catch(err=> {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
export default htmlToCavas
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# html2canvas
|
||||
|
||||
### 使用方法
|
||||
|
||||
```
|
||||
import htmlToCavas from '@/components/html2image/html2image'
|
||||
|
||||
htmlToCavas(element, {
|
||||
useCORS: true,
|
||||
logging: true,
|
||||
backgroundColor: '#982121',
|
||||
scale: 2,
|
||||
dpi: 350}).then(res=> {
|
||||
this.imageSrc = res.src
|
||||
}).catch(err=> {
|
||||
console.log(err)
|
||||
})
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,318 @@
|
|||
<template>
|
||||
<view class="msgbox">
|
||||
<!-- <view class="quick" :style="[{ background: quick ? '#fff' : 'none' }]">
|
||||
<view class="justify-between section_7" v-if="quick">
|
||||
<view class="flex-row">
|
||||
<view class="flex-col items-center text-wrapper_2">
|
||||
<text class="text">交换信息</text>
|
||||
</view>
|
||||
<view class="flex-col items-end text-wrapper_3">
|
||||
<text class="text">交换联系方式</text>
|
||||
</view>
|
||||
</view>
|
||||
<image
|
||||
@click="quick = false"
|
||||
src="/static/common/img/msgclose.png"
|
||||
class="image_13"
|
||||
/>
|
||||
</view>
|
||||
<view style="display: flex; justify-content: flex-end" v-else>
|
||||
<image
|
||||
style="margin: 0.08rem; width: 0.2rem; height: 0.2rem"
|
||||
@click="quick = true"
|
||||
src="/static/common/img/msgopen.png"
|
||||
class="image_13"
|
||||
/>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="flex-row section_1">
|
||||
<text class="text" v-if="!isCommonWords" @click="CommonWords = !CommonWords;emoji = false;">常用语</text>
|
||||
|
||||
<view class="input-container">
|
||||
<image @click="emoji = !emoji;CommonWords = false;emojicurrent = 0;" src="/static/common/img/homepage/icon-message.png" class="input-icon" />
|
||||
<u-input class="input" :type="'textarea'" v-model="message" :auto-height="true" @click="shuru"
|
||||
@blur="inputBlur" @focus="inputFocus" :placeholder='placeholder'/>
|
||||
</view>
|
||||
<!-- <u-input class="input" :type="'textarea'" v-model="message" :auto-height="true" @click="shuru"
|
||||
@blur="inputBlur" @focus="inputFocus" :placeholder='placeholder'/> -->
|
||||
<!-- <view class="icon" @click="emoji = !emoji;CommonWords = false;emojicurrent = 0;">
|
||||
<image src="/static/common/img/icon.png" class="image" />
|
||||
</view> -->
|
||||
<view class="btn" v-if="message != ''">
|
||||
<!-- <u-button size="mini" class="sendOut" @click="send">发送</u-button> -->
|
||||
<image
|
||||
src="/static/common/img/homepage/icon-send.png"
|
||||
class="image_send"
|
||||
@click="send"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 常用语 -->
|
||||
<view class="CommonWords">
|
||||
<scroll-view scroll-y="true" style="transition: all 0.3s; height: 0rem" :class="CommonWords ? 'open' : ''">
|
||||
<text v-for="(v, i) in commonWords" :key="i" @click="choice(v)">{{v}}</text>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- emoji 表情 -->
|
||||
<swiper class="slider" :current="emojicurrent" :class="emoji ? 'emojishow' : ''">
|
||||
<swiper-item v-for="(item, key) in emojiData" :key="key" class="slider-emoji"
|
||||
:class="[key == emojiData.length - 1 ? 'lastbox' : '']">
|
||||
<text v-for="(emoji, index) in item" :key="index" @click="selemoji(emoji)"
|
||||
class="slider-emoji-icon">{{ emoji }}</text>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import emoji from "../static/common/js/emoji";
|
||||
export default {
|
||||
name: "messageBox",
|
||||
props:['isCommonWords'],
|
||||
data() {
|
||||
return {
|
||||
commonWords: [
|
||||
'您好,很高兴认识你!',
|
||||
'您好,有空聊一聊吗?',
|
||||
'嗨,你好呀!',
|
||||
'好的,我知道了。',
|
||||
'我们下次再聊,拜拜。'
|
||||
],
|
||||
CommonWords: false,
|
||||
quick: false,
|
||||
message: "",
|
||||
emojiData: [],
|
||||
emoji: false,
|
||||
inputShow: false,
|
||||
emojicurrent: 0,
|
||||
placeholder:"",
|
||||
};
|
||||
},
|
||||
// props:['placeholder'],
|
||||
mounted() {
|
||||
// console.log(this.placeholder)
|
||||
this.emojiInit();
|
||||
},
|
||||
created(){
|
||||
// console.log(this.placeholder)
|
||||
},
|
||||
methods: {
|
||||
outbox() {
|
||||
alert("out");
|
||||
},
|
||||
emojiInit() {
|
||||
var number = 60;
|
||||
var page = Math.ceil(emoji.length / number);
|
||||
for (let i = 0; i < page; i++) {
|
||||
this.emojiData[i] = [];
|
||||
for (let k = 0; k < number; k++) {
|
||||
emoji[i * number + k] ?
|
||||
this.emojiData[i].push(emoji[i * number + k]) :
|
||||
"";
|
||||
}
|
||||
}
|
||||
},
|
||||
inputFocus() {
|
||||
this.CommonWords = false;
|
||||
this.emoji = false;
|
||||
setTimeout(() => {
|
||||
this.scrollTop += 1;
|
||||
}, 100);
|
||||
// console.log("inputFocus");
|
||||
},
|
||||
inputBlur() {
|
||||
// console.log("inputBlur");
|
||||
},
|
||||
shuru() {
|
||||
setTimeout(() => {
|
||||
this.scrollTop += 1;
|
||||
}, 100);
|
||||
},
|
||||
choice(txt) {
|
||||
this.message = txt;
|
||||
},
|
||||
close() {
|
||||
this.CommonWords = false;
|
||||
this.emoji = false;
|
||||
},
|
||||
sendOut() {
|
||||
this.close();
|
||||
},
|
||||
selemoji(m) {
|
||||
this.message += m;
|
||||
},
|
||||
send(){
|
||||
this.$emit('onsend',this.message)
|
||||
this.message = ""
|
||||
this.$emit('onmsgShow',false)
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.msgbox {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
|
||||
.section_1 {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
// height: 0.52rem;
|
||||
background-color: #ffffff;
|
||||
border: solid 0.01rem #eeeeee;
|
||||
padding: 0.11rem 0.1rem 0.11rem 0.1rem;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.15rem;
|
||||
color: #505051;
|
||||
margin: 0 0.1rem;
|
||||
line-height: 0.36rem;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
min-height: 0.36rem !important;
|
||||
line-height: 0.36rem;
|
||||
background-color: #f7f7f7;
|
||||
border-radius: 0.1rem;
|
||||
font-size: 0.14rem;
|
||||
padding-right: 0.1rem !important;
|
||||
|
||||
::v-deep .u-input__input {
|
||||
padding: 0.05rem;
|
||||
min-height: 0.16rem !important;
|
||||
transform: translateY(0.03rem);
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-left: 0.05rem;
|
||||
padding: 0.03rem 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 0.03rem 0;
|
||||
|
||||
.sendOut {
|
||||
height: 0.3rem;
|
||||
line-height: 0.3rem;
|
||||
width: 0.5rem;
|
||||
margin-left: 0.05rem;
|
||||
background-color: #2e9bff;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.image_send {
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
margin-left: 0.05rem;
|
||||
transform: translateY(0.03rem);
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 0.26rem;
|
||||
height: 0.26rem;
|
||||
}
|
||||
|
||||
.CommonWords {
|
||||
width: 100%;
|
||||
background-color: #f6f7fa;
|
||||
|
||||
text {
|
||||
transition: all 0.3s;
|
||||
display: block;
|
||||
padding: 0.1rem 0 0.1rem 0.2rem;
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.2rem;
|
||||
height: 0.4rem;
|
||||
overflow: hidden;
|
||||
color: #505051;
|
||||
}
|
||||
|
||||
text:active {
|
||||
background: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
.open {
|
||||
height: 3rem !important;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.input-container{
|
||||
position: relative;
|
||||
// width: 90%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
|
||||
|
||||
.input-icon {
|
||||
width: 0.2rem;
|
||||
height: 0.2rem;
|
||||
position: absolute;
|
||||
left: 0.1rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
min-height: 0.36rem !important;
|
||||
line-height: 0.36rem;
|
||||
// background-color: #f7f7f7;
|
||||
border-radius: 0.1rem;
|
||||
font-size: 0.14rem;
|
||||
padding-right: 0.1rem !important;
|
||||
padding-left: 0.35rem !important; /* 为左侧图标留出空间 */
|
||||
|
||||
::v-deep .u-input__input {
|
||||
padding: 0.05rem;
|
||||
min-height: 0.16rem !important;
|
||||
transform: translateY(0.03rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.emojishow {
|
||||
height: 3rem !important;
|
||||
}
|
||||
|
||||
.slider {
|
||||
background: #fff;
|
||||
width: 7.75rem;
|
||||
height: 0rem;
|
||||
transition: all 0.3s;
|
||||
|
||||
.slider-emoji {
|
||||
overflow-y: scroll;
|
||||
width: 100vw !important;
|
||||
}
|
||||
|
||||
&-emoji {
|
||||
width: 6.75rem;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
&-icon {
|
||||
font-size: 0.265rem;
|
||||
display: inline-block;
|
||||
width: 0.4rem;
|
||||
text-align: center;
|
||||
padding: 0.05rem 0;
|
||||
border-radius: 0.1rem;
|
||||
// border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
&-icon:active {
|
||||
background: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
<template>
|
||||
<view class="nav-wrap">
|
||||
<view class="nav-title">
|
||||
<image class="logo" src="https://cdn.uviewui.com/uview/common/logo.png" mode="widthFix"></image>
|
||||
<view class="nav-info">
|
||||
<view class="nav-title__text">
|
||||
{{$t('common.title')}}
|
||||
</view>
|
||||
<view class="nav-slogan">
|
||||
{{$t('common.intro')}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nav-desc">
|
||||
{{desc}}
|
||||
</view>
|
||||
<view class="lang" @tap="switchLang">
|
||||
<u-icon size="46" color="warning" :name="lang"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
desc: String,
|
||||
title: String,
|
||||
},
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$i18n.locale == 'zh' ? 'zh' : 'en';
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
switchLang() {
|
||||
this.$i18n.locale = this.$i18n.locale == 'en' ? 'zh' : 'en';
|
||||
this.vuex_tabbar[0].text = this.$t('nav.components')
|
||||
this.vuex_tabbar[1].text = this.$t('nav.js')
|
||||
this.vuex_tabbar[2].text = this.$t('nav.template')
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.$t(this.title)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.nav-wrap {
|
||||
padding: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.lang {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-info {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.nav-title__text {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
color: $u-main-color;
|
||||
font-size: 25px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 70px;
|
||||
/* #ifndef APP-NVUE */
|
||||
height: auto;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.nav-slogan {
|
||||
color: $u-tips-color;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.nav-desc {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
color: $u-content-color;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// 返校核验状态枚举
|
||||
|
||||
export const AuditStateEnumMap = new Map([
|
||||
[0, '待审核'],
|
||||
[1, '通过'],
|
||||
[2, '未通过'],
|
||||
])
|
||||
|
||||
//
|
||||
export const PrebookStateEnumMap = new Map([
|
||||
[0, '待核验'],
|
||||
[1, '已取消'],
|
||||
[2, '已驳回'],
|
||||
[3, '已核验'],
|
||||
[4, '未返校'],
|
||||
])
|
||||
|
||||
// 彭剑提供的枚举
|
||||
export const glyTypeEnumMap = new Map([
|
||||
[0,'校级管理员'],
|
||||
[1,'教职工管理员'],
|
||||
[2,'学生管理员'],
|
||||
[3,'普通人员'],
|
||||
])
|
||||
|
|
@ -0,0 +1,462 @@
|
|||
/**
|
||||
* 微信小程序JavaScriptSDK
|
||||
*
|
||||
* @version 1.0
|
||||
* @date 2017-01-10
|
||||
* @author jaysonzhou@tencent.com
|
||||
*/
|
||||
|
||||
var ERROR_CONF = {
|
||||
KEY_ERR: 311,
|
||||
KEY_ERR_MSG: 'key格式错误',
|
||||
PARAM_ERR: 310,
|
||||
PARAM_ERR_MSG: '请求参数信息有误',
|
||||
SYSTEM_ERR: 600,
|
||||
SYSTEM_ERR_MSG: '系统错误',
|
||||
WX_ERR_CODE: 1000,
|
||||
WX_OK_CODE: 200
|
||||
};
|
||||
var BASE_URL = 'https://apis.map.qq.com/ws/';
|
||||
var URL_SEARCH = BASE_URL + 'place/v1/search';
|
||||
var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion';
|
||||
var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/';
|
||||
var URL_CITY_LIST = BASE_URL + 'district/v1/list';
|
||||
var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren';
|
||||
var URL_DISTANCE = BASE_URL + 'distance/v1/';
|
||||
var Utils = {
|
||||
/**
|
||||
* 得到终点query字符串
|
||||
* @param {Array|String} 检索数据
|
||||
*/
|
||||
location2query(data) {
|
||||
if (typeof data == 'string') {
|
||||
return data;
|
||||
}
|
||||
var query = '';
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var d = data[i];
|
||||
if (!!query) {
|
||||
query += ';';
|
||||
}
|
||||
if (d.location) {
|
||||
query = query + d.location.lat + ',' + d.location.lng;
|
||||
}
|
||||
if (d.latitude && d.longitude) {
|
||||
query = query + d.latitude + ',' + d.longitude;
|
||||
}
|
||||
}
|
||||
return query;
|
||||
},
|
||||
|
||||
/**
|
||||
* 使用微信接口进行定位
|
||||
*/
|
||||
getWXLocation(success, fail, complete) {
|
||||
wx.getLocation({
|
||||
type: 'gcj02',
|
||||
success: success,
|
||||
fail: fail,
|
||||
complete: complete
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取location参数
|
||||
*/
|
||||
getLocationParam(location) {
|
||||
if (typeof location == 'string') {
|
||||
var locationArr = location.split(',');
|
||||
if (locationArr.length === 2) {
|
||||
location = {
|
||||
latitude: location.split(',')[0],
|
||||
longitude: location.split(',')[1]
|
||||
};
|
||||
} else {
|
||||
location = {};
|
||||
}
|
||||
}
|
||||
return location;
|
||||
},
|
||||
|
||||
/**
|
||||
* 回调函数默认处理
|
||||
*/
|
||||
polyfillParam(param) {
|
||||
param.success = param.success || function () { };
|
||||
param.fail = param.fail || function () { };
|
||||
param.complete = param.complete || function () { };
|
||||
},
|
||||
|
||||
/**
|
||||
* 验证param对应的key值是否为空
|
||||
*
|
||||
* @param {Object} param 接口参数
|
||||
* @param {String} key 对应参数的key
|
||||
*/
|
||||
checkParamKeyEmpty(param, key) {
|
||||
if (!param[key]) {
|
||||
var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误');
|
||||
param.fail(errconf);
|
||||
param.complete(errconf);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* 验证参数中是否存在检索词keyword
|
||||
*
|
||||
* @param {Object} param 接口参数
|
||||
*/
|
||||
checkKeyword(param){
|
||||
return !this.checkParamKeyEmpty(param, 'keyword');
|
||||
},
|
||||
|
||||
/**
|
||||
* 验证location值
|
||||
*
|
||||
* @param {Object} param 接口参数
|
||||
*/
|
||||
checkLocation(param) {
|
||||
var location = this.getLocationParam(param.location);
|
||||
if (!location || !location.latitude || !location.longitude) {
|
||||
var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误')
|
||||
param.fail(errconf);
|
||||
param.complete(errconf);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 构造错误数据结构
|
||||
* @param {Number} errCode 错误码
|
||||
* @param {Number} errMsg 错误描述
|
||||
*/
|
||||
buildErrorConfig(errCode, errMsg) {
|
||||
return {
|
||||
status: errCode,
|
||||
message: errMsg
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 构造微信请求参数,公共属性处理
|
||||
*
|
||||
* @param {Object} param 接口参数
|
||||
* @param {Object} param 配置项
|
||||
*/
|
||||
buildWxRequestConfig(param, options) {
|
||||
var that = this;
|
||||
options.header = { "content-type": "application/json" };
|
||||
options.method = 'GET';
|
||||
options.success = function (res) {
|
||||
var data = res.data;
|
||||
if (data.status === 0) {
|
||||
param.success(data);
|
||||
} else {
|
||||
param.fail(data);
|
||||
}
|
||||
};
|
||||
options.fail = function (res) {
|
||||
res.statusCode = ERROR_CONF.WX_ERR_CODE;
|
||||
param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, result.errMsg));
|
||||
};
|
||||
options.complete = function (res) {
|
||||
var statusCode = +res.statusCode;
|
||||
switch(statusCode) {
|
||||
case ERROR_CONF.WX_ERR_CODE: {
|
||||
param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
|
||||
break;
|
||||
}
|
||||
case ERROR_CONF.WX_OK_CODE: {
|
||||
var data = res.data;
|
||||
if (data.status === 0) {
|
||||
param.complete(data);
|
||||
} else {
|
||||
param.complete(that.buildErrorConfig(data.status, data.message));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return options;
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理用户参数是否传入坐标进行不同的处理
|
||||
*/
|
||||
locationProcess(param, locationsuccess, locationfail, locationcomplete) {
|
||||
var that = this;
|
||||
locationfail = locationfail || function (res) {
|
||||
res.statusCode = ERROR_CONF.WX_ERR_CODE;
|
||||
param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
|
||||
};
|
||||
locationcomplete = locationcomplete || function (res) {
|
||||
if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
|
||||
param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
|
||||
}
|
||||
};
|
||||
if (!param.location) {
|
||||
that.getWXLocation(locationsuccess, locationfail, locationcomplete);
|
||||
} else if (that.checkLocation(param)) {
|
||||
var location = Utils.getLocationParam(param.location);
|
||||
locationsuccess(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class QQMapWX {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @param {Object} options 接口参数,key 为必选参数
|
||||
*/
|
||||
constructor(options) {
|
||||
if (!options.key) {
|
||||
throw Error('key值不能为空');
|
||||
}
|
||||
this.key = options.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* POI周边检索
|
||||
*
|
||||
* @param {Object} options 接口参数对象
|
||||
*
|
||||
* 参数对象结构可以参考
|
||||
* @see http://lbs.qq.com/webservice_v1/guide-search.html
|
||||
*/
|
||||
search(options) {
|
||||
var that = this;
|
||||
options = options || {};
|
||||
|
||||
Utils.polyfillParam(options);
|
||||
|
||||
if (!Utils.checkKeyword(options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var requestParam = {
|
||||
keyword: options.keyword,
|
||||
orderby: options.orderby || '_distance',
|
||||
page_size: options.page_size || 10,
|
||||
page_index: options.page_index || 1,
|
||||
output: 'json',
|
||||
key: that.key
|
||||
};
|
||||
|
||||
if (options.address_format) {
|
||||
requestParam.address_format = options.address_format;
|
||||
}
|
||||
|
||||
if (options.filter) {
|
||||
requestParam.filter = options.filter;
|
||||
}
|
||||
|
||||
var distance = options.distance || "1000";
|
||||
var auto_extend = options.auto_extend || 1;
|
||||
|
||||
var locationsuccess = function (result) {
|
||||
requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend +")";
|
||||
wx.request(Utils.buildWxRequestConfig(options, {
|
||||
url: URL_SEARCH,
|
||||
data: requestParam
|
||||
}));
|
||||
}
|
||||
Utils.locationProcess(options, locationsuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* sug模糊检索
|
||||
*
|
||||
* @param {Object} options 接口参数对象
|
||||
*
|
||||
* 参数对象结构可以参考
|
||||
* http://lbs.qq.com/webservice_v1/guide-suggestion.html
|
||||
*/
|
||||
getSuggestion(options) {
|
||||
var that = this;
|
||||
options = options || {};
|
||||
Utils.polyfillParam(options);
|
||||
|
||||
if (!Utils.checkKeyword(options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var requestParam = {
|
||||
keyword: options.keyword,
|
||||
region: options.region || '全国',
|
||||
region_fix: options.region_fix || 0,
|
||||
policy: options.policy || 0,
|
||||
output: 'json',
|
||||
key: that.key
|
||||
};
|
||||
wx.request(Utils.buildWxRequestConfig(options, {
|
||||
url: URL_SUGGESTION,
|
||||
data: requestParam
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 逆地址解析
|
||||
*
|
||||
* @param {Object} options 接口参数对象
|
||||
*
|
||||
* 请求参数结构可以参考
|
||||
* http://lbs.qq.com/webservice_v1/guide-gcoder.html
|
||||
*/
|
||||
reverseGeocoder(options) {
|
||||
var that = this;
|
||||
options = options || {};
|
||||
Utils.polyfillParam(options);
|
||||
var requestParam = {
|
||||
coord_type: options.coord_type || 5,
|
||||
get_poi: options.get_poi || 0,
|
||||
output: 'json',
|
||||
key: that.key
|
||||
};
|
||||
if (options.poi_options) {
|
||||
requestParam.poi_options = options.poi_options
|
||||
}
|
||||
|
||||
var locationsuccess = function (result) {
|
||||
requestParam.location = result.latitude + ',' + result.longitude;
|
||||
wx.request(Utils.buildWxRequestConfig(options, {
|
||||
url: URL_GET_GEOCODER,
|
||||
data: requestParam
|
||||
}));
|
||||
};
|
||||
Utils.locationProcess(options, locationsuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 地址解析
|
||||
*
|
||||
* @param {Object} options 接口参数对象
|
||||
*
|
||||
* 请求参数结构可以参考
|
||||
* http://lbs.qq.com/webservice_v1/guide-geocoder.html
|
||||
*/
|
||||
geocoder(options) {
|
||||
var that = this;
|
||||
options = options || {};
|
||||
Utils.polyfillParam(options);
|
||||
|
||||
if (Utils.checkParamKeyEmpty(options, 'address')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var requestParam = {
|
||||
address: options.address,
|
||||
output: 'json',
|
||||
key: that.key
|
||||
};
|
||||
|
||||
wx.request(Utils.buildWxRequestConfig(options, {
|
||||
url: URL_GET_GEOCODER,
|
||||
data: requestParam
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取城市列表
|
||||
*
|
||||
* @param {Object} options 接口参数对象
|
||||
*
|
||||
* 请求参数结构可以参考
|
||||
* http://lbs.qq.com/webservice_v1/guide-region.html
|
||||
*/
|
||||
getCityList(options) {
|
||||
var that = this;
|
||||
options = options || {};
|
||||
Utils.polyfillParam(options);
|
||||
var requestParam = {
|
||||
output: 'json',
|
||||
key: that.key
|
||||
};
|
||||
|
||||
wx.request(Utils.buildWxRequestConfig(options, {
|
||||
url: URL_CITY_LIST,
|
||||
data: requestParam
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对应城市ID的区县列表
|
||||
*
|
||||
* @param {Object} options 接口参数对象
|
||||
*
|
||||
* 请求参数结构可以参考
|
||||
* http://lbs.qq.com/webservice_v1/guide-region.html
|
||||
*/
|
||||
getDistrictByCityId(options) {
|
||||
var that = this;
|
||||
options = options || {};
|
||||
Utils.polyfillParam(options);
|
||||
|
||||
if (Utils.checkParamKeyEmpty(options, 'id')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var requestParam = {
|
||||
id: options.id || '',
|
||||
output: 'json',
|
||||
key: that.key
|
||||
};
|
||||
|
||||
wx.request(Utils.buildWxRequestConfig(options, {
|
||||
url: URL_AREA_LIST,
|
||||
data: requestParam
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于单起点到多终点的路线距离(非直线距离)计算:
|
||||
* 支持两种距离计算方式:步行和驾车。
|
||||
* 起点到终点最大限制直线距离10公里。
|
||||
*
|
||||
* @param {Object} options 接口参数对象
|
||||
*
|
||||
* 请求参数结构可以参考
|
||||
* http://lbs.qq.com/webservice_v1/guide-distance.html
|
||||
*/
|
||||
calculateDistance(options) {
|
||||
var that = this;
|
||||
options = options || {};
|
||||
Utils.polyfillParam(options);
|
||||
|
||||
if (Utils.checkParamKeyEmpty(options, 'to')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var requestParam = {
|
||||
mode: options.mode || 'walking',
|
||||
to: Utils.location2query(options.to),
|
||||
output: 'json',
|
||||
key: that.key
|
||||
};
|
||||
|
||||
var locationsuccess = function (result) {
|
||||
requestParam.from = result.latitude + ',' + result.longitude;
|
||||
wx.request(Utils.buildWxRequestConfig(options, {
|
||||
url: URL_DISTANCE,
|
||||
data: requestParam
|
||||
}));
|
||||
}
|
||||
if (options.from) {
|
||||
options.location = options.from;
|
||||
}
|
||||
|
||||
Utils.locationProcess(options, locationsuccess);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = QQMapWX;
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,106 @@
|
|||
import Vue from 'vue';
|
||||
import App from './App';
|
||||
import "./static/common/css/font.css"
|
||||
import common from './static/common/js/common'
|
||||
import jweixin from 'jweixin-module'
|
||||
import {
|
||||
HubConnectionBuilder,
|
||||
LogLevel,
|
||||
} from "./uni_modules/Lyuan-SignalR/js_sdk/signalr";
|
||||
|
||||
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
App.mpType = 'app';
|
||||
// 提示
|
||||
var tips = function(title, type, time) {
|
||||
this.$refs.uTips.show({
|
||||
title: title ? title : "",
|
||||
type: type ? type : "success",
|
||||
duration: time ? time + "" : "1000",
|
||||
});
|
||||
}
|
||||
|
||||
// 导入公用js
|
||||
Vue.prototype.$tips = tips
|
||||
Vue.prototype.common = common
|
||||
// 导入微信sdk
|
||||
Vue.prototype.jweixin = jweixin
|
||||
// 引入全局uView
|
||||
import uView from 'uview-ui';
|
||||
Vue.use(uView);
|
||||
|
||||
// 此处为演示vuex使用,非uView的功能部分
|
||||
import store from '@/store';
|
||||
|
||||
// 引入uView提供的对vuex的简写法文件
|
||||
let vuexStore = require('@/store/$u.mixin.js');
|
||||
Vue.mixin(vuexStore);
|
||||
|
||||
// 引入uView对小程序分享的mixin封装
|
||||
let mpShare = require('uview-ui/libs/mixin/mpShare.js');
|
||||
Vue.mixin(mpShare);
|
||||
|
||||
// 引入 jsonp
|
||||
import {VueJsonp} from 'vue-jsonp' //中间有忘记大括号出现install undefind问题
|
||||
Vue.use(VueJsonp)
|
||||
|
||||
// i18n部分的配置
|
||||
// 引入语言包,注意路径
|
||||
import Chinese from '@/common/locales/zh.js';
|
||||
import English from '@/common/locales/en.js';
|
||||
|
||||
// VueI18n
|
||||
import VueI18n from '@/common/vue-i18n.min.js';
|
||||
|
||||
// VueI18n
|
||||
Vue.use(VueI18n);
|
||||
|
||||
const i18n = new VueI18n({
|
||||
// 默认语言
|
||||
locale: 'zh',
|
||||
// 引入语言文件
|
||||
messages: {
|
||||
'zh': Chinese,
|
||||
'en': English,
|
||||
}
|
||||
});
|
||||
|
||||
// 由于微信小程序的运行机制问题,需声明如下一行,H5和APP非必填
|
||||
Vue.prototype._i18n = i18n;
|
||||
|
||||
|
||||
const app = new Vue({
|
||||
i18n,
|
||||
store,
|
||||
...App
|
||||
});
|
||||
|
||||
// http拦截器,将此部分放在new Vue()和app.$mount()之间,才能App.vue中正常使用
|
||||
import httpInterceptor from '@/common/http.interceptor.js';
|
||||
Vue.use(httpInterceptor, app);
|
||||
|
||||
// http接口API抽离,免于写url或者一些固定的参数
|
||||
import httpApi from '@/common/http.api.js';
|
||||
Vue.use(httpApi, app);
|
||||
|
||||
import httpApiList from '@/common/http.apiList.js';
|
||||
Vue.use(httpApiList, app);
|
||||
|
||||
var connection = new HubConnectionBuilder()
|
||||
// .withUrl("https://xy.apps.service.zheke.com/ChatHub",)
|
||||
.withUrl("http://sl.vrgon.com:8003/ChatHub",)
|
||||
.configureLogging(LogLevel.Error)
|
||||
.build();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Vue.prototype.$connection = connection
|
||||
|
||||
|
||||
|
||||
|
||||
app.$mount();
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
{
|
||||
"name" : "Dl Chat",
|
||||
"appid" : "__UNI__D70D15E",
|
||||
"description" : "",
|
||||
"versionName" : "1.8.4",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
"sassImplementationName" : "node-sass",
|
||||
"app-plus" : {
|
||||
"optimization" : {
|
||||
"subPackages" : true
|
||||
},
|
||||
"safearea" : {
|
||||
"bottom" : {
|
||||
"offset" : "none"
|
||||
}
|
||||
},
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
"usingComponents" : true,
|
||||
"nvueCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"modules" : {},
|
||||
"distribute" : {
|
||||
"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.READ_CONTACTS\"/>",
|
||||
"<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.WRITE_CONTACTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
|
||||
"<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.CALL_PHONE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
],
|
||||
"abiFilters" : [ "armeabi-v7a", "arm64-v8a" ]
|
||||
},
|
||||
"ios" : {},
|
||||
"sdkConfigs" : {
|
||||
"ad" : {}
|
||||
},
|
||||
"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" : true,
|
||||
"es6" : false,
|
||||
"minified" : true,
|
||||
"postcss" : true
|
||||
},
|
||||
"optimization" : {
|
||||
"subPackages" : true
|
||||
},
|
||||
"usingComponents" : true,
|
||||
"permission" : {},
|
||||
"secureNetwork" : {
|
||||
"enable" : false
|
||||
}
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true,
|
||||
"component2" : true
|
||||
},
|
||||
"mp-qq" : {
|
||||
"optimization" : {
|
||||
"subPackages" : true
|
||||
},
|
||||
"appid" : "15646153"
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true,
|
||||
"appid" : ""
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true,
|
||||
"appid" : ""
|
||||
},
|
||||
"h5" : {
|
||||
"devServer" : {
|
||||
"port" : 8080,
|
||||
"disableHostCheck" : true,
|
||||
// "proxy" : {
|
||||
// "/api" : {
|
||||
// "target" : "https://apis.map.qq.com",
|
||||
// "changeOrigin" : true,
|
||||
// "secure" : false,
|
||||
// "pathRewrite" : {
|
||||
// "^/api" : ""
|
||||
// }
|
||||
// },
|
||||
// "/dpa" : {
|
||||
// "target" : "http://pv.sohu.com",
|
||||
// "changeOrigin" : true,
|
||||
// "secure" : false,
|
||||
// "pathRewrite" : {
|
||||
// "^/dpa" : ""
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
"https" : false
|
||||
},
|
||||
"template" : "template.h5.html",
|
||||
"router" : {
|
||||
"mode" : "hash",
|
||||
"base" : "./"
|
||||
},
|
||||
"optimization" : {
|
||||
"treeShaking" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"title" : "笑柚",
|
||||
"sdkConfigs" : {
|
||||
"maps" : {
|
||||
"qqmap" : {
|
||||
"key" : "2OLBZ-OOSRQ-RYZ5A-GMCM2-DJ43O-3QFLS"
|
||||
},
|
||||
"tencent" : {
|
||||
"key" : "2OLBZ-OOSRQ-RYZ5A-GMCM2-DJ43O-3QFLS"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"name": "uView",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"node_modules/css-line-break": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/html2canvas": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
||||
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
||||
"dependencies": {
|
||||
"css-line-break": "^2.1.0",
|
||||
"text-segmentation": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-md5": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.8.3.tgz",
|
||||
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ=="
|
||||
},
|
||||
"node_modules/jweixin-module": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jweixin-module/-/jweixin-module-1.6.0.tgz",
|
||||
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
|
||||
},
|
||||
"node_modules/text-segmentation": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/utrie": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||
"dependencies": {
|
||||
"base64-arraybuffer": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-i18n": {
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.20.0.tgz",
|
||||
"integrity": "sha512-ZiAOoeR4d/JtKpbjipx3I80ey7cYG1ki5gQ7HwzWm4YFio9brA15BEYHjalEoBaEfzF5OBEZP+Y2MvAaWnyXXg=="
|
||||
},
|
||||
"node_modules/vue-jsonp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-jsonp/-/vue-jsonp-2.0.0.tgz",
|
||||
"integrity": "sha512-Mzd9GNeuKP5hHFDWZNMWOsCuMILSkA6jo2l4A02wheFz3qqBzH7aSEFTey1BRCZCLizlaf1EqJ5YUtF392KspA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# jweixin-module
|
||||
|
||||
微信JS-SDK
|
||||
|
||||
## 安装
|
||||
|
||||
### NPM
|
||||
|
||||
```shell
|
||||
npm install jweixin-module --save
|
||||
```
|
||||
|
||||
### UMD
|
||||
|
||||
```http
|
||||
https://unpkg.com/jweixin-module/out/index.js
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
```js
|
||||
var jweixin = require('jweixin-module')
|
||||
jweixin.ready(function(){
|
||||
// TODO
|
||||
});
|
||||
```
|
||||
|
||||
## 完整API
|
||||
|
||||
>[微信JS-SDK说明文档](https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115)
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"_from": "jweixin-module",
|
||||
"_id": "jweixin-module@1.6.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w==",
|
||||
"_location": "/jweixin-module",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "jweixin-module",
|
||||
"name": "jweixin-module",
|
||||
"escapedName": "jweixin-module",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/jweixin-module/-/jweixin-module-1.6.0.tgz",
|
||||
"_shasum": "4a7ea614083e3c9c3f49e2fdc2bb882cfa58dfcd",
|
||||
"_spec": "jweixin-module",
|
||||
"_where": "C:\\Users\\Administrator\\Documents\\HBuilderProjects\\笑柚",
|
||||
"author": {
|
||||
"name": "Shengqiang Guo"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/zhetengbiji/jweixin-module/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "微信JS-SDK",
|
||||
"devDependencies": {},
|
||||
"homepage": "https://github.com/zhetengbiji/jweixin-module#readme",
|
||||
"keywords": [
|
||||
"wxjssdk",
|
||||
"weixin",
|
||||
"jweixin",
|
||||
"wechat",
|
||||
"jssdk",
|
||||
"wx"
|
||||
],
|
||||
"license": "ISC",
|
||||
"main": "lib/index.js",
|
||||
"name": "jweixin-module",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/zhetengbiji/jweixin-module.git"
|
||||
},
|
||||
"scripts": {},
|
||||
"version": "1.6.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 kazuya kawaguchi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<p align="center"><img width="128px" height="112px" src="./assets/vue-i18n-logo.png" alt="Vue I18n logo"></p>
|
||||
<h1 align="center">vue-i18n</h1>
|
||||
<p align="center">
|
||||
<a href="https://circleci.com/gh/kazupon/vue-i18n/tree/dev"><img src="https://circleci.com/gh/kazupon/vue-i18n/tree/dev.svg?style=shield" alt="Build Status"></a>
|
||||
<a href="https://codecov.io/gh/kazupon/vue-i18n"><img src="https://codecov.io/gh/kazupon/vue-i18n/branch/dev/graph/badge.svg" alt="Coverage Status"></a>
|
||||
<a href="http://badge.fury.io/js/vue-i18n"><img src="https://badge.fury.io/js/vue-i18n.svg" alt="NPM version"></a>
|
||||
<a href="https://discord.gg/4yCnk2m"><img src="https://img.shields.io/badge/Discord-join%20chat-738bd7.svg" alt="vue-i18n channel on Discord"></a>
|
||||
<a href="https://devtoken.rocks/package/vue-i18n"><img src="https://badge.devtoken.rocks/vue-i18n" alt="vue-i18n Dev Token"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">Internationalization plugin for Vue.js</p>
|
||||
|
||||
<br/>
|
||||
|
||||
<h3 align="center">Silver Sponsors</h3>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.codeandweb.com/babeledit?utm_campaign=vue-i18n-2019-01" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/kazupon/vue-i18n/dev/vuepress/.vuepress/public/patrons/babeledit.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h3 align="center">Bronze Sponsors</h3>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://zenarchitects.co.jp/" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/kazupon/vue-i18n/v8.x/vuepress/.vuepress/public/patrons/zenarchitects.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br/>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.patreon.com/kazupon" target="_blank">
|
||||
<img src="https://c5.patreon.com/external/logo/become_a_patron_button.png" alt="Become a Patreon">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br/>
|
||||
|
||||
## :loudspeaker: Notice
|
||||
|
||||
vue-i18n will soon be transferred to [intlify organization](https://github.com/intlify). After that, it will be developed and maintained on intlify.
|
||||
|
||||
The `vue-i18n` that has been released on npm will be released as `@intlify/vue-i18n` in near future.
|
||||
|
||||
`@intlify/vue-i18n` repo is [here](https://github.com/intlify/vue-i18n-next)
|
||||
|
||||
Intlify is a new i18n project kickoff by @kazupon. 😉
|
||||
|
||||
## :book: Documentation
|
||||
|
||||
See [here](http://kazupon.github.io/vue-i18n/)
|
||||
|
||||
|
||||
## :scroll: Changelog
|
||||
|
||||
Detailed changes for each release are documented in the [CHANGELOG.md](https://github.com/kazupon/vue-i18n/blob/dev/CHANGELOG.md).
|
||||
|
||||
|
||||
## :exclamation: Issues
|
||||
|
||||
Please make sure to read the [Issue Reporting Checklist](https://github.com/kazupon/vue-i18n/blob/dev/CONTRIBUTING.md#issue-reporting-guidelines) before opening an issue. Issues not conforming to the guidelines may be closed immediately.
|
||||
|
||||
|
||||
## :muscle: Contribution
|
||||
|
||||
Please make sure to read the [Contributing Guide](https://github.com/kazupon/vue-i18n/blob/dev/CONTRIBUTING.md) before making a pull request.
|
||||
|
||||
|
||||
## :copyright: License
|
||||
|
||||
[MIT](http://opensource.org/licenses/MIT)
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
declare var Intl: any;
|
||||
|
||||
declare type Path = string;
|
||||
declare type Locale = string;
|
||||
declare type FallbackLocale = string | string[] | false | { [locale: string]: string[] };
|
||||
declare type LocaleMessage = string | LocaleMessageObject | LocaleMessageArray;
|
||||
declare type LocaleMessageObject = { [key: Path]: LocaleMessage };
|
||||
declare type LocaleMessageArray = Array<LocaleMessage>;
|
||||
declare type LocaleMessages = { [key: Locale]: LocaleMessageObject };
|
||||
|
||||
// This options is the same as Intl.DateTimeFormat constructor options:
|
||||
// http://www.ecma-international.org/ecma-402/2.0/#sec-intl-datetimeformat-constructor
|
||||
declare type DateTimeFormatOptions = {
|
||||
year?: 'numeric' | '2-digit',
|
||||
month?: 'numeric' | '2-digit' | 'narrow' | 'short' | 'long',
|
||||
day?: 'numeric' | '2-digit',
|
||||
hour?: 'numeric' | '2-digit',
|
||||
minute?: 'numeric' | '2-digit',
|
||||
second?: 'numeric' | '2-digit',
|
||||
weekday?: 'narrow' | 'short' | 'long',
|
||||
hour12?: boolean,
|
||||
era?: 'narrow' | 'short' | 'long',
|
||||
timeZone?: string, // IANA time zone
|
||||
timeZoneName?: 'short' | 'long',
|
||||
localeMatcher?: 'lookup' | 'best fit',
|
||||
formatMatcher?: 'basic' | 'best fit'
|
||||
};
|
||||
declare type DateTimeFormat = { [key: string]: DateTimeFormatOptions };
|
||||
declare type DateTimeFormats = { [key: Locale]: DateTimeFormat };
|
||||
|
||||
// This options is the same as Intl.NumberFormat constructor options:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
|
||||
declare type NumberFormatOptions = {
|
||||
style?: 'decimal' | 'currency' | 'percent',
|
||||
currency?: string, // ISO 4217 currency codes
|
||||
currencyDisplay?: 'symbol' | 'code' | 'name',
|
||||
useGrouping?: boolean,
|
||||
minimumIntegerDigits?: number,
|
||||
minimumFractionDigits?: number,
|
||||
maximumFractionDigits?: number,
|
||||
minimumSignificantDigits?: number,
|
||||
maximumSignificantDigits?: number,
|
||||
localeMatcher?: 'lookup' | 'best fit',
|
||||
formatMatcher?: 'basic' | 'best fit'
|
||||
};
|
||||
declare type NumberFormat = { [key: string]: NumberFormatOptions };
|
||||
declare type NumberFormats = { [key: Locale]: NumberFormat };
|
||||
declare type Modifiers = { [key: string]: (str: string) => string };
|
||||
|
||||
declare type TranslateResult = string | LocaleMessages;
|
||||
declare type DateTimeFormatResult = string;
|
||||
declare type NumberFormatResult = string;
|
||||
declare type MissingHandler = (locale: Locale, key: Path, vm?: any) => string | void;
|
||||
declare type PostTranslationHandler = (str: string, key?: string) => string;
|
||||
declare type GetChoiceIndex = (choice: number, choicesLength: number) => number
|
||||
declare type ComponentInstanceCreatedListener = (newI18n: I18n, rootI18n: I18n) => void;
|
||||
|
||||
declare type FormattedNumberPartType = 'currency' | 'decimal' | 'fraction' | 'group' | 'infinity' | 'integer' | 'literal' | 'minusSign' | 'nan' | 'plusSign' | 'percentSign';
|
||||
declare type FormattedNumberPart = {
|
||||
type: FormattedNumberPartType,
|
||||
value: string,
|
||||
};
|
||||
// This array is the same as Intl.NumberFormat.formatToParts() return value:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat/formatToParts#Return_value
|
||||
declare type NumberFormatToPartsResult = Array<FormattedNumberPart>;
|
||||
|
||||
declare type WarnHtmlInMessageLevel = 'off' | 'warn' | 'error';
|
||||
|
||||
declare type I18nOptions = {
|
||||
locale?: Locale,
|
||||
fallbackLocale?: FallbackLocale,
|
||||
messages?: LocaleMessages,
|
||||
dateTimeFormats?: DateTimeFormats,
|
||||
numberFormats?: NumberFormats,
|
||||
formatter?: Formatter,
|
||||
missing?: MissingHandler,
|
||||
modifiers?: Modifiers,
|
||||
root?: I18n, // for internal
|
||||
fallbackRoot?: boolean,
|
||||
formatFallbackMessages?: boolean,
|
||||
sync?: boolean,
|
||||
silentTranslationWarn?: boolean | RegExp,
|
||||
silentFallbackWarn?: boolean | RegExp,
|
||||
pluralizationRules?: PluralizationRules,
|
||||
preserveDirectiveContent?: boolean,
|
||||
warnHtmlInMessage?: WarnHtmlInMessageLevel,
|
||||
sharedMessages?: LocaleMessage,
|
||||
postTranslation?: PostTranslationHandler,
|
||||
componentInstanceCreatedListener?: ComponentInstanceCreatedListener,
|
||||
};
|
||||
|
||||
declare type IntlAvailability = {
|
||||
dateTimeFormat: boolean,
|
||||
numberFormat: boolean
|
||||
};
|
||||
|
||||
declare type PluralizationRules = {
|
||||
[lang: string]: GetChoiceIndex,
|
||||
}
|
||||
|
||||
declare interface I18n {
|
||||
static install: () => void, // for Vue plugin interface
|
||||
static version: string,
|
||||
static availabilities: IntlAvailability,
|
||||
get vm (): any, // for internal
|
||||
get locale (): Locale,
|
||||
set locale (locale: Locale): void,
|
||||
get fallbackLocale (): FallbackLocale,
|
||||
set fallbackLocale (locale: FallbackLocale): void,
|
||||
get messages (): LocaleMessages,
|
||||
get dateTimeFormats (): DateTimeFormats,
|
||||
get numberFormats (): NumberFormats,
|
||||
get availableLocales (): Locale[],
|
||||
get missing (): ?MissingHandler,
|
||||
set missing (handler: MissingHandler): void,
|
||||
get formatter (): Formatter,
|
||||
set formatter (formatter: Formatter): void,
|
||||
get formatFallbackMessages (): boolean,
|
||||
set formatFallbackMessages (fallback: boolean): void,
|
||||
get silentTranslationWarn (): boolean | RegExp,
|
||||
set silentTranslationWarn (silent: boolean | RegExp): void,
|
||||
get silentFallbackWarn (): boolean | RegExp,
|
||||
set silentFallbackWarn (slient: boolean | RegExp): void,
|
||||
get pluralizationRules (): PluralizationRules,
|
||||
set pluralizationRules (rules: PluralizationRules): void,
|
||||
get preserveDirectiveContent (): boolean,
|
||||
set preserveDirectiveContent (preserve: boolean): void,
|
||||
get warnHtmlInMessage (): WarnHtmlInMessageLevel,
|
||||
set warnHtmlInMessage (level: WarnHtmlInMessageLevel): void,
|
||||
get postTranslation (): ?PostTranslationHandler,
|
||||
set postTranslation (handler: PostTranslationHandler): void,
|
||||
|
||||
getLocaleMessage (locale: Locale): LocaleMessageObject,
|
||||
setLocaleMessage (locale: Locale, message: LocaleMessageObject): void,
|
||||
mergeLocaleMessage (locale: Locale, message: LocaleMessageObject): void,
|
||||
t (key: Path, ...values: any): TranslateResult,
|
||||
i (key: Path, locale: Locale, values: Object): TranslateResult,
|
||||
tc (key: Path, choice?: number, ...values: any): TranslateResult,
|
||||
te (key: Path, locale?: Locale): boolean,
|
||||
getDateTimeFormat (locale: Locale): DateTimeFormat,
|
||||
setDateTimeFormat (locale: Locale, format: DateTimeFormat): void,
|
||||
mergeDateTimeFormat (locale: Locale, format: DateTimeFormat): void,
|
||||
d (value: number | Date, ...args: any): DateTimeFormatResult,
|
||||
getNumberFormat (locale: Locale): NumberFormat,
|
||||
setNumberFormat (locale: Locale, format: NumberFormat): void,
|
||||
mergeNumberFormat (locale: Locale, format: NumberFormat): void,
|
||||
n (value: number, ...args: any): NumberFormatResult,
|
||||
getChoiceIndex: GetChoiceIndex,
|
||||
pluralizationRules: PluralizationRules,
|
||||
preserveDirectiveContent: boolean
|
||||
};
|
||||
|
||||
declare interface Formatter {
|
||||
interpolate (message: string, values: any, path: string): (Array<any> | null)
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
declare type $npm$Vue$Dictionaly<T> = { [key: string]: T }
|
||||
|
||||
declare type Util = {
|
||||
extend: (to: Object, from: ?Object) => Object,
|
||||
hasOwn: (obj: Object, key: string) => boolean,
|
||||
isPlainObject: (obj: any) => boolean,
|
||||
isObject: (obj: mixed) => boolean,
|
||||
}
|
||||
|
||||
declare type Config = {
|
||||
optionMergeStrategies: $npm$Vue$Dictionaly<Function>,
|
||||
silent: boolean,
|
||||
productionTip: boolean,
|
||||
performance: boolean,
|
||||
devtools: boolean,
|
||||
errorHandler: ?(err: Error, vm: Vue, info: string) => void,
|
||||
ignoredElements: Array<string>,
|
||||
keyCodes: $npm$Vue$Dictionaly<number>,
|
||||
isReservedTag: (x?: string) => boolean,
|
||||
parsePlatformTagName: (x: string) => string,
|
||||
isUnknownElement: (x?: string) => boolean,
|
||||
getTagNamespace: (x?: string) => string | void,
|
||||
mustUseProp: (tag: string, type: ?string, name: string) => boolean,
|
||||
}
|
||||
|
||||
declare interface Vue {
|
||||
static config: Config,
|
||||
static util: Util,
|
||||
static version: string,
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,176 @@
|
|||
{
|
||||
"_args": [
|
||||
[
|
||||
"vue-i18n@8.20.0",
|
||||
"C:\\Users\\Administrator\\Documents\\HBuilderProjects\\uView示例"
|
||||
]
|
||||
],
|
||||
"_from": "vue-i18n@8.20.0",
|
||||
"_id": "vue-i18n@8.20.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-ZiAOoeR4d/JtKpbjipx3I80ey7cYG1ki5gQ7HwzWm4YFio9brA15BEYHjalEoBaEfzF5OBEZP+Y2MvAaWnyXXg==",
|
||||
"_location": "/vue-i18n",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "vue-i18n@8.20.0",
|
||||
"name": "vue-i18n",
|
||||
"escapedName": "vue-i18n",
|
||||
"rawSpec": "8.20.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "8.20.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.20.0.tgz",
|
||||
"_spec": "8.20.0",
|
||||
"_where": "C:\\Users\\Administrator\\Documents\\HBuilderProjects\\uView示例",
|
||||
"author": {
|
||||
"name": "kazuya kawaguchi",
|
||||
"email": "kawakazu80@gmail.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/kazupon/vue-i18n/issues"
|
||||
},
|
||||
"changelog": {
|
||||
"labels": {
|
||||
"Type: Feature": ":star: New Features",
|
||||
"Type: Bug": ":bug: Bug Fixes",
|
||||
"Type: Security": ":lock: Security Fixes",
|
||||
"Type: Performance": ":chart_with_upwards_trend: Performance Fixes",
|
||||
"Type: Improvement": ":zap: Improved Features",
|
||||
"Type: Breaking": ":boom: Breaking Change",
|
||||
"Type: Deprecated": ":warning: Deprecated Features",
|
||||
"Type: I18n": ":globe_with_meridians: Internationalization",
|
||||
"Type: A11y": ":wheelchair: Accessibility",
|
||||
"Type: Documentation": ":pencil: Documentation"
|
||||
}
|
||||
},
|
||||
"description": "Internationalization plugin for Vue.js",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.1.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.1.0",
|
||||
"@babel/plugin-syntax-flow": "^7.0.0",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^3.0.0",
|
||||
"@typescript-eslint/parser": "^3.0.0",
|
||||
"@vue/babel-preset-app": "^4.4.1",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.1.0",
|
||||
"babel-plugin-istanbul": "^6.0.0",
|
||||
"babel-preset-power-assert": "^3.0.0",
|
||||
"buble": "^0.19.3",
|
||||
"chromedriver": "^83.0.0",
|
||||
"core-js": "^3.6.5",
|
||||
"cross-env": "^7.0.2",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-loader": "^4.0.2",
|
||||
"eslint-plugin-flowtype": "^4.7.0",
|
||||
"eslint-plugin-ie11": "^1.0.0",
|
||||
"eslint-plugin-no-autofix": "^1.0.1",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"eslint-plugin-vue-libs": "^4.0.0",
|
||||
"flow-bin": "^0.38.0",
|
||||
"http-server": "^0.12.3",
|
||||
"intl": "^1.2.5",
|
||||
"karma": "^5.0.9",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"karma-coverage": "^2.0.2",
|
||||
"karma-firefox-launcher": "^1.1.0",
|
||||
"karma-mocha": "^2.0.1",
|
||||
"karma-mocha-reporter": "^2.2.5",
|
||||
"karma-safari-launcher": "^1.0.0",
|
||||
"karma-sauce-launcher": "^4.1.5",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^4.0.2",
|
||||
"lerna-changelog": "^1.0.0",
|
||||
"lerna-changelog-label-schema": "^3.0.0",
|
||||
"mocha": "^7.2.0",
|
||||
"mocha-loader": "^5.0.0",
|
||||
"nightwatch": "^1.3.5",
|
||||
"nightwatch-helpers": "^1.2.0",
|
||||
"power-assert": "^1.6.0",
|
||||
"rollup": "^0.66.0",
|
||||
"rollup-plugin-buble": "^0.19.2",
|
||||
"rollup-plugin-commonjs": "^9.1.8",
|
||||
"rollup-plugin-flow-no-whitespace": "^1.0.0",
|
||||
"rollup-plugin-node-resolve": "^3.4.0",
|
||||
"rollup-plugin-replace": "^2.0.0",
|
||||
"selenium-server": "^3.141.59",
|
||||
"shipjs": "^0.17.0",
|
||||
"sinon": "^9.0.2",
|
||||
"terser": "^3.17.0",
|
||||
"typescript": "^3.9.3",
|
||||
"vue": "^2.5.17",
|
||||
"vue-github-button": "^1.1.2",
|
||||
"vue-template-compiler": "^2.5.17",
|
||||
"vuepress": "^1.5.0",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.1.1",
|
||||
"webpack-dev-middleware": "^3.7.2",
|
||||
"webpack-dev-server": "^3.11.0"
|
||||
},
|
||||
"files": [
|
||||
"dist/vue-i18n.js",
|
||||
"dist/vue-i18n.min.js",
|
||||
"dist/vue-i18n.common.js",
|
||||
"dist/vue-i18n.esm.js",
|
||||
"dist/vue-i18n.esm.browser.js",
|
||||
"dist/vue-i18n.esm.browser.min.js",
|
||||
"src/**/*.js",
|
||||
"types/*.d.ts",
|
||||
"decls",
|
||||
"vetur/tags.json",
|
||||
"vetur/attributes.json"
|
||||
],
|
||||
"homepage": "https://github.com/kazupon/vue-i18n#readme",
|
||||
"keywords": [
|
||||
"i18n",
|
||||
"internationalization",
|
||||
"plugin",
|
||||
"vue",
|
||||
"vue.js"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "dist/vue-i18n.common.js",
|
||||
"module": "dist/vue-i18n.esm.js",
|
||||
"name": "vue-i18n",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/kazupon/vue-i18n.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node config/build.js",
|
||||
"clean": "rm -rf coverage && rm -rf dist/*.js* && rm ./*.log",
|
||||
"coverage": "cat ./coverage/lcov.info",
|
||||
"dev": "cross-env BABEL_ENV=test webpack-dev-server --inline --hot --open --content-base ./test/unit/ --config config/webpack.dev.conf.js",
|
||||
"docs:build": "cross-env NODE_ENV=production node config/version.js && cross-env NODE_ENV=production vuepress build vuepress -d docs",
|
||||
"docs:clean": "rm -rf docs/**",
|
||||
"docs:dev": "vuepress dev vuepress",
|
||||
"flow": "flow check",
|
||||
"lint": "eslint --fix src test types/**/*.ts",
|
||||
"release:prepare": "shipjs prepare",
|
||||
"release:trigger": "shipjs trigger",
|
||||
"sauce": "npm run sauce:coolkids && npm run sauce:ie && npm run sauce:mobile",
|
||||
"sauce:coolkids": "karma start config/karma.sauce.conf.js -- 0",
|
||||
"sauce:ie": "karma start config/karma.sauce.conf.js -- 1",
|
||||
"sauce:mobile": "karma start config/karma.sauce.conf.js -- 2",
|
||||
"test": "npm run lint && npm run flow && npm run test:types && npm run test:cover && npm run test:e2e",
|
||||
"test:cover": "cross-env BABEL_ENV=test karma start config/karma.cover.conf.js",
|
||||
"test:e2e": "npm run build && node test/e2e/runner.js",
|
||||
"test:types": "tsc -p types",
|
||||
"test:unit": "cross-env BABEL_ENV=test karma start config/karma.unit.conf.js",
|
||||
"test:unit:ci": "cross-env BABEL_ENV=test karma start config/karma.unit.ci.conf.js"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"types": "types/index.d.ts",
|
||||
"unpkg": "dist/vue-i18n.js",
|
||||
"version": "8.20.0",
|
||||
"vetur": {
|
||||
"tags": "vetur/tags.json",
|
||||
"attributes": "vetur/attributes.json"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/* @flow */
|
||||
|
||||
import { warn } from '../util'
|
||||
|
||||
export default {
|
||||
name: 'i18n',
|
||||
functional: true,
|
||||
props: {
|
||||
tag: {
|
||||
type: [String, Boolean, Object],
|
||||
default: 'span'
|
||||
},
|
||||
path: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
locale: {
|
||||
type: String
|
||||
},
|
||||
places: {
|
||||
type: [Array, Object]
|
||||
}
|
||||
},
|
||||
render (h: Function, { data, parent, props, slots }: Object) {
|
||||
const { $i18n } = parent
|
||||
if (!$i18n) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn('Cannot find VueI18n instance!')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const { path, locale, places } = props
|
||||
const params = slots()
|
||||
const children = $i18n.i(
|
||||
path,
|
||||
locale,
|
||||
onlyHasDefaultPlace(params) || places
|
||||
? useLegacyPlaces(params.default, places)
|
||||
: params
|
||||
)
|
||||
|
||||
const tag = (!!props.tag && props.tag !== true) || props.tag === false ? props.tag : 'span'
|
||||
return tag ? h(tag, data, children) : children
|
||||
}
|
||||
}
|
||||
|
||||
function onlyHasDefaultPlace (params) {
|
||||
let prop
|
||||
for (prop in params) {
|
||||
if (prop !== 'default') { return false }
|
||||
}
|
||||
return Boolean(prop)
|
||||
}
|
||||
|
||||
function useLegacyPlaces (children, places) {
|
||||
const params = places ? createParamsFromPlaces(places) : {}
|
||||
|
||||
if (!children) { return params }
|
||||
|
||||
// Filter empty text nodes
|
||||
children = children.filter(child => {
|
||||
return child.tag || child.text.trim() !== ''
|
||||
})
|
||||
|
||||
const everyPlace = children.every(vnodeHasPlaceAttribute)
|
||||
if (process.env.NODE_ENV !== 'production' && everyPlace) {
|
||||
warn('`place` attribute is deprecated in next major version. Please switch to Vue slots.')
|
||||
}
|
||||
|
||||
return children.reduce(
|
||||
everyPlace ? assignChildPlace : assignChildIndex,
|
||||
params
|
||||
)
|
||||
}
|
||||
|
||||
function createParamsFromPlaces (places) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn('`places` prop is deprecated in next major version. Please switch to Vue slots.')
|
||||
}
|
||||
|
||||
return Array.isArray(places)
|
||||
? places.reduce(assignChildIndex, {})
|
||||
: Object.assign({}, places)
|
||||
}
|
||||
|
||||
function assignChildPlace (params, child) {
|
||||
if (child.data && child.data.attrs && child.data.attrs.place) {
|
||||
params[child.data.attrs.place] = child
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
function assignChildIndex (params, child, index) {
|
||||
params[index] = child
|
||||
return params
|
||||
}
|
||||
|
||||
function vnodeHasPlaceAttribute (vnode) {
|
||||
return Boolean(vnode.data && vnode.data.attrs && vnode.data.attrs.place)
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* @flow */
|
||||
|
||||
import { warn, isString, isObject, includes, numberFormatKeys } from '../util'
|
||||
|
||||
export default {
|
||||
name: 'i18n-n',
|
||||
functional: true,
|
||||
props: {
|
||||
tag: {
|
||||
type: [String, Boolean, Object],
|
||||
default: 'span'
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
format: {
|
||||
type: [String, Object]
|
||||
},
|
||||
locale: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
render (h: Function, { props, parent, data }: Object) {
|
||||
const i18n = parent.$i18n
|
||||
|
||||
if (!i18n) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn('Cannot find VueI18n instance!')
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
let key: ?string = null
|
||||
let options: ?NumberFormatOptions = null
|
||||
|
||||
if (isString(props.format)) {
|
||||
key = props.format
|
||||
} else if (isObject(props.format)) {
|
||||
if (props.format.key) {
|
||||
key = props.format.key
|
||||
}
|
||||
|
||||
// Filter out number format options only
|
||||
options = Object.keys(props.format).reduce((acc, prop) => {
|
||||
if (includes(numberFormatKeys, prop)) {
|
||||
return Object.assign({}, acc, { [prop]: props.format[prop] })
|
||||
}
|
||||
return acc
|
||||
}, null)
|
||||
}
|
||||
|
||||
const locale: Locale = props.locale || i18n.locale
|
||||
const parts: NumberFormatToPartsResult = i18n._ntp(props.value, locale, key, options)
|
||||
|
||||
const values = parts.map((part, index) => {
|
||||
const slot: ?Function = data.scopedSlots && data.scopedSlots[part.type]
|
||||
return slot ? slot({ [part.type]: part.value, index, parts }) : part.value
|
||||
})
|
||||
|
||||
const tag = (!!props.tag && props.tag !== true) || props.tag === false ? props.tag : 'span'
|
||||
return tag
|
||||
? h(tag, {
|
||||
attrs: data.attrs,
|
||||
'class': data['class'],
|
||||
staticClass: data.staticClass
|
||||
}, values)
|
||||
: values
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/* @flow */
|
||||
|
||||
import { warn, isString, isPlainObject, looseEqual } from './util'
|
||||
|
||||
export function bind (el: any, binding: Object, vnode: any): void {
|
||||
if (!assert(el, vnode)) { return }
|
||||
|
||||
t(el, binding, vnode)
|
||||
}
|
||||
|
||||
export function update (el: any, binding: Object, vnode: any, oldVNode: any): void {
|
||||
if (!assert(el, vnode)) { return }
|
||||
|
||||
const i18n: any = vnode.context.$i18n
|
||||
if (localeEqual(el, vnode) &&
|
||||
(looseEqual(binding.value, binding.oldValue) &&
|
||||
looseEqual(el._localeMessage, i18n.getLocaleMessage(i18n.locale)))) { return }
|
||||
|
||||
t(el, binding, vnode)
|
||||
}
|
||||
|
||||
export function unbind (el: any, binding: Object, vnode: any, oldVNode: any): void {
|
||||
const vm: any = vnode.context
|
||||
if (!vm) {
|
||||
warn('Vue instance does not exists in VNode context')
|
||||
return
|
||||
}
|
||||
|
||||
const i18n: any = vnode.context.$i18n || {}
|
||||
if (!binding.modifiers.preserve && !i18n.preserveDirectiveContent) {
|
||||
el.textContent = ''
|
||||
}
|
||||
el._vt = undefined
|
||||
delete el['_vt']
|
||||
el._locale = undefined
|
||||
delete el['_locale']
|
||||
el._localeMessage = undefined
|
||||
delete el['_localeMessage']
|
||||
}
|
||||
|
||||
function assert (el: any, vnode: any): boolean {
|
||||
const vm: any = vnode.context
|
||||
if (!vm) {
|
||||
warn('Vue instance does not exists in VNode context')
|
||||
return false
|
||||
}
|
||||
|
||||
if (!vm.$i18n) {
|
||||
warn('VueI18n instance does not exists in Vue instance')
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function localeEqual (el: any, vnode: any): boolean {
|
||||
const vm: any = vnode.context
|
||||
return el._locale === vm.$i18n.locale
|
||||
}
|
||||
|
||||
function t (el: any, binding: Object, vnode: any): void {
|
||||
const value: any = binding.value
|
||||
|
||||
const { path, locale, args, choice } = parseValue(value)
|
||||
if (!path && !locale && !args) {
|
||||
warn('value type not supported')
|
||||
return
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
warn('`path` is required in v-t directive')
|
||||
return
|
||||
}
|
||||
|
||||
const vm: any = vnode.context
|
||||
if (choice != null) {
|
||||
el._vt = el.textContent = vm.$i18n.tc(path, choice, ...makeParams(locale, args))
|
||||
} else {
|
||||
el._vt = el.textContent = vm.$i18n.t(path, ...makeParams(locale, args))
|
||||
}
|
||||
el._locale = vm.$i18n.locale
|
||||
el._localeMessage = vm.$i18n.getLocaleMessage(vm.$i18n.locale)
|
||||
}
|
||||
|
||||
function parseValue (value: any): Object {
|
||||
let path: ?string
|
||||
let locale: ?Locale
|
||||
let args: any
|
||||
let choice: ?number
|
||||
|
||||
if (isString(value)) {
|
||||
path = value
|
||||
} else if (isPlainObject(value)) {
|
||||
path = value.path
|
||||
locale = value.locale
|
||||
args = value.args
|
||||
choice = value.choice
|
||||
}
|
||||
|
||||
return { path, locale, args, choice }
|
||||
}
|
||||
|
||||
function makeParams (locale: Locale, args: any): Array<any> {
|
||||
const params: Array<any> = []
|
||||
|
||||
locale && params.push(locale)
|
||||
if (args && (Array.isArray(args) || isPlainObject(args))) {
|
||||
params.push(args)
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/* @flow */
|
||||
|
||||
export default function extend (Vue: any): void {
|
||||
if (!Vue.prototype.hasOwnProperty('$i18n')) {
|
||||
// $FlowFixMe
|
||||
Object.defineProperty(Vue.prototype, '$i18n', {
|
||||
get () { return this._i18n }
|
||||
})
|
||||
}
|
||||
|
||||
Vue.prototype.$t = function (key: Path, ...values: any): TranslateResult {
|
||||
const i18n = this.$i18n
|
||||
return i18n._t(key, i18n.locale, i18n._getMessages(), this, ...values)
|
||||
}
|
||||
|
||||
Vue.prototype.$tc = function (key: Path, choice?: number, ...values: any): TranslateResult {
|
||||
const i18n = this.$i18n
|
||||
return i18n._tc(key, i18n.locale, i18n._getMessages(), this, choice, ...values)
|
||||
}
|
||||
|
||||
Vue.prototype.$te = function (key: Path, locale?: Locale): boolean {
|
||||
const i18n = this.$i18n
|
||||
return i18n._te(key, i18n.locale, i18n._getMessages(), locale)
|
||||
}
|
||||
|
||||
Vue.prototype.$d = function (value: number | Date, ...args: any): DateTimeFormatResult {
|
||||
return this.$i18n.d(value, ...args)
|
||||
}
|
||||
|
||||
Vue.prototype.$n = function (value: number, ...args: any): NumberFormatResult {
|
||||
return this.$i18n.n(value, ...args)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/* @flow */
|
||||
|
||||
import { warn, isObject } from './util'
|
||||
|
||||
export default class BaseFormatter {
|
||||
_caches: { [key: string]: Array<Token> }
|
||||
|
||||
constructor () {
|
||||
this._caches = Object.create(null)
|
||||
}
|
||||
|
||||
interpolate (message: string, values: any): Array<any> {
|
||||
if (!values) {
|
||||
return [message]
|
||||
}
|
||||
let tokens: Array<Token> = this._caches[message]
|
||||
if (!tokens) {
|
||||
tokens = parse(message)
|
||||
this._caches[message] = tokens
|
||||
}
|
||||
return compile(tokens, values)
|
||||
}
|
||||
}
|
||||
|
||||
type Token = {
|
||||
type: 'text' | 'named' | 'list' | 'unknown',
|
||||
value: string
|
||||
}
|
||||
|
||||
const RE_TOKEN_LIST_VALUE: RegExp = /^(?:\d)+/
|
||||
const RE_TOKEN_NAMED_VALUE: RegExp = /^(?:\w)+/
|
||||
|
||||
export function parse (format: string): Array<Token> {
|
||||
const tokens: Array<Token> = []
|
||||
let position: number = 0
|
||||
|
||||
let text: string = ''
|
||||
while (position < format.length) {
|
||||
let char: string = format[position++]
|
||||
if (char === '{') {
|
||||
if (text) {
|
||||
tokens.push({ type: 'text', value: text })
|
||||
}
|
||||
|
||||
text = ''
|
||||
let sub: string = ''
|
||||
char = format[position++]
|
||||
while (char !== undefined && char !== '}') {
|
||||
sub += char
|
||||
char = format[position++]
|
||||
}
|
||||
const isClosed = char === '}'
|
||||
|
||||
const type = RE_TOKEN_LIST_VALUE.test(sub)
|
||||
? 'list'
|
||||
: isClosed && RE_TOKEN_NAMED_VALUE.test(sub)
|
||||
? 'named'
|
||||
: 'unknown'
|
||||
tokens.push({ value: sub, type })
|
||||
} else if (char === '%') {
|
||||
// when found rails i18n syntax, skip text capture
|
||||
if (format[(position)] !== '{') {
|
||||
text += char
|
||||
}
|
||||
} else {
|
||||
text += char
|
||||
}
|
||||
}
|
||||
|
||||
text && tokens.push({ type: 'text', value: text })
|
||||
|
||||
return tokens
|
||||
}
|
||||
|
||||
export function compile (tokens: Array<Token>, values: Object | Array<any>): Array<any> {
|
||||
const compiled: Array<any> = []
|
||||
let index: number = 0
|
||||
|
||||
const mode: string = Array.isArray(values)
|
||||
? 'list'
|
||||
: isObject(values)
|
||||
? 'named'
|
||||
: 'unknown'
|
||||
if (mode === 'unknown') { return compiled }
|
||||
|
||||
while (index < tokens.length) {
|
||||
const token: Token = tokens[index]
|
||||
switch (token.type) {
|
||||
case 'text':
|
||||
compiled.push(token.value)
|
||||
break
|
||||
case 'list':
|
||||
compiled.push(values[parseInt(token.value, 10)])
|
||||
break
|
||||
case 'named':
|
||||
if (mode === 'named') {
|
||||
compiled.push((values: any)[token.value])
|
||||
} else {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(`Type of token '${token.type}' and format of value '${mode}' don't match!`)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'unknown':
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(`Detect 'unknown' type of token!`)
|
||||
}
|
||||
break
|
||||
}
|
||||
index++
|
||||
}
|
||||
|
||||
return compiled
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,40 @@
|
|||
import { warn } from './util'
|
||||
import extend from './extend'
|
||||
import mixin from './mixin'
|
||||
import interpolationComponent from './components/interpolation'
|
||||
import numberComponent from './components/number'
|
||||
import { bind, update, unbind } from './directive'
|
||||
|
||||
export let Vue
|
||||
|
||||
export function install (_Vue) {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' && install.installed && _Vue === Vue) {
|
||||
warn('already installed.')
|
||||
return
|
||||
}
|
||||
install.installed = true
|
||||
|
||||
Vue = _Vue
|
||||
|
||||
const version = (Vue.version && Number(Vue.version.split('.')[0])) || -1
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' && version < 2) {
|
||||
warn(`vue-i18n (${install.version}) need to use Vue 2.0 or later (Vue: ${Vue.version}).`)
|
||||
return
|
||||
}
|
||||
|
||||
extend(Vue)
|
||||
Vue.mixin(mixin)
|
||||
Vue.directive('t', { bind, update, unbind })
|
||||
Vue.component(interpolationComponent.name, interpolationComponent)
|
||||
Vue.component(numberComponent.name, numberComponent)
|
||||
|
||||
// use simple mergeStrategies to prevent i18n instance lose '__proto__'
|
||||
const strats = Vue.config.optionMergeStrategies
|
||||
strats.i18n = function (parentVal, childVal) {
|
||||
return childVal === undefined
|
||||
? parentVal
|
||||
: childVal
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/* @flow */
|
||||
|
||||
import VueI18n from './index'
|
||||
import { isPlainObject, warn, error, merge } from './util'
|
||||
|
||||
export default {
|
||||
beforeCreate (): void {
|
||||
const options: any = this.$options
|
||||
options.i18n = options.i18n || (options.__i18n ? {} : null)
|
||||
|
||||
if (options.i18n) {
|
||||
if (options.i18n instanceof VueI18n) {
|
||||
// init locale messages via custom blocks
|
||||
if (options.__i18n) {
|
||||
try {
|
||||
let localeMessages = {}
|
||||
options.__i18n.forEach(resource => {
|
||||
localeMessages = merge(localeMessages, JSON.parse(resource))
|
||||
})
|
||||
Object.keys(localeMessages).forEach((locale: Locale) => {
|
||||
options.i18n.mergeLocaleMessage(locale, localeMessages[locale])
|
||||
})
|
||||
} catch (e) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
error(`Cannot parse locale messages via custom blocks.`, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
this._i18n = options.i18n
|
||||
this._i18nWatcher = this._i18n.watchI18nData()
|
||||
} else if (isPlainObject(options.i18n)) {
|
||||
const rootI18n = this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n
|
||||
? this.$root.$i18n
|
||||
: null
|
||||
// component local i18n
|
||||
if (rootI18n) {
|
||||
options.i18n.root = this.$root
|
||||
options.i18n.formatter = rootI18n.formatter
|
||||
options.i18n.fallbackLocale = rootI18n.fallbackLocale
|
||||
options.i18n.formatFallbackMessages = rootI18n.formatFallbackMessages
|
||||
options.i18n.silentTranslationWarn = rootI18n.silentTranslationWarn
|
||||
options.i18n.silentFallbackWarn = rootI18n.silentFallbackWarn
|
||||
options.i18n.pluralizationRules = rootI18n.pluralizationRules
|
||||
options.i18n.preserveDirectiveContent = rootI18n.preserveDirectiveContent
|
||||
}
|
||||
|
||||
// init locale messages via custom blocks
|
||||
if (options.__i18n) {
|
||||
try {
|
||||
let localeMessages = {}
|
||||
options.__i18n.forEach(resource => {
|
||||
localeMessages = merge(localeMessages, JSON.parse(resource))
|
||||
})
|
||||
options.i18n.messages = localeMessages
|
||||
} catch (e) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(`Cannot parse locale messages via custom blocks.`, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { sharedMessages } = options.i18n
|
||||
if (sharedMessages && isPlainObject(sharedMessages)) {
|
||||
options.i18n.messages = merge(options.i18n.messages, sharedMessages)
|
||||
}
|
||||
|
||||
this._i18n = new VueI18n(options.i18n)
|
||||
this._i18nWatcher = this._i18n.watchI18nData()
|
||||
|
||||
if (options.i18n.sync === undefined || !!options.i18n.sync) {
|
||||
this._localeWatcher = this.$i18n.watchLocale()
|
||||
}
|
||||
|
||||
if (rootI18n) {
|
||||
rootI18n.onComponentInstanceCreated(this._i18n)
|
||||
}
|
||||
} else {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(`Cannot be interpreted 'i18n' option.`)
|
||||
}
|
||||
}
|
||||
} else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
|
||||
// root i18n
|
||||
this._i18n = this.$root.$i18n
|
||||
} else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) {
|
||||
// parent i18n
|
||||
this._i18n = options.parent.$i18n
|
||||
}
|
||||
},
|
||||
|
||||
beforeMount (): void {
|
||||
const options: any = this.$options
|
||||
options.i18n = options.i18n || (options.__i18n ? {} : null)
|
||||
|
||||
if (options.i18n) {
|
||||
if (options.i18n instanceof VueI18n) {
|
||||
// init locale messages via custom blocks
|
||||
this._i18n.subscribeDataChanging(this)
|
||||
this._subscribing = true
|
||||
} else if (isPlainObject(options.i18n)) {
|
||||
this._i18n.subscribeDataChanging(this)
|
||||
this._subscribing = true
|
||||
} else {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(`Cannot be interpreted 'i18n' option.`)
|
||||
}
|
||||
}
|
||||
} else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
|
||||
this._i18n.subscribeDataChanging(this)
|
||||
this._subscribing = true
|
||||
} else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) {
|
||||
this._i18n.subscribeDataChanging(this)
|
||||
this._subscribing = true
|
||||
}
|
||||
},
|
||||
|
||||
beforeDestroy (): void {
|
||||
if (!this._i18n) { return }
|
||||
|
||||
const self = this
|
||||
this.$nextTick(() => {
|
||||
if (self._subscribing) {
|
||||
self._i18n.unsubscribeDataChanging(self)
|
||||
delete self._subscribing
|
||||
}
|
||||
|
||||
if (self._i18nWatcher) {
|
||||
self._i18nWatcher()
|
||||
self._i18n.destroyVM()
|
||||
delete self._i18nWatcher
|
||||
}
|
||||
|
||||
if (self._localeWatcher) {
|
||||
self._localeWatcher()
|
||||
delete self._localeWatcher
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
/* @flow */
|
||||
|
||||
import { isObject } from './util'
|
||||
|
||||
/**
|
||||
* Path parser
|
||||
* - Inspired:
|
||||
* Vue.js Path parser
|
||||
*/
|
||||
|
||||
// actions
|
||||
const APPEND = 0
|
||||
const PUSH = 1
|
||||
const INC_SUB_PATH_DEPTH = 2
|
||||
const PUSH_SUB_PATH = 3
|
||||
|
||||
// states
|
||||
const BEFORE_PATH = 0
|
||||
const IN_PATH = 1
|
||||
const BEFORE_IDENT = 2
|
||||
const IN_IDENT = 3
|
||||
const IN_SUB_PATH = 4
|
||||
const IN_SINGLE_QUOTE = 5
|
||||
const IN_DOUBLE_QUOTE = 6
|
||||
const AFTER_PATH = 7
|
||||
const ERROR = 8
|
||||
|
||||
const pathStateMachine: any = []
|
||||
|
||||
pathStateMachine[BEFORE_PATH] = {
|
||||
'ws': [BEFORE_PATH],
|
||||
'ident': [IN_IDENT, APPEND],
|
||||
'[': [IN_SUB_PATH],
|
||||
'eof': [AFTER_PATH]
|
||||
}
|
||||
|
||||
pathStateMachine[IN_PATH] = {
|
||||
'ws': [IN_PATH],
|
||||
'.': [BEFORE_IDENT],
|
||||
'[': [IN_SUB_PATH],
|
||||
'eof': [AFTER_PATH]
|
||||
}
|
||||
|
||||
pathStateMachine[BEFORE_IDENT] = {
|
||||
'ws': [BEFORE_IDENT],
|
||||
'ident': [IN_IDENT, APPEND],
|
||||
'0': [IN_IDENT, APPEND],
|
||||
'number': [IN_IDENT, APPEND]
|
||||
}
|
||||
|
||||
pathStateMachine[IN_IDENT] = {
|
||||
'ident': [IN_IDENT, APPEND],
|
||||
'0': [IN_IDENT, APPEND],
|
||||
'number': [IN_IDENT, APPEND],
|
||||
'ws': [IN_PATH, PUSH],
|
||||
'.': [BEFORE_IDENT, PUSH],
|
||||
'[': [IN_SUB_PATH, PUSH],
|
||||
'eof': [AFTER_PATH, PUSH]
|
||||
}
|
||||
|
||||
pathStateMachine[IN_SUB_PATH] = {
|
||||
"'": [IN_SINGLE_QUOTE, APPEND],
|
||||
'"': [IN_DOUBLE_QUOTE, APPEND],
|
||||
'[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
|
||||
']': [IN_PATH, PUSH_SUB_PATH],
|
||||
'eof': ERROR,
|
||||
'else': [IN_SUB_PATH, APPEND]
|
||||
}
|
||||
|
||||
pathStateMachine[IN_SINGLE_QUOTE] = {
|
||||
"'": [IN_SUB_PATH, APPEND],
|
||||
'eof': ERROR,
|
||||
'else': [IN_SINGLE_QUOTE, APPEND]
|
||||
}
|
||||
|
||||
pathStateMachine[IN_DOUBLE_QUOTE] = {
|
||||
'"': [IN_SUB_PATH, APPEND],
|
||||
'eof': ERROR,
|
||||
'else': [IN_DOUBLE_QUOTE, APPEND]
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an expression is a literal value.
|
||||
*/
|
||||
|
||||
const literalValueRE: RegExp = /^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/
|
||||
function isLiteral (exp: string): boolean {
|
||||
return literalValueRE.test(exp)
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip quotes from a string
|
||||
*/
|
||||
|
||||
function stripQuotes (str: string): string | boolean {
|
||||
const a: number = str.charCodeAt(0)
|
||||
const b: number = str.charCodeAt(str.length - 1)
|
||||
return a === b && (a === 0x22 || a === 0x27)
|
||||
? str.slice(1, -1)
|
||||
: str
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the type of a character in a keypath.
|
||||
*/
|
||||
|
||||
function getPathCharType (ch: ?string): string {
|
||||
if (ch === undefined || ch === null) { return 'eof' }
|
||||
|
||||
const code: number = ch.charCodeAt(0)
|
||||
|
||||
switch (code) {
|
||||
case 0x5B: // [
|
||||
case 0x5D: // ]
|
||||
case 0x2E: // .
|
||||
case 0x22: // "
|
||||
case 0x27: // '
|
||||
return ch
|
||||
|
||||
case 0x5F: // _
|
||||
case 0x24: // $
|
||||
case 0x2D: // -
|
||||
return 'ident'
|
||||
|
||||
case 0x09: // Tab
|
||||
case 0x0A: // Newline
|
||||
case 0x0D: // Return
|
||||
case 0xA0: // No-break space
|
||||
case 0xFEFF: // Byte Order Mark
|
||||
case 0x2028: // Line Separator
|
||||
case 0x2029: // Paragraph Separator
|
||||
return 'ws'
|
||||
}
|
||||
|
||||
return 'ident'
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a subPath, return its plain form if it is
|
||||
* a literal string or number. Otherwise prepend the
|
||||
* dynamic indicator (*).
|
||||
*/
|
||||
|
||||
function formatSubPath (path: string): boolean | string {
|
||||
const trimmed: string = path.trim()
|
||||
// invalid leading 0
|
||||
if (path.charAt(0) === '0' && isNaN(path)) { return false }
|
||||
|
||||
return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string path into an array of segments
|
||||
*/
|
||||
|
||||
function parse (path: Path): ?Array<string> {
|
||||
const keys: Array<string> = []
|
||||
let index: number = -1
|
||||
let mode: number = BEFORE_PATH
|
||||
let subPathDepth: number = 0
|
||||
let c: ?string
|
||||
let key: any
|
||||
let newChar: any
|
||||
let type: string
|
||||
let transition: number
|
||||
let action: Function
|
||||
let typeMap: any
|
||||
const actions: Array<Function> = []
|
||||
|
||||
actions[PUSH] = function () {
|
||||
if (key !== undefined) {
|
||||
keys.push(key)
|
||||
key = undefined
|
||||
}
|
||||
}
|
||||
|
||||
actions[APPEND] = function () {
|
||||
if (key === undefined) {
|
||||
key = newChar
|
||||
} else {
|
||||
key += newChar
|
||||
}
|
||||
}
|
||||
|
||||
actions[INC_SUB_PATH_DEPTH] = function () {
|
||||
actions[APPEND]()
|
||||
subPathDepth++
|
||||
}
|
||||
|
||||
actions[PUSH_SUB_PATH] = function () {
|
||||
if (subPathDepth > 0) {
|
||||
subPathDepth--
|
||||
mode = IN_SUB_PATH
|
||||
actions[APPEND]()
|
||||
} else {
|
||||
subPathDepth = 0
|
||||
if (key === undefined) { return false }
|
||||
key = formatSubPath(key)
|
||||
if (key === false) {
|
||||
return false
|
||||
} else {
|
||||
actions[PUSH]()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function maybeUnescapeQuote (): ?boolean {
|
||||
const nextChar: string = path[index + 1]
|
||||
if ((mode === IN_SINGLE_QUOTE && nextChar === "'") ||
|
||||
(mode === IN_DOUBLE_QUOTE && nextChar === '"')) {
|
||||
index++
|
||||
newChar = '\\' + nextChar
|
||||
actions[APPEND]()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
while (mode !== null) {
|
||||
index++
|
||||
c = path[index]
|
||||
|
||||
if (c === '\\' && maybeUnescapeQuote()) {
|
||||
continue
|
||||
}
|
||||
|
||||
type = getPathCharType(c)
|
||||
typeMap = pathStateMachine[mode]
|
||||
transition = typeMap[type] || typeMap['else'] || ERROR
|
||||
|
||||
if (transition === ERROR) {
|
||||
return // parse error
|
||||
}
|
||||
|
||||
mode = transition[0]
|
||||
action = actions[transition[1]]
|
||||
if (action) {
|
||||
newChar = transition[2]
|
||||
newChar = newChar === undefined
|
||||
? c
|
||||
: newChar
|
||||
if (action() === false) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (mode === AFTER_PATH) {
|
||||
return keys
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type PathValue = PathValueObject | PathValueArray | string | number | boolean | null
|
||||
export type PathValueObject = { [key: string]: PathValue }
|
||||
export type PathValueArray = Array<PathValue>
|
||||
|
||||
export default class I18nPath {
|
||||
_cache: Object
|
||||
|
||||
constructor () {
|
||||
this._cache = Object.create(null)
|
||||
}
|
||||
|
||||
/**
|
||||
* External parse that check for a cache hit first
|
||||
*/
|
||||
parsePath (path: Path): Array<string> {
|
||||
let hit: ?Array<string> = this._cache[path]
|
||||
if (!hit) {
|
||||
hit = parse(path)
|
||||
if (hit) {
|
||||
this._cache[path] = hit
|
||||
}
|
||||
}
|
||||
return hit || []
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path value from path string
|
||||
*/
|
||||
getPathValue (obj: mixed, path: Path): PathValue {
|
||||
if (!isObject(obj)) { return null }
|
||||
|
||||
const paths: Array<string> = this.parsePath(path)
|
||||
if (paths.length === 0) {
|
||||
return null
|
||||
} else {
|
||||
const length: number = paths.length
|
||||
let last: any = obj
|
||||
let i: number = 0
|
||||
while (i < length) {
|
||||
const value: any = last[paths[i]]
|
||||
if (value === undefined) {
|
||||
return null
|
||||
}
|
||||
last = value
|
||||
i++
|
||||
}
|
||||
|
||||
return last
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
/* @flow */
|
||||
|
||||
/**
|
||||
* constants
|
||||
*/
|
||||
|
||||
export const numberFormatKeys = [
|
||||
'style',
|
||||
'currency',
|
||||
'currencyDisplay',
|
||||
'useGrouping',
|
||||
'minimumIntegerDigits',
|
||||
'minimumFractionDigits',
|
||||
'maximumFractionDigits',
|
||||
'minimumSignificantDigits',
|
||||
'maximumSignificantDigits',
|
||||
'localeMatcher',
|
||||
'formatMatcher',
|
||||
'unit'
|
||||
]
|
||||
|
||||
/**
|
||||
* utilities
|
||||
*/
|
||||
|
||||
export function warn (msg: string, err: ?Error): void {
|
||||
if (typeof console !== 'undefined') {
|
||||
console.warn('[vue-i18n] ' + msg)
|
||||
/* istanbul ignore if */
|
||||
if (err) {
|
||||
console.warn(err.stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function error (msg: string, err: ?Error): void {
|
||||
if (typeof console !== 'undefined') {
|
||||
console.error('[vue-i18n] ' + msg)
|
||||
/* istanbul ignore if */
|
||||
if (err) {
|
||||
console.error(err.stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const isArray = Array.isArray
|
||||
|
||||
export function isObject (obj: mixed): boolean %checks {
|
||||
return obj !== null && typeof obj === 'object'
|
||||
}
|
||||
|
||||
export function isBoolean (val: mixed): boolean %checks {
|
||||
return typeof val === 'boolean'
|
||||
}
|
||||
|
||||
export function isString (val: mixed): boolean %checks {
|
||||
return typeof val === 'string'
|
||||
}
|
||||
|
||||
const toString: Function = Object.prototype.toString
|
||||
const OBJECT_STRING: string = '[object Object]'
|
||||
export function isPlainObject (obj: any): boolean {
|
||||
return toString.call(obj) === OBJECT_STRING
|
||||
}
|
||||
|
||||
export function isNull (val: mixed): boolean {
|
||||
return val === null || val === undefined
|
||||
}
|
||||
|
||||
export function parseArgs (...args: Array<mixed>): Object {
|
||||
let locale: ?string = null
|
||||
let params: mixed = null
|
||||
if (args.length === 1) {
|
||||
if (isObject(args[0]) || Array.isArray(args[0])) {
|
||||
params = args[0]
|
||||
} else if (typeof args[0] === 'string') {
|
||||
locale = args[0]
|
||||
}
|
||||
} else if (args.length === 2) {
|
||||
if (typeof args[0] === 'string') {
|
||||
locale = args[0]
|
||||
}
|
||||
/* istanbul ignore if */
|
||||
if (isObject(args[1]) || Array.isArray(args[1])) {
|
||||
params = args[1]
|
||||
}
|
||||
}
|
||||
|
||||
return { locale, params }
|
||||
}
|
||||
|
||||
export function looseClone (obj: Object): Object {
|
||||
return JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
|
||||
export function remove (arr: Array<any>, item: any): Array<any> | void {
|
||||
if (arr.length) {
|
||||
const index = arr.indexOf(item)
|
||||
if (index > -1) {
|
||||
return arr.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function includes (arr: Array<any>, item: any): boolean {
|
||||
return !!~arr.indexOf(item)
|
||||
}
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
export function hasOwn (obj: Object | Array<*>, key: string): boolean {
|
||||
return hasOwnProperty.call(obj, key)
|
||||
}
|
||||
|
||||
export function merge (target: Object): Object {
|
||||
const output = Object(target)
|
||||
for (let i = 1; i < arguments.length; i++) {
|
||||
const source = arguments[i]
|
||||
if (source !== undefined && source !== null) {
|
||||
let key
|
||||
for (key in source) {
|
||||
if (hasOwn(source, key)) {
|
||||
if (isObject(source[key])) {
|
||||
output[key] = merge(output[key], source[key])
|
||||
} else {
|
||||
output[key] = source[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
export function looseEqual (a: any, b: any): boolean {
|
||||
if (a === b) { return true }
|
||||
const isObjectA: boolean = isObject(a)
|
||||
const isObjectB: boolean = isObject(b)
|
||||
if (isObjectA && isObjectB) {
|
||||
try {
|
||||
const isArrayA: boolean = Array.isArray(a)
|
||||
const isArrayB: boolean = Array.isArray(b)
|
||||
if (isArrayA && isArrayB) {
|
||||
return a.length === b.length && a.every((e: any, i: number): boolean => {
|
||||
return looseEqual(e, b[i])
|
||||
})
|
||||
} else if (!isArrayA && !isArrayB) {
|
||||
const keysA: Array<string> = Object.keys(a)
|
||||
const keysB: Array<string> = Object.keys(b)
|
||||
return keysA.length === keysB.length && keysA.every((key: string): boolean => {
|
||||
return looseEqual(a[key], b[key])
|
||||
})
|
||||
} else {
|
||||
/* istanbul ignore next */
|
||||
return false
|
||||
}
|
||||
} catch (e) {
|
||||
/* istanbul ignore next */
|
||||
return false
|
||||
}
|
||||
} else if (!isObjectA && !isObjectB) {
|
||||
return String(a) === String(b)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
import Vue, { PluginFunction } from 'vue';
|
||||
|
||||
declare namespace VueI18n {
|
||||
type Path = string;
|
||||
type Locale = string;
|
||||
type FallbackLocale = string | string[] | false | { [locale: string]: string[] }
|
||||
type Values = any[] | { [key: string]: any };
|
||||
type Choice = number;
|
||||
type LocaleMessage = string | LocaleMessageObject | LocaleMessageArray;
|
||||
interface LocaleMessageObject { [key: string]: LocaleMessage; }
|
||||
interface LocaleMessageArray { [index: number]: LocaleMessage; }
|
||||
interface LocaleMessages { [key: string]: LocaleMessageObject; }
|
||||
type TranslateResult = string | LocaleMessages;
|
||||
|
||||
type LocaleMatcher = 'lookup' | 'best-fit';
|
||||
type FormatMatcher = 'basic' | 'best-fit';
|
||||
|
||||
type DateTimeHumanReadable = 'long' | 'short' | 'narrow';
|
||||
type DateTimeDigital = 'numeric' | '2-digit';
|
||||
|
||||
interface SpecificDateTimeFormatOptions extends Intl.DateTimeFormatOptions {
|
||||
year?: DateTimeDigital;
|
||||
month?: DateTimeDigital | DateTimeHumanReadable;
|
||||
day?: DateTimeDigital;
|
||||
hour?: DateTimeDigital;
|
||||
minute?: DateTimeDigital;
|
||||
second?: DateTimeDigital;
|
||||
weekday?: DateTimeHumanReadable;
|
||||
era?: DateTimeHumanReadable;
|
||||
timeZoneName?: 'long' | 'short';
|
||||
localeMatcher?: LocaleMatcher;
|
||||
formatMatcher?: FormatMatcher;
|
||||
}
|
||||
|
||||
type DateTimeFormatOptions = Intl.DateTimeFormatOptions | SpecificDateTimeFormatOptions;
|
||||
|
||||
interface DateTimeFormat { [key: string]: DateTimeFormatOptions; }
|
||||
interface DateTimeFormats { [locale: string]: DateTimeFormat; }
|
||||
type DateTimeFormatResult = string;
|
||||
|
||||
type CurrencyDisplay = 'symbol' | 'code' | 'name';
|
||||
|
||||
interface SpecificNumberFormatOptions extends Intl.NumberFormatOptions {
|
||||
style?: 'decimal' | 'percent';
|
||||
currency?: string;
|
||||
currencyDisplay?: CurrencyDisplay;
|
||||
localeMatcher?: LocaleMatcher;
|
||||
formatMatcher?: FormatMatcher;
|
||||
}
|
||||
|
||||
interface CurrencyNumberFormatOptions extends Intl.NumberFormatOptions {
|
||||
style: 'currency';
|
||||
currency: string; // Obligatory if style is 'currency'
|
||||
currencyDisplay?: CurrencyDisplay;
|
||||
localeMatcher?: LocaleMatcher;
|
||||
formatMatcher?: FormatMatcher;
|
||||
}
|
||||
|
||||
type NumberFormatOptions = Intl.NumberFormatOptions | SpecificNumberFormatOptions | CurrencyNumberFormatOptions;
|
||||
|
||||
interface NumberFormat { [key: string]: NumberFormatOptions; }
|
||||
interface NumberFormats { [locale: string]: NumberFormat; }
|
||||
type NumberFormatResult = string;
|
||||
type PluralizationRulesMap = {
|
||||
/**
|
||||
* @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
|
||||
* @param choicesLength {number} an overall amount of available choices
|
||||
* @returns a final choice index
|
||||
*/
|
||||
[lang: string]: (choice: number, choicesLength: number) => number;
|
||||
};
|
||||
type Modifiers = { [key: string]: (str : string) => string };
|
||||
|
||||
type FormattedNumberPartType = 'currency' | 'decimal' | 'fraction' | 'group' | 'infinity' | 'integer' | 'literal' | 'minusSign' | 'nan' | 'plusSign' | 'percentSign';
|
||||
|
||||
type WarnHtmlInMessageLevel = 'off' | 'warn' | 'error';
|
||||
|
||||
interface FormattedNumberPart {
|
||||
type: FormattedNumberPartType;
|
||||
value: string;
|
||||
}
|
||||
interface NumberFormatToPartsResult { [index: number]: FormattedNumberPart; }
|
||||
|
||||
interface Formatter {
|
||||
interpolate(message: string, values: Values | undefined, path: string): (any[] | null);
|
||||
}
|
||||
|
||||
type MissingHandler = (locale: Locale, key: Path, vm: Vue | null, values: any) => string | void;
|
||||
type PostTranslationHandler = (str: string, key?: string) => string;
|
||||
type ComponentInstanceCreatedListener = (newVm: VueI18n & IVueI18n, rootVm: VueI18n & IVueI18n) => void;
|
||||
|
||||
interface IntlAvailability {
|
||||
dateTimeFormat: boolean;
|
||||
numberFormat: boolean;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:interface-name
|
||||
interface I18nOptions {
|
||||
locale?: Locale;
|
||||
fallbackLocale?: FallbackLocale;
|
||||
messages?: LocaleMessages;
|
||||
dateTimeFormats?: DateTimeFormats;
|
||||
numberFormats?: NumberFormats;
|
||||
formatter?: Formatter;
|
||||
modifiers?: Modifiers,
|
||||
missing?: MissingHandler;
|
||||
fallbackRoot?: boolean;
|
||||
formatFallbackMessages?: boolean;
|
||||
sync?: boolean;
|
||||
silentTranslationWarn?: boolean | RegExp;
|
||||
silentFallbackWarn?: boolean | RegExp;
|
||||
preserveDirectiveContent?: boolean;
|
||||
pluralizationRules?: PluralizationRulesMap;
|
||||
warnHtmlInMessage?: WarnHtmlInMessageLevel;
|
||||
sharedMessages?: LocaleMessages;
|
||||
postTranslation?: PostTranslationHandler;
|
||||
componentInstanceCreatedListener?: ComponentInstanceCreatedListener;
|
||||
}
|
||||
}
|
||||
|
||||
export type Path = VueI18n.Path;
|
||||
export type Locale = VueI18n.Locale;
|
||||
export type FallbackLocale = VueI18n.FallbackLocale;
|
||||
export type Values = VueI18n.Values;
|
||||
export type Choice = VueI18n.Choice;
|
||||
export type LocaleMessage = VueI18n.LocaleMessage;
|
||||
export type LocaleMessageObject = VueI18n.LocaleMessageObject;
|
||||
export type LocaleMessageArray = VueI18n.LocaleMessageArray;
|
||||
export type LocaleMessages = VueI18n.LocaleMessages;
|
||||
export type TranslateResult = VueI18n.TranslateResult;
|
||||
export type DateTimeFormatOptions = VueI18n.DateTimeFormatOptions;
|
||||
export type DateTimeFormat = VueI18n.DateTimeFormat;
|
||||
export type DateTimeFormats = VueI18n.DateTimeFormats;
|
||||
export type DateTimeFormatResult = VueI18n.DateTimeFormatResult;
|
||||
export type NumberFormatOptions = VueI18n.NumberFormatOptions;
|
||||
export type NumberFormat = VueI18n.NumberFormat;
|
||||
export type NumberFormats = VueI18n.NumberFormats;
|
||||
export type NumberFormatResult = VueI18n.NumberFormatResult;
|
||||
export type NumberFormatToPartsResult = VueI18n.NumberFormatToPartsResult;
|
||||
export type WarnHtmlInMessageLevel = VueI18n.WarnHtmlInMessageLevel;
|
||||
export type Formatter = VueI18n.Formatter;
|
||||
export type MissingHandler = VueI18n.MissingHandler;
|
||||
export type PostTranslationHandler = VueI18n.PostTranslationHandler;
|
||||
export type IntlAvailability = VueI18n.IntlAvailability;
|
||||
export type I18nOptions = VueI18n.I18nOptions;
|
||||
|
||||
export declare interface IVueI18n {
|
||||
readonly messages: VueI18n.LocaleMessages;
|
||||
readonly dateTimeFormats: VueI18n.DateTimeFormats;
|
||||
readonly numberFormats: VueI18n.NumberFormats;
|
||||
|
||||
locale: VueI18n.Locale;
|
||||
fallbackLocale: VueI18n.FallbackLocale;
|
||||
missing: VueI18n.MissingHandler;
|
||||
formatter: VueI18n.Formatter;
|
||||
formatFallbackMessages: boolean;
|
||||
silentTranslationWarn: boolean | RegExp;
|
||||
silentFallbackWarn: boolean | RegExp;
|
||||
preserveDirectiveContent: boolean;
|
||||
pluralizationRules: VueI18n.PluralizationRulesMap;
|
||||
warnHtmlInMessage: VueI18n.WarnHtmlInMessageLevel;
|
||||
postTranslation: VueI18n.PostTranslationHandler;
|
||||
t(key: VueI18n.Path, values?: VueI18n.Values): VueI18n.TranslateResult;
|
||||
t(key: VueI18n.Path, locale: VueI18n.Locale, values?: VueI18n.Values): VueI18n.TranslateResult;
|
||||
tc(key: VueI18n.Path, choice?: VueI18n.Choice, values?: VueI18n.Values): string;
|
||||
tc(
|
||||
key: VueI18n.Path,
|
||||
choice: VueI18n.Choice,
|
||||
locale: VueI18n.Locale,
|
||||
values?: VueI18n.Values,
|
||||
): string;
|
||||
te(key: VueI18n.Path, locale?: VueI18n.Locale): boolean;
|
||||
d(
|
||||
value: number | Date,
|
||||
key?: VueI18n.Path,
|
||||
locale?: VueI18n.Locale,
|
||||
): VueI18n.DateTimeFormatResult;
|
||||
d(value: number | Date, args?: { [key: string]: string }): VueI18n.DateTimeFormatResult;
|
||||
n(value: number, key?: VueI18n.Path, locale?: VueI18n.Locale): VueI18n.NumberFormatResult;
|
||||
n(value: number, args?: { [key: string]: string }): VueI18n.NumberFormatResult;
|
||||
getLocaleMessage(locale: VueI18n.Locale): VueI18n.LocaleMessageObject;
|
||||
setLocaleMessage(locale: VueI18n.Locale, message: VueI18n.LocaleMessageObject): void;
|
||||
mergeLocaleMessage(locale: VueI18n.Locale, message: VueI18n.LocaleMessageObject): void;
|
||||
getDateTimeFormat(locale: VueI18n.Locale): VueI18n.DateTimeFormat;
|
||||
setDateTimeFormat(locale: VueI18n.Locale, format: VueI18n.DateTimeFormat): void;
|
||||
mergeDateTimeFormat(locale: VueI18n.Locale, format: VueI18n.DateTimeFormat): void;
|
||||
getNumberFormat(locale: VueI18n.Locale): VueI18n.NumberFormat;
|
||||
setNumberFormat(locale: VueI18n.Locale, format: VueI18n.NumberFormat): void;
|
||||
mergeNumberFormat(locale: VueI18n.Locale, format: VueI18n.NumberFormat): void;
|
||||
getChoiceIndex: (choice: number, choicesLength: number) => number;
|
||||
}
|
||||
|
||||
declare class VueI18n {
|
||||
constructor(options?: VueI18n.I18nOptions)
|
||||
|
||||
readonly messages: VueI18n.LocaleMessages;
|
||||
readonly dateTimeFormats: VueI18n.DateTimeFormats;
|
||||
readonly numberFormats: VueI18n.NumberFormats;
|
||||
readonly availableLocales: VueI18n.Locale[];
|
||||
|
||||
locale: VueI18n.Locale;
|
||||
fallbackLocale: VueI18n.FallbackLocale;
|
||||
missing: VueI18n.MissingHandler;
|
||||
formatter: VueI18n.Formatter;
|
||||
formatFallbackMessages: boolean;
|
||||
silentTranslationWarn: boolean | RegExp;
|
||||
silentFallbackWarn: boolean | RegExp;
|
||||
preserveDirectiveContent: boolean;
|
||||
pluralizationRules: VueI18n.PluralizationRulesMap;
|
||||
warnHtmlInMessage: VueI18n.WarnHtmlInMessageLevel;
|
||||
postTranslation: VueI18n.PostTranslationHandler;
|
||||
|
||||
t(key: VueI18n.Path, values?: VueI18n.Values): VueI18n.TranslateResult;
|
||||
t(key: VueI18n.Path, locale: VueI18n.Locale, values?: VueI18n.Values): VueI18n.TranslateResult;
|
||||
tc(key: VueI18n.Path, choice?: VueI18n.Choice, values?: VueI18n.Values): string;
|
||||
tc(key: VueI18n.Path, choice: VueI18n.Choice, locale: VueI18n.Locale, values?: VueI18n.Values): string;
|
||||
te(key: VueI18n.Path, locale?: VueI18n.Locale): boolean;
|
||||
d(value: number | Date, key?: VueI18n.Path, locale?: VueI18n.Locale): VueI18n.DateTimeFormatResult;
|
||||
d(value: number | Date, args?: { [key: string]: string }): VueI18n.DateTimeFormatResult;
|
||||
n(value: number, key?: VueI18n.Path, locale?: VueI18n.Locale): VueI18n.NumberFormatResult;
|
||||
n(value: number, args?: { [key: string]: string }): VueI18n.NumberFormatResult;
|
||||
|
||||
getLocaleMessage(locale: VueI18n.Locale): VueI18n.LocaleMessageObject;
|
||||
setLocaleMessage(locale: VueI18n.Locale, message: VueI18n.LocaleMessageObject): void;
|
||||
mergeLocaleMessage(locale: VueI18n.Locale, message: VueI18n.LocaleMessageObject): void;
|
||||
|
||||
getDateTimeFormat(locale: VueI18n.Locale): VueI18n.DateTimeFormat;
|
||||
setDateTimeFormat(locale: VueI18n.Locale, format: VueI18n.DateTimeFormat): void;
|
||||
mergeDateTimeFormat(locale: VueI18n.Locale, format: VueI18n.DateTimeFormat): void;
|
||||
|
||||
getNumberFormat(locale: VueI18n.Locale): VueI18n.NumberFormat;
|
||||
setNumberFormat(locale: VueI18n.Locale, format: VueI18n.NumberFormat): void;
|
||||
mergeNumberFormat(locale: VueI18n.Locale, format: VueI18n.NumberFormat): void;
|
||||
|
||||
/**
|
||||
* @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
|
||||
* @param choicesLength {number} an overall amount of available choices
|
||||
* @returns a final choice index
|
||||
*/
|
||||
getChoiceIndex: (choice: number, choicesLength: number) => number;
|
||||
|
||||
static install: PluginFunction<never>;
|
||||
static version: string;
|
||||
static availabilities: VueI18n.IntlAvailability;
|
||||
}
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
readonly $i18n: VueI18n & IVueI18n;
|
||||
$t: typeof VueI18n.prototype.t;
|
||||
$tc: typeof VueI18n.prototype.tc;
|
||||
$te: typeof VueI18n.prototype.te;
|
||||
$d: typeof VueI18n.prototype.d;
|
||||
$n: typeof VueI18n.prototype.n;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'vue/types/options' {
|
||||
interface ComponentOptions<V extends Vue> {
|
||||
i18n?: {
|
||||
messages?: VueI18n.LocaleMessages;
|
||||
dateTimeFormats?: VueI18n.DateTimeFormats;
|
||||
numberFormats?: VueI18n.NumberFormats;
|
||||
sharedMessages?: VueI18n.LocaleMessages;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default VueI18n;
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"i18n/path" : {
|
||||
"description": "[required]\nKeypath of the locale message",
|
||||
"type": "string"
|
||||
},
|
||||
"i18n/locale" : {
|
||||
"description": "[optional]\nLocale to be used in this translation",
|
||||
"type": "string"
|
||||
},
|
||||
"i18n/tag" : {
|
||||
"description": "[optional]\nWhich tag to render, default is \"span\"",
|
||||
"type": "string"
|
||||
},
|
||||
"i18n/places": {
|
||||
"description": "[optional after v8.14]\nWill be removed in the next major version, use the slot syntax instead\n\nhttp://kazupon.github.io/vue-i18n/guide/interpolation.html#slots-syntax-usage",
|
||||
"type": "array|object"
|
||||
},
|
||||
"i18n-n/value" : {
|
||||
"description": "[required]\nNumber to be used in formatting",
|
||||
"type": "number"
|
||||
},
|
||||
"i18n-n/format": {
|
||||
"description": "[optional]\nNumber format name or object with explicit format options",
|
||||
"type": "string|object"
|
||||
},
|
||||
"i18n-n/locale" : {
|
||||
"description": "[optional]\nLocale to be used in this translation",
|
||||
"type": "string"
|
||||
},
|
||||
"i18n-n/tag" : {
|
||||
"description": "[optional]\nWhich tag to render, default is `span`",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"i18n": {
|
||||
"attributes": [
|
||||
"path",
|
||||
"locale",
|
||||
"tag",
|
||||
"places"
|
||||
],
|
||||
"description": "This is a functional component that can be used when HTML interpolation is needed.\n\nhttp://kazupon.github.io/vue-i18n/guide/interpolation.html#basic-usage"
|
||||
},
|
||||
"i18n-n": {
|
||||
"attributes": [
|
||||
"value",
|
||||
"format",
|
||||
"locale",
|
||||
"tag"
|
||||
],
|
||||
"description": "This functional component provides a way to use HTML interpolation in pair with number formatting.\n\nhttp://kazupon.github.io/vue-i18n/guide/number.html#custom-formatting"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 LancerComet
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
# Vue-jsonp
|
||||
|
||||
[](https://github.com/LancerComet/vue-jsonp/actions)
|
||||
|
||||
A tiny library for handling JSONP request.
|
||||
|
||||
## Quick Start
|
||||
|
||||
As Vue plugin:
|
||||
|
||||
```ts
|
||||
import { VueJsonp } from 'vue-jsonp'
|
||||
|
||||
// Vue Plugin.
|
||||
Vue.use(VueJsonp)
|
||||
|
||||
// Now you can use this.$jsonp in Vue components.
|
||||
const vm = new Vue()
|
||||
vm.$jsonp('/some-jsonp-url', {
|
||||
myCustomUrlParam: 'veryNice'
|
||||
})
|
||||
```
|
||||
|
||||
Use function directly:
|
||||
|
||||
```ts
|
||||
import { jsonp } from 'vue-jsonp'
|
||||
|
||||
jsonp('/some-jsonp-url', {
|
||||
myCustomUrlParam: 'veryNice'
|
||||
})
|
||||
```
|
||||
|
||||
## Send data and set query & function name
|
||||
|
||||
### Send data
|
||||
|
||||
```ts
|
||||
// The request url will be "/some-jsonp-url?name=LancerComet&age=100&callback=jsonp_{RANDOM_STR}".
|
||||
jsonp('/some-jsonp-url', {
|
||||
name: 'LancerComet',
|
||||
age: 100
|
||||
})
|
||||
```
|
||||
|
||||
### Custom query & function name
|
||||
|
||||
The url uniform is `/url?{callbackQuery}={callbackName}&...`, the default is `/url?callback=jsonp_{RANDOM_STRING}&...`.
|
||||
|
||||
And you can change it like this:
|
||||
|
||||
```ts
|
||||
// The request url will be "/some-jsonp-url?name=LancerComet&age=100&cb=jsonp_func".
|
||||
jsonp('/some-jsonp-url', {
|
||||
callbackQuery: 'cb',
|
||||
callbackName: 'jsonp_func',
|
||||
name: 'LancerComet',
|
||||
age: 100
|
||||
})
|
||||
```
|
||||
|
||||
## Module exports
|
||||
|
||||
- `VueJsonp: PluginObject<never>`
|
||||
|
||||
- `jsonp<T>: (url: string, param?: IJsonpParam, timeout?: number) => Promise<T>`
|
||||
|
||||
## API
|
||||
|
||||
### IJsonpParam
|
||||
|
||||
IJsonpParam is the type of param for jsonp function.
|
||||
|
||||
```ts
|
||||
/**
|
||||
* JSONP parameter declaration.
|
||||
*/
|
||||
interface IJsonpParam {
|
||||
/**
|
||||
* Callback query name.
|
||||
* This param is used to define the query name of the callback function.
|
||||
*
|
||||
* @example
|
||||
* // The request url will be "/some-url?myCallback=jsonp_func&myCustomUrlParam=veryNice"
|
||||
* jsonp('/some-url', {
|
||||
* callbackQuery: 'myCallback',
|
||||
* callbackName: 'jsonp_func',
|
||||
* myCustomUrlParam: 'veryNice'
|
||||
* })
|
||||
*
|
||||
* @default callback
|
||||
*/
|
||||
callbackQuery?: string
|
||||
|
||||
/**
|
||||
* Callback function name.
|
||||
* This param is used to define the jsonp function name.
|
||||
*
|
||||
* @example
|
||||
* // The request url will be "/some-url?myCallback=jsonp_func&myCustomUrlParam=veryNice"
|
||||
* jsonp('/some-url', {
|
||||
* callbackQuery: 'myCallback',
|
||||
* callbackName: 'jsonp_func',
|
||||
* myCustomUrlParam: 'veryNice'
|
||||
* })
|
||||
*
|
||||
* @default jsonp_ + randomStr()
|
||||
*/
|
||||
callbackName?: string
|
||||
|
||||
/**
|
||||
* Custom data.
|
||||
*/
|
||||
[key: string]: any
|
||||
}
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
import Vue from 'vue'
|
||||
import { VueJsonp } from 'vue-jsonp'
|
||||
|
||||
Vue.use(VueJsonp)
|
||||
|
||||
const vm = new Vue()
|
||||
const { code, data, message } = await vm.$jsonp<{
|
||||
code: number,
|
||||
message: string,
|
||||
data: {
|
||||
id: number,
|
||||
nickname: string
|
||||
}
|
||||
}>('/my-awesome-url', {
|
||||
name: 'MyName', age: 20
|
||||
})
|
||||
|
||||
assert(code === 0)
|
||||
assert(message === 'ok')
|
||||
assert(data.id === 1)
|
||||
assert(data.nickname === 'John Smith')
|
||||
```
|
||||
|
||||
```ts
|
||||
import { jsonp } from 'vue-jsonp'
|
||||
|
||||
const result = await jsonp<string>('/my-awesome-url')
|
||||
assert(result === 'such a jsonp')
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* Vue Jsonp.
|
||||
* # Carry Your World #
|
||||
*
|
||||
* @author: LancerComet
|
||||
* @license: MIT
|
||||
*/
|
||||
import { PluginObject } from 'vue/types/plugin';
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
$jsonp: typeof jsonp;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Vue JSONP.
|
||||
*/
|
||||
declare const VueJsonp: PluginObject<never>;
|
||||
/**
|
||||
* JSONP function.
|
||||
*
|
||||
* @param { string } url Target URL address.
|
||||
* @param { IJsonpParam } param Querying params object.
|
||||
* @param { number } timeout Timeout setting (ms).
|
||||
*
|
||||
* @example
|
||||
* jsonp('/url', {
|
||||
* callbackQuery: ''
|
||||
* callbackName: '',
|
||||
* name: 'LancerComet',
|
||||
* age: 26
|
||||
* }, 1000)
|
||||
*/
|
||||
declare function jsonp<T = any>(url: string, param?: IJsonpParam, timeout?: number): Promise<T>;
|
||||
export { VueJsonp, jsonp };
|
||||
/**
|
||||
* JSONP parameter declaration.
|
||||
*/
|
||||
interface IJsonpParam {
|
||||
/**
|
||||
* Callback query name.
|
||||
* This param is used to define the query name of the callback function.
|
||||
*
|
||||
* @example
|
||||
* // The request url will be "/some-url?myCallback=jsonp_func&myCustomUrlParam=veryNice"
|
||||
* jsonp('/some-url', {
|
||||
* callbackQuery: 'myCallback',
|
||||
* callbackName: 'jsonp_func',
|
||||
* myCustomUrlParam: 'veryNice'
|
||||
* })
|
||||
*
|
||||
* @default callback
|
||||
*/
|
||||
callbackQuery?: string;
|
||||
/**
|
||||
* Callback function name.
|
||||
* This param is used to define the jsonp function name.
|
||||
*
|
||||
* @example
|
||||
* // The request url will be "/some-url?myCallback=jsonp_func&myCustomUrlParam=veryNice"
|
||||
* jsonp('/some-url', {
|
||||
* callbackQuery: 'myCallback',
|
||||
* callbackName: 'jsonp_func',
|
||||
* myCustomUrlParam: 'veryNice'
|
||||
* })
|
||||
*
|
||||
* @default jsonp_ + randomStr()
|
||||
*/
|
||||
callbackName?: string;
|
||||
/**
|
||||
* Custom data.
|
||||
*/
|
||||
[key: string]: any;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
function e(t,n){t=t.replace(/=/g,"");var o=[];switch(n.constructor){case String:case Number:case Boolean:o.push(encodeURIComponent(t)+"="+encodeURIComponent(n));break;case Array:n.forEach((function(n){o=o.concat(e(t+"[]=",n))}));break;case Object:Object.keys(n).forEach((function(r){var a=n[r];o=o.concat(e(t+"["+r+"]",a))}))}return o}function t(e){var n=[];return e.forEach((function(e){"string"==typeof e?n.push(e):n=n.concat(t(e))})),n}
|
||||
/**
|
||||
* Vue Jsonp.
|
||||
* # Carry Your World #
|
||||
*
|
||||
* @author: LancerComet
|
||||
* @license: MIT
|
||||
*/var n={install:function(e){e.prototype.$jsonp=o}};function o(n,o,r){if(void 0===o&&(o={}),"string"!=typeof n)throw new Error('[Vue-jsonp] Type of param "url" is not string.');if("object"!=typeof o||!o)throw new Error("[Vue-jsonp] Invalid params, should be an object.");return r="number"==typeof r?r:5e3,new Promise((function(a,c){var u="string"==typeof o.callbackQuery?o.callbackQuery:"callback",i="string"==typeof o.callbackName?o.callbackName:"jsonp_"+(Math.floor(1e5*Math.random())*Date.now()).toString(16);o[u]=i,delete o.callbackQuery,delete o.callbackName;var s=[];Object.keys(o).forEach((function(t){s=s.concat(e(t,o[t]))}));var l=t(s).join("&"),f=function(){p(),clearTimeout(m),c({status:400,statusText:"Bad Request"})},p=function(){b.removeEventListener("error",f)},d=function(){document.body.removeChild(b),delete window[i]},m=null;r>-1&&(m=setTimeout((function(){p(),d(),c({statusText:"Request Timeout",status:408})}),r)),window[i]=function(e){clearTimeout(m),p(),d(),a(e)};var b=document.createElement("script");b.addEventListener("error",f),b.src=n+(/\?/.test(n)?"&":"?")+l,document.body.appendChild(b)}))}export{n as VueJsonp,o as jsonp};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VueJsonp={})}(this,(function(e){"use strict";function t(e,o){e=e.replace(/=/g,"");var n=[];switch(o.constructor){case String:case Number:case Boolean:n.push(encodeURIComponent(e)+"="+encodeURIComponent(o));break;case Array:o.forEach((function(o){n=n.concat(t(e+"[]=",o))}));break;case Object:Object.keys(o).forEach((function(r){var c=o[r];n=n.concat(t(e+"["+r+"]",c))}))}return n}function o(e){var t=[];return e.forEach((function(e){"string"==typeof e?t.push(e):t=t.concat(o(e))})),t}
|
||||
/**
|
||||
* Vue Jsonp.
|
||||
* # Carry Your World #
|
||||
*
|
||||
* @author: LancerComet
|
||||
* @license: MIT
|
||||
*/var n={install:function(e){e.prototype.$jsonp=r}};function r(e,n,r){if(void 0===n&&(n={}),"string"!=typeof e)throw new Error('[Vue-jsonp] Type of param "url" is not string.');if("object"!=typeof n||!n)throw new Error("[Vue-jsonp] Invalid params, should be an object.");return r="number"==typeof r?r:5e3,new Promise((function(c,a){var i="string"==typeof n.callbackQuery?n.callbackQuery:"callback",s="string"==typeof n.callbackName?n.callbackName:"jsonp_"+(Math.floor(1e5*Math.random())*Date.now()).toString(16);n[i]=s,delete n.callbackQuery,delete n.callbackName;var u=[];Object.keys(n).forEach((function(e){u=u.concat(t(e,n[e]))}));var f=o(u).join("&"),l=function(){p(),clearTimeout(b),a({status:400,statusText:"Bad Request"})},p=function(){m.removeEventListener("error",l)},d=function(){document.body.removeChild(m),delete window[s]},b=null;r>-1&&(b=setTimeout((function(){p(),d(),a({statusText:"Request Timeout",status:408})}),r)),window[s]=function(e){clearTimeout(b),p(),d(),c(e)};var m=document.createElement("script");m.addEventListener("error",l),m.src=e+(/\?/.test(e)?"&":"?")+f,document.body.appendChild(m)}))}e.VueJsonp=n,e.jsonp=r,Object.defineProperty(e,"__esModule",{value:!0})}));
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Generate random string.
|
||||
*
|
||||
* @return { string }
|
||||
*/
|
||||
declare function randomStr(): string;
|
||||
/**
|
||||
* Format params into querying string.
|
||||
*
|
||||
* @return {string[]}
|
||||
*/
|
||||
declare function formatParams(queryKey: string, value: any): string[];
|
||||
/**
|
||||
* Flat querys.
|
||||
*
|
||||
* @param {string[] | (string[])[]} array
|
||||
* @returns
|
||||
*/
|
||||
declare function flatten(array: string[] | (string[])[]): string[];
|
||||
export { formatParams, flatten, randomStr };
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"name": "vue-jsonp",
|
||||
"version": "2.0.0",
|
||||
"description": "A tiny library for handling JSONP request.",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.esm.js",
|
||||
"keywords": [
|
||||
"Vue",
|
||||
"JSONP"
|
||||
],
|
||||
"files": [
|
||||
"dist/",
|
||||
"index.d.ts",
|
||||
"README.md"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"test": "jest",
|
||||
"pretest": "npm run build",
|
||||
"preversion": "npm run test",
|
||||
"prepublish": "npm run test"
|
||||
},
|
||||
"author": {
|
||||
"name": "LancerComet",
|
||||
"email": "chw644@hotmail.com"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/LancerComet/vue-jsonp.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/expect-puppeteer": "^4.4.3",
|
||||
"@types/jest": "^26.0.14",
|
||||
"@types/jest-environment-puppeteer": "^4.4.0",
|
||||
"@types/puppeteer": "^3.0.2",
|
||||
"jest": "^26.4.2",
|
||||
"jest-puppeteer": "^4.4.0",
|
||||
"puppeteer": "^5.3.1",
|
||||
"rollup": "^2.28.2",
|
||||
"rollup-plugin-cleanup": "^3.2.1",
|
||||
"rollup-plugin-delete": "^2.0.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-typescript2": "^0.27.3",
|
||||
"ts-jest": "^26.4.1",
|
||||
"tslint": "^6.1.3",
|
||||
"typescript": "^4.0.3",
|
||||
"vue": "^2.6.12"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
{
|
||||
"name": "uView",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "uView",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"crypto-js": "^4.2.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"js-md5": "^0.8.3",
|
||||
"jweixin-module": "^1.6.0",
|
||||
"vue-i18n": "^8.20.0",
|
||||
"vue-jsonp": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"node_modules/css-line-break": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/html2canvas": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
||||
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
||||
"dependencies": {
|
||||
"css-line-break": "^2.1.0",
|
||||
"text-segmentation": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-md5": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.8.3.tgz",
|
||||
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ=="
|
||||
},
|
||||
"node_modules/jweixin-module": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jweixin-module/-/jweixin-module-1.6.0.tgz",
|
||||
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
|
||||
},
|
||||
"node_modules/text-segmentation": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/utrie": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||
"dependencies": {
|
||||
"base64-arraybuffer": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-i18n": {
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.20.0.tgz",
|
||||
"integrity": "sha512-ZiAOoeR4d/JtKpbjipx3I80ey7cYG1ki5gQ7HwzWm4YFio9brA15BEYHjalEoBaEfzF5OBEZP+Y2MvAaWnyXXg=="
|
||||
},
|
||||
"node_modules/vue-jsonp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-jsonp/-/vue-jsonp-2.0.0.tgz",
|
||||
"integrity": "sha512-Mzd9GNeuKP5hHFDWZNMWOsCuMILSkA6jo2l4A02wheFz3qqBzH7aSEFTey1BRCZCLizlaf1EqJ5YUtF392KspA=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"css-line-break": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||
"requires": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"html2canvas": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
||||
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
||||
"requires": {
|
||||
"css-line-break": "^2.1.0",
|
||||
"text-segmentation": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"js-md5": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.8.3.tgz",
|
||||
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ=="
|
||||
},
|
||||
"jweixin-module": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jweixin-module/-/jweixin-module-1.6.0.tgz",
|
||||
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
|
||||
},
|
||||
"text-segmentation": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||
"requires": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"utrie": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"vue-i18n": {
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.20.0.tgz",
|
||||
"integrity": "sha512-ZiAOoeR4d/JtKpbjipx3I80ey7cYG1ki5gQ7HwzWm4YFio9brA15BEYHjalEoBaEfzF5OBEZP+Y2MvAaWnyXXg=="
|
||||
},
|
||||
"vue-jsonp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-jsonp/-/vue-jsonp-2.0.0.tgz",
|
||||
"integrity": "sha512-Mzd9GNeuKP5hHFDWZNMWOsCuMILSkA6jo2l4A02wheFz3qqBzH7aSEFTey1BRCZCLizlaf1EqJ5YUtF392KspA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "uView",
|
||||
"version": "1.0.0",
|
||||
"description": "<p align=\"center\">\r <img alt=\"logo\" src=\"https://uviewui.com/common/logo.png\" width=\"120\" height=\"120\" style=\"margin-bottom: 10px;\">\r </p>\r <h3 align=\"center\" style=\"margin: 30px 0 30px;font-weight: bold;font-size:40px;\">uView</h3>\r <h3 align=\"center\">多平台快速开发的UI框架</h3>",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/YanxinNet/uView.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/YanxinNet/uView/issues"
|
||||
},
|
||||
"homepage": "https://github.com/YanxinNet/uView#readme",
|
||||
"dependencies": {
|
||||
"crypto-js": "^4.2.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"js-md5": "^0.8.3",
|
||||
"jweixin-module": "^1.6.0",
|
||||
"vue-i18n": "^8.20.0",
|
||||
"vue-jsonp": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,678 @@
|
|||
{
|
||||
"easycom": {
|
||||
"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
|
||||
},
|
||||
"condition": {
|
||||
//模式配置,仅开发期间生效
|
||||
"current": 0,
|
||||
//当前激活的模式(list 的索引项)
|
||||
"list": [
|
||||
{
|
||||
"name": "test",
|
||||
//模式名称
|
||||
"path": "pages/login/login/login"
|
||||
//启动页面,必选
|
||||
// "query": "uuid=c4bba940-f69e-11ea-a419-6bafda9d095e&__id__=1" //启动参数,在页面的onLoad函数里面得到
|
||||
}
|
||||
]
|
||||
},
|
||||
"pages": [
|
||||
// 登录
|
||||
{
|
||||
"path": "pages/login/login/login",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
// 注册,
|
||||
{
|
||||
"path": "pages/login/register/register",
|
||||
"style": {
|
||||
"navigationBarTitleText": "注册",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
//实名验证
|
||||
// 完善信息
|
||||
{
|
||||
"path": "pages/login/perfect/perfect",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 毕业生认证
|
||||
{
|
||||
"path": "pages/login/graduateCertification/graduateCertification",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 首页,
|
||||
{
|
||||
"path": "pages/home/home/home",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 全部服务,
|
||||
{
|
||||
"path": "pages/home/home/components/recommend/allServices",
|
||||
"style": {
|
||||
"navigationBarTitleText": "全部服务",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 更多好友,
|
||||
{
|
||||
"path": "pages/home/home/components/recommend/moreFriends",
|
||||
"style": {
|
||||
"navigationBarTitleText": "更多好友",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 话题广场,
|
||||
{
|
||||
"path": "pages/home/home/components/topic/topicSquare",
|
||||
"style": {
|
||||
"navigationBarTitleText": "话题广场",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 话题详情,
|
||||
{
|
||||
"path": "pages/home/home/components/topic/topicDetail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "话题详情",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 搜索页,
|
||||
{
|
||||
"path": "pages/home/home/components/searchPage/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "搜索",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 帖子详情,
|
||||
{
|
||||
"path": "pages/home/home/components/contentDetail/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "详情",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 找校友,
|
||||
{
|
||||
"path": "pages/main/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 消息列表,
|
||||
{
|
||||
"path": "pages/message/msgList/msgList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 校友圈,
|
||||
{
|
||||
"path": "pages/AlumniCircle/alumnus/alumnus",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/AlumniCircle/forward/forward",
|
||||
"style": {
|
||||
"navigationBarTitleText": "转发",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 我的,
|
||||
{
|
||||
"path": "pages/my/my/my",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 查看实名信息
|
||||
// {
|
||||
// "path": "pages/my/realDetail/realDetail",
|
||||
// "style": {
|
||||
// "navigationBarTitleText": "实名认证",
|
||||
// "enablePullDownRefresh": false
|
||||
// }
|
||||
// },
|
||||
// 添加教育经历
|
||||
{
|
||||
"path": "pages/my/AddEducation/AddEducation",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 对话框,
|
||||
{
|
||||
"path": "pages/message/dialogBox/dialogBox",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 互动消息,
|
||||
{
|
||||
"path": "pages/message/interactionList/interactionList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "互动消息",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 管理列表,
|
||||
{
|
||||
"path": "pages/message/adminList/adminList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "管理列表",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 系统消息,
|
||||
{
|
||||
"path": "pages/message/sysList/sysList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "系统消息",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 新增关注,
|
||||
{
|
||||
"path": "pages/message/attentionList/attentionList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "新增关注",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 搜索校友圈,
|
||||
{
|
||||
"path": "pages/AlumniCircle/searchAlumnus/searchAlumnus",
|
||||
"style": {
|
||||
"navigationBarTitleText": "搜索",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 设置,
|
||||
{
|
||||
"path": "pages/my/mySeting/mySeting",
|
||||
"style": {
|
||||
"navigationBarTitleText": "设置",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 我的信息详情,
|
||||
{
|
||||
"path": "pages/my/myDetails/myDetails",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 头像裁剪
|
||||
{
|
||||
"path": "uview-ui/components/u-avatar-cropper/u-avatar-cropper",
|
||||
"style": {
|
||||
"navigationBarTitleText": "头像裁剪",
|
||||
"navigationBarBackgroundColor": "#000000",
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 官方认证,
|
||||
{
|
||||
"path": "pages/my/authentication/authentication",
|
||||
"style": {
|
||||
"navigationBarTitleText": "官方认证",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
//认证详情,
|
||||
{
|
||||
"path": "pages/my/certificationDetails/certificationDetails",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 搜索,
|
||||
{
|
||||
"path": "pages/main/search/search",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 忘记密码,
|
||||
{
|
||||
"path": "pages/login/ForgetPassword/ForgetPassword",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 文章详情,
|
||||
{
|
||||
"path": "pages/AlumniCircle/ArticleDetails/ArticleDetails",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 评论详情,
|
||||
{
|
||||
"path": "pages/AlumniCircle/ReplyDetails/ReplyDetails",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
// 文章发布页面,
|
||||
{
|
||||
"path": "pages/AlumniCircle/release/release",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/AlumniCircle/Alumni/Alumni",
|
||||
"style": {
|
||||
"navigationBarTitleText": "校友",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/AlumniCircle/userDetail/userDetail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "个人主页",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/confirmPwd/confirmPwd",
|
||||
"style": {
|
||||
"navigationBarTitleText": "确认密码",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/ShoolList/ShoolList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "教育经历",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/TeacherList/TeacherList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "任职院校",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/shoolAuthentication/shoolAuthentication",
|
||||
"style": {
|
||||
"navigationBarTitleText": "学历认证",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/ReleaseList/ReleaseList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的发布",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/examine/examine",
|
||||
"style": {
|
||||
"navigationBarTitleText": "审核",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/AuditDeatil/AuditDeatil",
|
||||
"style": {
|
||||
"navigationBarTitleText": "审核资料",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/Feedback/Feedback",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/wishlist/wishlist",
|
||||
"style": {
|
||||
"navigationBarTitleText": "心愿单",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/wishlist/addwishlist",
|
||||
"style": {
|
||||
"navigationBarTitleText": "添加心愿",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/BackSchool/BackSchool",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/BackApply/BackApply",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/BackDetail/BackDetail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/BackCode/BackCode",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/BackSuccess/BackSuccess",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/personalResume/personalResume",
|
||||
"style": {
|
||||
"navigationBarTitleText": "个人简历",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/personalResume/online",
|
||||
"style": {
|
||||
"navigationBarTitleText": "在线简历",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/personalResume/workPage",
|
||||
"style": {
|
||||
"navigationBarTitleText": "工作经历",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/personalResume/proPage",
|
||||
"style": {
|
||||
"navigationBarTitleText": "工作经历",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/BackCodeLook/BackCodeLook",
|
||||
"style": {
|
||||
"navigationBarTitleText": "返校核验",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/fileAcc/fileAcc",
|
||||
"style": {
|
||||
"navigationBarTitleText": "附件简历",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/roleSelection",
|
||||
"style": {
|
||||
"navigationBarTitleText": "角色选择",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/teacherCertification",
|
||||
"style": {
|
||||
"navigationBarTitleText": "教职工认证",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/webview/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "网页链接",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/recognitionResult/recognitionResult",
|
||||
"style": {
|
||||
"navigationBarTitleText": "提示",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/recognitionResult/recognitionFailed",
|
||||
"style": {
|
||||
"navigationBarTitleText": "认证失败",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/mySeting/mySetPwd",
|
||||
"style": {
|
||||
"navigationBarTitleText": "设置密码",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/my/myDetails/myInterest",
|
||||
"style": {
|
||||
"navigationBarTitleText": "兴趣爱好",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
// 隐藏系统导航栏
|
||||
}
|
||||
}
|
||||
],
|
||||
"subPackages": [],
|
||||
// "preloadRule": {
|
||||
// "pages/example/components": {
|
||||
// "network": "all",
|
||||
// "packages": ["pages/componentsA", "pages/componentsB", "pages/componentsC"]
|
||||
// }
|
||||
// },
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uView",
|
||||
"navigationBarBackgroundColor": "#FFFFFF",
|
||||
"backgroundColor": "#FFFFFF"
|
||||
},
|
||||
"tabBar": {
|
||||
"color": "#909399",
|
||||
"selectedColor": "#303133",
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"borderStyle": "black",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/home/home/home",
|
||||
"iconPath": "/static/common/tabbar/index.png",
|
||||
"selectedIconPath": "/static/common/tabbar/selectindex.png",
|
||||
"text": "首页"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/message/msgList/msgList",
|
||||
"iconPath": "static/common/tabbar/message.png",
|
||||
"selectedIconPath": "static/common/tabbar/selectmessage.png",
|
||||
"text": "消息"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/main/index/index",
|
||||
"iconPath": "/static/common/tabbar/findFriends.png",
|
||||
"selectedIconPath": "/static/common/tabbar/selectFindFridend.png",
|
||||
"text": "找校友"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/AlumniCircle/alumnus/alumnus",
|
||||
"iconPath": "static/common/tabbar/AlumniCircle.png",
|
||||
"selectedIconPath": "static/common/tabbar/selectAlumniCircle.png",
|
||||
"text": "校友圈"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/my/my/my",
|
||||
"iconPath": "static/common/tabbar/my.png",
|
||||
"selectedIconPath": "static/common/tabbar/selectmy.png",
|
||||
"text": "我的"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
<template>
|
||||
<view style="background: #fff">
|
||||
<u-navbar back-text="" title="校友找找" ></u-navbar>
|
||||
<view class="slot-wrap">
|
||||
<u-tabs-swiper ref="uTabs" :list="navList" :current="current" :is-scroll="true" gutter='60'
|
||||
:active-item-style="{ color: '#3CB5FB',transition:'all 0.5s'}" :bar-style="{ background: '#3CB5FB' }"
|
||||
@change="tabsChange"></u-tabs-swiper>
|
||||
</view>
|
||||
<swiper :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish"
|
||||
style="height: calc(100vh - 0.8rem); width: 100%">
|
||||
<swiper-item class="swiper-item" v-for="(item, index) in navList" :key="index"
|
||||
style="height: calc(100vh - 0.8rem); width: 100%">
|
||||
<scroll-view scroll-y="true" style="height: calc(100vh - 0.8rem); width: 100%"
|
||||
@scrolltolower="onreachBottom" @refresherrefresh='' :scroll-with-animation="true">
|
||||
<!-- 学生 -->
|
||||
<template v-if='item.List.length'>
|
||||
<view class="flex-col student_list group_7">
|
||||
<view class="flex-row list-item group_8" :key="i" v-for="(v, i) in item.List"
|
||||
@click="toDetil(v.userId)">
|
||||
<u-avatar :src="$u.http.config.imgUrl+v.imageUrl" class="image_1" ></u-avatar>
|
||||
<view class="justify-between section_4">
|
||||
<view class="flex-col items-start group_9 view_1">
|
||||
<text class="text_6">{{v.name}}</text>
|
||||
<text class="text_24">{{v.college+' '+ v.major}} {{v.startYear}}级</text>
|
||||
</view>
|
||||
<image src="/static/common/img/16486889538940144558.png" class="image_3" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<view v-else style='padding-top:30vh'>
|
||||
<u-empty text="没有找到匹配的校友" mode="message"></u-empty>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
swiperCurrent: 0,
|
||||
current: 0,
|
||||
List: [],
|
||||
navList: [{
|
||||
name: "全部",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "学院",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "同专业",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "同届",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "同行",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "同城",
|
||||
List: [],
|
||||
},
|
||||
],
|
||||
PageIndex: 1,
|
||||
PageSize: 10,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
current() {
|
||||
this.PageIndex = 1
|
||||
this.getList(1);
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
this.getList(1);
|
||||
},
|
||||
onShow() {
|
||||
// this.getList(1);
|
||||
},
|
||||
methods: {
|
||||
getList(type) {
|
||||
const data = {
|
||||
PageIndex: this.PageIndex,
|
||||
PageSize: this.PageSize,
|
||||
type: this.current
|
||||
}
|
||||
this.$u.api.AlumnSearchList(data).then(res => {
|
||||
if (this.navList[this.current].List.length == 0 || type == 1) {
|
||||
this.navList[this.current].List = res.items
|
||||
} else {
|
||||
this.navList[this.current].List = this.navList[this.current].List.concat(res.items)
|
||||
}
|
||||
})
|
||||
},
|
||||
toDetil(id) {
|
||||
this.$u.route({
|
||||
url: '/pages/AlumniCircle/userDetail/userDetail?id=' + id + '&type=2'
|
||||
})
|
||||
},
|
||||
// tabs通知swiper切换
|
||||
tabsChange(index) {
|
||||
this.swiperCurrent = index;
|
||||
},
|
||||
// swiper-item左右移动,通知tabs的滑块跟随移动
|
||||
transition(e) {
|
||||
let dx = e.detail.dx;
|
||||
this.$refs.uTabs.setDx(dx);
|
||||
},
|
||||
// 由于swiper的内部机制问速切题,快换swiper不会触发dx的连续变化,需要在结束时重置状态
|
||||
// swiper滑动结束,分别设置tabs和swiper的状态
|
||||
animationfinish(e) {
|
||||
let current = e.detail.current;
|
||||
this.$refs.uTabs.setFinishCurrent(current);
|
||||
this.swiperCurrent = current;
|
||||
this.current = current;
|
||||
},
|
||||
// scroll-view到底部加载更多
|
||||
onreachBottom() {
|
||||
this.PageIndex++
|
||||
this.getList(2)
|
||||
},
|
||||
//返回上一级
|
||||
router() {
|
||||
uni.switchTab({
|
||||
url: '../../AlumniCircle/alumnus/alumnus'
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .u-avatar__sex {
|
||||
width: 0.1rem !important;
|
||||
height: 0.1rem !important;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.student_list {
|
||||
.list-item {
|
||||
padding: 0.05rem 0.2rem;
|
||||
box-shadow: 0px 0.0063rem #eaeaea;
|
||||
|
||||
.image_1 {
|
||||
flex-shrink: 0;
|
||||
align-self: center;
|
||||
width: 0.5rem !important;
|
||||
height: 0.5rem !important;
|
||||
border-radius: 50%;
|
||||
flex:0 0 0.5rem !important;
|
||||
}
|
||||
|
||||
.section_4 {
|
||||
margin-left: 0.05rem;
|
||||
padding: 0.1rem;
|
||||
flex: 1 1 auto;
|
||||
|
||||
.group_9 {
|
||||
align-self: flex-start;
|
||||
color: #020202;
|
||||
font-size: 0.19rem;
|
||||
letter-spacing: 0.019rem;
|
||||
|
||||
.text_6 {
|
||||
color: #020202;
|
||||
font-size: 0.16rem;
|
||||
line-height: 1;
|
||||
letter-spacing: 0.019rem;
|
||||
}
|
||||
|
||||
.text_24 {
|
||||
margin-top: 0.1rem;
|
||||
color: #b4b6bd;
|
||||
font-size: 0.14rem;
|
||||
line-height: 1;
|
||||
letter-spacing: 0.015rem;
|
||||
width: 2rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.view_1 {
|
||||
align-self: initial;
|
||||
color: initial;
|
||||
font-size: initial;
|
||||
line-height: initial;
|
||||
letter-spacing: initial;
|
||||
white-space: initial;
|
||||
}
|
||||
|
||||
.image_3 {
|
||||
align-self: center;
|
||||
width: 0.075rem;
|
||||
height: 0.14rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
margin-top: 0.17rem;
|
||||
padding: 0 5%;
|
||||
|
||||
.list-item {
|
||||
padding: 0.13rem 0.12rem 0.13rem 0.33rem;
|
||||
background-color: #f6f7fa;
|
||||
border-radius: 0.05rem;
|
||||
|
||||
.text_6 {
|
||||
color: #373b48;
|
||||
font-size: 0.15rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
|
||||
.text_10 {
|
||||
color: #ffffff;
|
||||
line-height: 0.16rem;
|
||||
}
|
||||
|
||||
.image_1 {
|
||||
margin-bottom: 0.02rem;
|
||||
width: 0.06rem;
|
||||
height: 0.11rem;
|
||||
}
|
||||
|
||||
.image_5 {
|
||||
margin-bottom: 0.04rem;
|
||||
}
|
||||
}
|
||||
|
||||
.section_5 {
|
||||
padding: 0.12rem 0.12rem 0.12rem 0.34rem;
|
||||
background-color: #2e9bff;
|
||||
margin-top: 0.07rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,349 @@
|
|||
<template>
|
||||
<view style="background: #fff">
|
||||
<u-navbar back-text="" title="校友找找"></u-navbar>
|
||||
<view class="slot-wrap">
|
||||
<u-tabs-swiper ref="uTabs" :list="navList" :current="current" :is-scroll="true" gutter="60"
|
||||
:active-item-style="{ color: '#3CB5FB', transition: 'all 0.5s' }" :bar-style="{ background: '#3CB5FB' }"
|
||||
@change="tabsChange"></u-tabs-swiper>
|
||||
</view>
|
||||
<swiper :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish"
|
||||
style="height: calc(100vh - 0.8rem); width: 100%">
|
||||
<swiper-item class="swiper-item" v-for="(item, index) in navList" :key="index"
|
||||
style="height: calc(100vh - 0.8rem); width: 100%">
|
||||
<scroll-view scroll-y="true" style="height: calc(100vh - 0.8rem); width: 100%" @scrolltolower="onreachBottom"
|
||||
@refresherrefresh="" :scroll-with-animation="true">
|
||||
<!-- 学生 -->
|
||||
<template v-if="item.List.length">
|
||||
<view class="flex-col student_list group_7">
|
||||
<view class="flex-row list-item group_8" :key="i" v-for="(v, i) in item.List" @click="toDetil(v.userId)">
|
||||
<u-avatar :src="$u.http.config.imgUrl + v.imageUrl" class="image_1"></u-avatar>
|
||||
<view class="justify-between section_4">
|
||||
<view class="flex-col items-start group_9 view_1">
|
||||
<text class="text_6">{{ v.name }}</text>
|
||||
<!-- <text class="text_24">
|
||||
{{ v.college + " " + v.major }} {{ v.startYear }}级
|
||||
</text> -->
|
||||
<!-- <u-tag
|
||||
:text="v.college + ' ' + v.major"
|
||||
type="primary"
|
||||
mode="plain"
|
||||
style="margin-top: 0.05rem"
|
||||
></u-tag> -->
|
||||
<view class="tag">
|
||||
<text class="tag-item">{{ v.college }}</text>
|
||||
<text class="tag-item">{{ v.major }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <u-button
|
||||
class="follow-btn"
|
||||
shape="circle"
|
||||
:type="v.isFollowed ? 'default' : 'primary'"
|
||||
@click="handleFollow(v.userId)"
|
||||
>
|
||||
{{ v.isFollowed ? "已关注" : "未关注" }}
|
||||
</u-button> -->
|
||||
<view class="flex-row ">
|
||||
<text class="message" @click.stop="toMessage(v.userId)">私信</text>
|
||||
<!-- <image
|
||||
src="/static/common/img/16486889538940144558.png"
|
||||
class="image_3"
|
||||
/> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<view v-else style="padding-top: 30vh">
|
||||
<!-- <u-empty text="没有找到匹配的校友" mode="message"></u-empty> -->
|
||||
<no-data type="friends" text="没有找到匹配的校友"></no-data>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NoData from "components/NoData.vue";
|
||||
export default {
|
||||
components: {
|
||||
NoData,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
swiperCurrent: 0,
|
||||
current: 0,
|
||||
List: [],
|
||||
navList: [
|
||||
{
|
||||
name: "全部",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "学院",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "同专业",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "同届",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "同行",
|
||||
List: [],
|
||||
},
|
||||
{
|
||||
name: "同城",
|
||||
List: [],
|
||||
},
|
||||
],
|
||||
PageIndex: 1,
|
||||
PageSize: 10,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
current() {
|
||||
this.PageIndex = 1;
|
||||
this.getList(1);
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
this.getList(1);
|
||||
},
|
||||
onShow() {
|
||||
// this.getList(1);
|
||||
},
|
||||
methods: {
|
||||
getList(type) {
|
||||
const data = {
|
||||
PageIndex: this.PageIndex,
|
||||
PageSize: this.PageSize,
|
||||
type: this.current,
|
||||
};
|
||||
this.$u.api.AlumnSearchList(data).then((res) => {
|
||||
if (this.navList[this.current].List.length == 0 || type == 1) {
|
||||
this.navList[this.current].List = res.items;
|
||||
} else {
|
||||
this.navList[this.current].List = this.navList[
|
||||
this.current
|
||||
].List.concat(res.items);
|
||||
}
|
||||
});
|
||||
},
|
||||
toDetil(id) {
|
||||
this.$u.route({
|
||||
url: "/pages/AlumniCircle/userDetail/userDetail?id=" + id + "&type=2",
|
||||
});
|
||||
},
|
||||
toMessage(id) {
|
||||
uni.navigateTo({
|
||||
url: "../../message/dialogBox/dialogBox?id=" + id + "&chatType=0",
|
||||
});
|
||||
},
|
||||
// tabs通知swiper切换
|
||||
tabsChange(index) {
|
||||
this.swiperCurrent = index;
|
||||
},
|
||||
// swiper-item左右移动,通知tabs的滑块跟随移动
|
||||
transition(e) {
|
||||
let dx = e.detail.dx;
|
||||
this.$refs.uTabs.setDx(dx);
|
||||
},
|
||||
// 由于swiper的内部机制问速切题,快换swiper不会触发dx的连续变化,需要在结束时重置状态
|
||||
// swiper滑动结束,分别设置tabs和swiper的状态
|
||||
animationfinish(e) {
|
||||
let current = e.detail.current;
|
||||
this.$refs.uTabs.setFinishCurrent(current);
|
||||
this.swiperCurrent = current;
|
||||
this.current = current;
|
||||
},
|
||||
// scroll-view到底部加载更多
|
||||
onreachBottom() {
|
||||
this.PageIndex++;
|
||||
this.getList(2);
|
||||
},
|
||||
|
||||
// 关注
|
||||
handleFollow(id) {
|
||||
const data = {
|
||||
userId: this.vuex_user.id,
|
||||
carewId: id,
|
||||
};
|
||||
this.$u.apiList.InsertOrDelFollow(data).then((res) => {
|
||||
this.getList(this.current);
|
||||
});
|
||||
},
|
||||
|
||||
//返回上一级
|
||||
router() {
|
||||
uni.switchTab({
|
||||
url: "../../AlumniCircle/alumnus/alumnus",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .u-avatar__sex {
|
||||
width: 0.1rem !important;
|
||||
height: 0.1rem !important;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.student_list {
|
||||
background: #f6f8f9;
|
||||
|
||||
.list-item {
|
||||
width: calc(100% - 48rpx);
|
||||
margin: 10rpx auto;
|
||||
padding: 24rpx;
|
||||
// box-shadow: 0px 0.0063rem #eaeaea;
|
||||
background: #FFFFFF;
|
||||
border-radius: 24rpx;
|
||||
|
||||
.image_1 {
|
||||
flex-shrink: 0;
|
||||
align-self: center;
|
||||
width: 0.5rem !important;
|
||||
height: 0.5rem !important;
|
||||
border-radius: 50%;
|
||||
flex: 0 0 0.5rem !important;
|
||||
}
|
||||
|
||||
.section_4 {
|
||||
margin-left: 0.05rem;
|
||||
// padding: 0.1rem;
|
||||
flex: 1 1 auto;
|
||||
|
||||
.group_9 {
|
||||
align-self: flex-start;
|
||||
color: #020202;
|
||||
font-size: 0.19rem;
|
||||
letter-spacing: 0.019rem;
|
||||
|
||||
.text_6 {
|
||||
color: #020202;
|
||||
font-size: 32rpx;
|
||||
line-height: 1;
|
||||
margin-top: 15rpx;
|
||||
// letter-spacing: 0.019rem;
|
||||
}
|
||||
|
||||
.text_24 {
|
||||
margin-top: 0.1rem;
|
||||
color: #b4b6bd;
|
||||
font-size: 0.14rem;
|
||||
line-height: 1;
|
||||
letter-spacing: 0.015rem;
|
||||
width: 2rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.view_1 {
|
||||
align-self: initial;
|
||||
color: initial;
|
||||
font-size: initial;
|
||||
line-height: initial;
|
||||
letter-spacing: initial;
|
||||
white-space: initial;
|
||||
}
|
||||
|
||||
.image_3 {
|
||||
align-self: center;
|
||||
width: 0.075rem;
|
||||
height: 0.14rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.message {
|
||||
display: inline-block;
|
||||
width: 100rpx;
|
||||
height: 60rpx;
|
||||
box-shadow: inset 4rpx 8rpx 32rpx 0rpx rgba(248, 248, 248, 0.06);
|
||||
border-radius: 64rpx 64rpx 64rpx 64rpx;
|
||||
border: 2rpx solid #3cb5fb;
|
||||
text-align: center;
|
||||
line-height: 55rpx;
|
||||
font-weight: 500;
|
||||
font-size: 24rpx;
|
||||
color: #3CB5FB;
|
||||
}
|
||||
}
|
||||
|
||||
.follow-btn {
|
||||
width: 120rpx;
|
||||
height: 64rpx;
|
||||
line-height: 64rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
margin-top: 0.17rem;
|
||||
padding: 0 5%;
|
||||
|
||||
.list-item {
|
||||
padding: 0.13rem 0.12rem 0.13rem 0.33rem;
|
||||
background-color: #f6f7fa;
|
||||
border-radius: 0.05rem;
|
||||
|
||||
.text_6 {
|
||||
color: #373b48;
|
||||
font-size: 0.15rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
|
||||
.text_10 {
|
||||
color: #ffffff;
|
||||
line-height: 0.16rem;
|
||||
}
|
||||
|
||||
.image_1 {
|
||||
margin-bottom: 0.02rem;
|
||||
width: 0.06rem;
|
||||
height: 0.11rem;
|
||||
}
|
||||
|
||||
.image_5 {
|
||||
margin-bottom: 0.04rem;
|
||||
}
|
||||
}
|
||||
|
||||
.section_5 {
|
||||
padding: 0.12rem 0.12rem 0.12rem 0.34rem;
|
||||
background-color: #2e9bff;
|
||||
margin-top: 0.07rem;
|
||||
}
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
|
||||
margin-top: 40rpx;
|
||||
width: 400rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
.tag-item {
|
||||
background: #F6F8F9;
|
||||
border-radius: 12rpx;
|
||||
font-size: 24rpx;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
font-weight: 400;
|
||||
padding: 12rpx;
|
||||
&:first-child {
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,349 @@
|
|||
<template>
|
||||
<view>
|
||||
<u-navbar title="评论详细">
|
||||
<template #right
|
||||
><view style="width: 50rpx; font-size: 32rpx">
|
||||
<!-- <u-icon name="star" v-if="true"></u-icon> -->
|
||||
<!-- <u-icon style="font-size:0.22rem;color:#ffc300" v-else name="star-fill"></u-icon> -->
|
||||
</view>
|
||||
</template>
|
||||
</u-navbar>
|
||||
<!-- 评论 -->
|
||||
<view class="comment">
|
||||
<view class="flex-col section_4">
|
||||
<view class="justify-between group_8">
|
||||
<text class="text_22">回复 {{total}}</text>
|
||||
</view>
|
||||
<view class="flex-col group_27">
|
||||
<view class="flex-col group">
|
||||
<view class="justify-between group_6">
|
||||
<view class="flex-row">
|
||||
<image
|
||||
:src="$u.http.config.imgUrl + headData.userHead"
|
||||
class="image image_6"
|
||||
/>
|
||||
<text class="text_24">{{headData.userName}}</text>
|
||||
<text class="text_27">{{headData.creationTime}}</text>
|
||||
</view>
|
||||
<view class="flex-row group_12">
|
||||
<text class="text_25">{{headData.likesCount}}</text>
|
||||
<image
|
||||
src="/static/common/img/homepage/like.png"
|
||||
class="image_8"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-col">
|
||||
<text class="text_26" @click="onreply">{{headData.content}}</text>
|
||||
<!-- <view class="justify-evenly section_5">
|
||||
<text class="text_42">{{total}}回复</text>
|
||||
<image
|
||||
src="/static/common/img/16486282410596443868.png"
|
||||
class="image_12"
|
||||
/>
|
||||
</view> -->
|
||||
<!-- <text class="text_27">{{headData.creationTime}}</text> -->
|
||||
</view>
|
||||
<view class="flex-col items-start group_9" v-for="(i,index) in commonData" :key="index">
|
||||
<view class="flex-row group_13">
|
||||
<image
|
||||
:src="$u.http.config.imgUrl + i.userHead"
|
||||
class="image image_9"
|
||||
/>
|
||||
<view class="group_14">
|
||||
<text class="text_28">{{i.userName}}</text>
|
||||
<text class="text_30">{{i.creationTime}}</text>
|
||||
<view class="flex-col items-start group_15">
|
||||
<text class="text_29">{{i.content}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-mask :show="show" @click="isMask">
|
||||
<msgbox @onsend="onSend" @onmsgShow="onMsgShow" ref="msg" :placeholder="placeholder"></msgbox>
|
||||
</u-mask>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import msgbox from "../../../components/messageBox.vue";
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
data : {
|
||||
PageIndex:1,
|
||||
PageSize:10,
|
||||
Title:"",
|
||||
Keyword:"",
|
||||
id:"",
|
||||
},
|
||||
show:false,
|
||||
headData:{},
|
||||
commonData:[],
|
||||
placeholder:"",
|
||||
total:0,
|
||||
}
|
||||
},
|
||||
onLoad(e){
|
||||
this.headData = JSON.parse(e.head)
|
||||
this.data = JSON.parse(e.data)
|
||||
this.data.PageIndex = 1
|
||||
this.data.PageSize = 10
|
||||
},
|
||||
created(){
|
||||
this.getComment()
|
||||
},
|
||||
methods:{
|
||||
getComment(){
|
||||
this.$u.apiList.GetComment(this.data).then((res)=>{
|
||||
this.commonData = res.items
|
||||
this.total = res.items.length
|
||||
})
|
||||
},
|
||||
onreply(){
|
||||
this.show = true
|
||||
this.placeholder = '回复'+this.headData.userName
|
||||
this.$refs.msg.placeholder = this.placeholder
|
||||
},
|
||||
isMask(){
|
||||
this.show =false
|
||||
},
|
||||
onSend(msg){
|
||||
const data = {
|
||||
commendId:this.headData.commendId,
|
||||
articleId:this.headData.articleId,
|
||||
userId:this.vuex_user.id,
|
||||
replyUserId:this.headData.userId,
|
||||
content:msg,
|
||||
level:1,
|
||||
type:this.headData.type
|
||||
}
|
||||
this.$u.apiList.InsertComment(data).then((res)=>{
|
||||
this.getComment()
|
||||
})
|
||||
},
|
||||
onMsgShow(val){
|
||||
this.isMsgShow = val
|
||||
this.show = val
|
||||
},
|
||||
},
|
||||
components: {
|
||||
msgbox: msgbox,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.comment {
|
||||
.section_4 {
|
||||
padding: 0.26rem 0.14rem 0.61rem 0.16rem;
|
||||
background-color: rgb(255, 255, 255);
|
||||
// margin-top:0.1rem;
|
||||
.section_5 {
|
||||
margin-top: 0.13rem;
|
||||
padding: 0.04rem 0.05rem 0.05rem 0.095rem;
|
||||
background-color: rgb(246, 247, 250);
|
||||
border-radius: 0.1rem;
|
||||
width: 0.6rem;
|
||||
.text_42 {
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.12rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.11rem;
|
||||
}
|
||||
.image_12 {
|
||||
margin-top: 0.015rem;
|
||||
width: 0.05rem;
|
||||
height: 0.09rem;
|
||||
}
|
||||
}
|
||||
.group_8 {
|
||||
margin-left: 0.025rem;
|
||||
.text_22 {
|
||||
margin-bottom: 0.02rem;
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.15rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
.text_23 {
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.15rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.17rem;
|
||||
}
|
||||
}
|
||||
.group_27 {
|
||||
margin-top: 0.25rem;
|
||||
.group {
|
||||
padding: 0 0.005rem;
|
||||
.group_6 {
|
||||
margin-right: 0.02rem;
|
||||
.group_12 {
|
||||
margin-top: 0.04rem;
|
||||
.text_25 {
|
||||
margin-top: 0.04rem;
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.15rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.12rem;
|
||||
}
|
||||
.image_8 {
|
||||
margin-left: 0.045rem;
|
||||
flex-shrink: 0;
|
||||
width: 0.16rem;
|
||||
height: 0.15rem;
|
||||
transform: translateY(0.02rem);
|
||||
}
|
||||
}
|
||||
|
||||
.image_6 {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.text_24 {
|
||||
margin-left: 0.13rem;
|
||||
margin-top: 0.07rem;
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.13rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
|
||||
.text_27 {
|
||||
margin-left: 0.13rem;
|
||||
margin-top: 0.07rem;
|
||||
align-self: flex-start;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.12rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.12rem;
|
||||
}
|
||||
}
|
||||
.text_26 {
|
||||
width: 100%;
|
||||
padding-left: 0.4rem;
|
||||
margin-top: 0.075rem;
|
||||
align-self: center;
|
||||
color: rgb(55, 59, 72);
|
||||
font-size: 0.15rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
}
|
||||
.group_9 {
|
||||
margin-top: 0.14rem;
|
||||
padding: 0 0.38rem;
|
||||
.group_13 {
|
||||
margin-left: 0.035rem;
|
||||
.image_9 {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.group_14 {
|
||||
margin-left: 0.18rem;
|
||||
margin-top: 0.05rem;
|
||||
flex: 1 1 auto;
|
||||
.text_28 {
|
||||
align-self: flex-start;
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.13rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
.text_30 {
|
||||
margin-left: 0.13rem;
|
||||
margin-top: 0.045rem;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.12rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.12rem;
|
||||
}
|
||||
.group_15 {
|
||||
margin-top: 0.12rem;
|
||||
.text_29 {
|
||||
color: rgb(55, 59, 72);
|
||||
font-size: 0.15rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.group_16 {
|
||||
margin-left: 0.035rem;
|
||||
margin-top: 0.11rem;
|
||||
width: 1.09rem;
|
||||
.group_17 {
|
||||
margin-top: 0.075rem;
|
||||
.text_31 {
|
||||
align-self: flex-start;
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.13rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.1rem;
|
||||
}
|
||||
.group_18 {
|
||||
margin-top: 0.14rem;
|
||||
padding-left: 0.015rem;
|
||||
.text_32 {
|
||||
color: rgb(55, 59, 72);
|
||||
font-size: 0.15rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
.text_33 {
|
||||
margin-top: 0.03rem;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.12rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.12rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.group_19 {
|
||||
margin-left: 0.05rem;
|
||||
margin-top: 0.12rem;
|
||||
width: 1.07rem;
|
||||
.group_20 {
|
||||
margin-top: 0.07rem;
|
||||
.text_34 {
|
||||
align-self: flex-start;
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.13rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.12rem;
|
||||
}
|
||||
.group_21 {
|
||||
margin-top: 0.14rem;
|
||||
.text_35 {
|
||||
color: rgb(55, 59, 72);
|
||||
font-size: 0.15rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
.text_36 {
|
||||
margin-left: 0.01rem;
|
||||
margin-top: 0.03rem;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.12rem;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.12rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.image {
|
||||
width: 0.3rem;
|
||||
height: 0.3rem;
|
||||
border-radius:50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,276 @@
|
|||
<template>
|
||||
<view class="flex-col forward">
|
||||
<u-navbar title="转发" ></u-navbar>
|
||||
<view class="flex-col group1">
|
||||
<view>
|
||||
<u-input v-model="value" :type="type" :border="border" :height="height" :auto-height="autoHeight" placeholder="转发分享内容"/>
|
||||
</view>
|
||||
<view class="flex-col list-item">
|
||||
<view class="flex-row group_8 view">
|
||||
<image :src="$u.http.config.imgUrl+forwardData.userHead" class="image_3" />
|
||||
<text class="text_8 text_43">{{forwardData.userName}}</text>
|
||||
<text class="text_9">{{forwardData.creationTime}}</text>
|
||||
<text class="text_11">{{forwardData.schoolName}}</text>
|
||||
</view>
|
||||
<view class="flex-col group_9">
|
||||
<text class="text_14">{{forwardData.title}}</text>
|
||||
<text class="text_15">
|
||||
{{forwardData.content}}
|
||||
</text>
|
||||
<view class="imgList flex-col" v-if="true">
|
||||
<view class="flex-row group_10">
|
||||
<!-- <image :src="$u.http.config.imgUrl + forwardData.imageUrl"
|
||||
class="image_10" /> -->
|
||||
<image v-for="(v, i) in forwardData.imageUrl.split(',')" @click="clickImg(v)" :key="i" :src="v?$u.http.config.imgUrl + v:''"
|
||||
class="image_10" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-col items-center button" @click="onSend">
|
||||
<text>发送</text>
|
||||
</view>
|
||||
<view>
|
||||
<u-toast ref="uToast" />
|
||||
<u-top-tips :z-index='999999' ref="uTips" :navbar-height="0"></u-top-tips>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
value:'',
|
||||
type:'textarea',
|
||||
border: true,
|
||||
height: 150,
|
||||
autoHeight: true,
|
||||
forwardData:{},
|
||||
}
|
||||
},
|
||||
onLoad(e){
|
||||
this.forwardData = JSON.parse(e.data)
|
||||
},
|
||||
methods:{
|
||||
onSend(){
|
||||
if(this.value == ""){
|
||||
// return this.$tips("请输入标题", "error");
|
||||
return this.$refs.uToast.show({
|
||||
title: '请输入标题',
|
||||
type: 'warning',
|
||||
})
|
||||
}
|
||||
const data = {
|
||||
title:this.value,
|
||||
content:this.forwardData.content,
|
||||
sysSignStr:this.forwardData.sysSignStr,
|
||||
userId:this.vuex_user.id,
|
||||
path:this.forwardData.imageUrl,
|
||||
forwardId:this.forwardData.id
|
||||
}
|
||||
if(this.forwardData.schoolId){
|
||||
data.schoolId = this.forwardData.schoolId
|
||||
}
|
||||
this.$u.apiList.ForwardHelpArticle(data).then((res)=>{
|
||||
/* uni.showToast({
|
||||
title: "转发成功",
|
||||
duration: 2000,
|
||||
}); */
|
||||
this.$refs.uToast.show({
|
||||
title: '转发成功',
|
||||
type: 'success',
|
||||
})
|
||||
uni.$emit('echoList',{
|
||||
type:'forward',
|
||||
data:{}
|
||||
})
|
||||
setTimeout(()=>{
|
||||
uni.switchTab({
|
||||
url: '../../AlumniCircle/alumnus/alumnus'
|
||||
});
|
||||
},1000)
|
||||
})
|
||||
},
|
||||
//图片预览
|
||||
clickImg(item){
|
||||
item = this.$u.http.config.imgUrl + item
|
||||
var images = [];
|
||||
images.push(item);
|
||||
uni.previewImage({ // 图片路径必须是一个数组 => ['']
|
||||
current: 0,
|
||||
urls: images,
|
||||
});
|
||||
},
|
||||
//返回上一级
|
||||
router(){
|
||||
if(this.forwardData.route==2){
|
||||
this.$u.route({
|
||||
url:'pages/AlumniCircle/userDetail/userDetail?id='+this.forwardData.userId
|
||||
})
|
||||
}else{
|
||||
uni.switchTab({
|
||||
url: '../../AlumniCircle/alumnus/alumnus'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.forward{
|
||||
background-color: #ffffff;
|
||||
height: 100vh;
|
||||
.group1{
|
||||
padding: 0.2rem 0.15rem;
|
||||
}
|
||||
.list-item {
|
||||
padding: 0.18rem 0 0.21rem 0.16rem;
|
||||
background-color: #F2F2F2;
|
||||
margin-bottom: 0.1rem;
|
||||
.view {
|
||||
margin-right: 0.051rem;
|
||||
}
|
||||
.group_9 {
|
||||
margin-right: 0.13rem;
|
||||
margin-top: 0.17rem;
|
||||
.text_14 {
|
||||
align-self: flex-start;
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 32rpx;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.17rem;
|
||||
}
|
||||
.text_15 {
|
||||
margin-top: 0.11rem;
|
||||
color: rgb(73, 76, 87);
|
||||
font-size: 28rpx;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.24rem;
|
||||
text-indent: 0.2rem;
|
||||
}
|
||||
.text_16 {
|
||||
margin-left: 0.04rem;
|
||||
margin-top: 0.12rem;
|
||||
align-self: flex-start;
|
||||
color: rgb(44, 109, 255);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
}
|
||||
.group_21 {
|
||||
margin-top: 0.1rem;
|
||||
justify-content: space-between;
|
||||
width: 90%;
|
||||
margin: 0.1rem auto 0;
|
||||
.group_20 {
|
||||
margin: 0.025rem 0;
|
||||
.image_6 {
|
||||
flex-shrink: 0;
|
||||
width: 0.22rem;
|
||||
height: 0.21rem;
|
||||
}
|
||||
.text_17 {
|
||||
margin-left: 0.08rem;
|
||||
margin-top: 0.065rem;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.11rem;
|
||||
}
|
||||
}
|
||||
.equal-division-item_1 {
|
||||
padding: 0.03rem 0;
|
||||
.image_8 {
|
||||
width: 0.2rem;
|
||||
height: 0.2rem;
|
||||
}
|
||||
.text_19 {
|
||||
margin-left: 0.095rem;
|
||||
margin-top: 0.06rem;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.11rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.group_8 {
|
||||
height: 0.32rem;
|
||||
position: relative;
|
||||
.image_3 {
|
||||
width: 0.3rem;
|
||||
height: 0.3rem;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.text_8 {
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
.text_43 {
|
||||
position: absolute;
|
||||
left: 0.37rem;
|
||||
top: 0.02rem;
|
||||
}
|
||||
.text_9 {
|
||||
color: rgb(184, 184, 184);
|
||||
font-size: 0.12rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.12rem;
|
||||
position: absolute;
|
||||
right: 15rpx;
|
||||
top: 0.035rem;
|
||||
}
|
||||
.text_11 {
|
||||
color: rgb(184, 184, 184);
|
||||
font-size: 0.12rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.12rem;
|
||||
position: absolute;
|
||||
left: 0.37rem;
|
||||
bottom: 0;
|
||||
}
|
||||
.text_20 {
|
||||
position: absolute;
|
||||
left: 0.36rem;
|
||||
top: 0.02rem;
|
||||
}
|
||||
}
|
||||
.button {
|
||||
margin-top: 0.18rem;
|
||||
padding: 0.13rem 0 0.12rem;
|
||||
align-self: center;
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 0.15rem;
|
||||
line-height: 0.16rem;
|
||||
letter-spacing: 0.03rem;
|
||||
white-space: nowrap;
|
||||
background-color: #3cb4fb;
|
||||
border-radius: 100rpx;
|
||||
width: 3.1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.imgList {
|
||||
image {
|
||||
// flex: 31%;
|
||||
width: 0.94rem;
|
||||
height: 0.91rem;
|
||||
margin: 0.01rem;
|
||||
}
|
||||
.group_10 {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,565 @@
|
|||
<template>
|
||||
<view>
|
||||
<u-navbar title="发布"></u-navbar>
|
||||
<view class="flex-col page">
|
||||
<view class="flex-col group">
|
||||
<view class="flex-col items-center text-wrapper">
|
||||
<u-input :maxlength='vuex_user.isAttestationGLY ? 35 : 20' type="text" v-model='title'
|
||||
:custom-style="{fontSize:'32rpx'}"
|
||||
@focus="inputFocus" placeholder="添加标题" class="text_1" />
|
||||
</view>
|
||||
<view class="flex-col items-start section_3">
|
||||
<view class="group_1">
|
||||
<u-input type="textarea" v-model='content' @click="shuru" @blur="inputBlur" @focus="inputFocus"
|
||||
maxlength="300" :custom-style="textareaStyle" placeholder="添加正文" />
|
||||
</view>
|
||||
<view class="flex-col section_5" v-if="type == 1">
|
||||
<scroll-view scroll-x="true">
|
||||
<view class="flex-row group_5">
|
||||
<view v-for="(item, index) in tabs" :key="index"
|
||||
class="flex-col items-center text-wrapper_1"
|
||||
:class="{ 'text-wrapper_2': arr1.includes(item.name) }"
|
||||
@click="current(index, item)">
|
||||
<image
|
||||
src="/static/common/img/icon-lineRounded.png"
|
||||
class="image_3"
|
||||
/>
|
||||
<text class="text_13" :class="{ 'text_16': arr1.includes(item.name) }">{{ item.name
|
||||
}}</text>
|
||||
</view>
|
||||
<!-- <view class="flex-col items-center text-wrapper_2"><text class="text_16">找工作</text></view> -->
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<view class="justify-between section_4">
|
||||
<view class="flex-row expression-box" @click='emoji = !emoji'>
|
||||
<image src="/static/common/img/icon-happy-face.png"
|
||||
class="image_3" />
|
||||
<text class="text_10">表情</text>
|
||||
</view>
|
||||
|
||||
<view class="flex-row group_2">
|
||||
<!-- <view class="flex-row">
|
||||
<text class="text_9">@</text>
|
||||
<text class="text_10">用户</text>
|
||||
</view> -->
|
||||
<!-- <view class="flex-row group_4">
|
||||
<image src="/static/common/img/16535374509810688026.png" class="image_4" />
|
||||
<text class="text_11">位置</text>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="uping">
|
||||
<u-upload :max-size="5 * 1024 * 1024" max-count="9" :header='header'
|
||||
:action="$u.http.config.baseUrl + action" @on-success="onSuccess" @on-remove="onRemove"
|
||||
ref="uUpload" width="140" height="140"></u-upload>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-col items-center text-wrapper_4" @click="onRelease"><text class="text_18">发 布</text></view>
|
||||
<!-- emoji 表情 -->
|
||||
<div @click='emoji = !emoji' class='back' v-show="emoji"></div>
|
||||
<swiper class="slider" :current="emojicurrent" :class="emoji ? 'emojishow' : ''">
|
||||
<swiper-item v-for="(item, key) in emojiData" :key="key" class="slider-emoji"
|
||||
:class="[key == emojiData.length - 1 ? 'lastbox' : '']">
|
||||
<text v-for="(value, index) in item" :key="index" @click="selemoji(value)" class="slider-emoji-icon">{{
|
||||
value }}</text>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<u-top-tips ref="uTips" :navbar-height="0"></u-top-tips>
|
||||
<u-toast ref="uToast"/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Debounce } from '../../../common/utils.js'
|
||||
import emoji from "../../../static/common/js/emoji";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
textareaStyle: {
|
||||
width: "80%",
|
||||
minHeight: "300rpx"
|
||||
},
|
||||
fileList: [],
|
||||
title: '',
|
||||
content: '',
|
||||
emojiData: [],
|
||||
emoji: false,
|
||||
emojicurrent: 0,
|
||||
header: {
|
||||
Authorization: ""
|
||||
},
|
||||
action: '/app/User/File',
|
||||
imgData: [],
|
||||
schoolId: "",
|
||||
sysSignStr: [],
|
||||
num: "",
|
||||
tabs: [],
|
||||
arr1: [],
|
||||
type: "",
|
||||
url: false,
|
||||
time: null,
|
||||
};
|
||||
},
|
||||
onLoad(e) {
|
||||
this.header.Authorization = "Bearer " + this.vuex_token;
|
||||
this.schoolId = e.Id
|
||||
this.type = e.type
|
||||
this.url = e.url
|
||||
this.emojiInit();
|
||||
this.getSign()
|
||||
},
|
||||
methods: {
|
||||
// 提示
|
||||
tips(title, type, time) {
|
||||
this.$refs.uToast.show({
|
||||
title: title ? title : "",
|
||||
type: type ? type : "success",
|
||||
duration: time ? time + "" : "1000",
|
||||
});
|
||||
},
|
||||
getSign() {
|
||||
this.$u.apiList.GetSign().then((res) => {
|
||||
if (!this.vuex_user.isAttestationQY) {
|
||||
this.tabs = res.filter(item => {
|
||||
return item.name != '企业招聘'
|
||||
})
|
||||
} else {
|
||||
this.tabs = res
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
inputFocus() {
|
||||
this.emoji = false;
|
||||
},
|
||||
current(i, item) {
|
||||
if (this.arr1.includes(item.name)) {
|
||||
this.arr1.splice(this.arr1.indexOf(item.name), 1)
|
||||
|
||||
} else {
|
||||
this.arr1.push(item.name)
|
||||
|
||||
}
|
||||
},
|
||||
onRelease() {
|
||||
// uni.$emit('helpAdd')
|
||||
// uni.switchTab({
|
||||
// url: '/pages/AlumniCircle/alumnus/alumnus?add=true',
|
||||
// });
|
||||
// return
|
||||
if (!this.time) {
|
||||
|
||||
}
|
||||
if (this.title === "") {
|
||||
this.tips('请输入标题', 'error')
|
||||
return
|
||||
}
|
||||
if (this.content === "") {
|
||||
this.tips('请输入内容', 'error')
|
||||
return
|
||||
}
|
||||
// let files = this.$refs.uUpload.lists[0];
|
||||
|
||||
if (this.type == 1) {
|
||||
if (this.arr1 == "") {
|
||||
this.tips("请选择标签", "error")
|
||||
return
|
||||
}
|
||||
}
|
||||
let file = this.imgData.join(',')
|
||||
// if(!file){
|
||||
// this.tips("请上传图片","error");
|
||||
// return false
|
||||
// }
|
||||
let sysSignStr = this.arr1.join(',')
|
||||
const data = {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
path: file,
|
||||
forwardId: "",
|
||||
sysSignStr: sysSignStr,
|
||||
userId: this.vuex_user.id,
|
||||
schoolId: this.schoolId,
|
||||
}
|
||||
|
||||
if (this.type == 0) {
|
||||
data.sysSignStr = ""
|
||||
this.onJourna(data)
|
||||
} else if (this.type == 1) {
|
||||
this.onHelp(data)
|
||||
}
|
||||
},
|
||||
//发布学校资讯
|
||||
onJourna: Debounce(function (data) {
|
||||
this.$u.apiList.InsertJournaArticle(data).then((res) => {
|
||||
/* uni.showToast({
|
||||
title: "发布成功",
|
||||
duration: 2000,
|
||||
}); */
|
||||
this.$refs.uToast.show({
|
||||
title: '发布成功',
|
||||
type: 'success',
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: "../../../pages/my/my/my"
|
||||
});
|
||||
}, 1000)
|
||||
})
|
||||
}, 1000),
|
||||
//发布帮帮资讯
|
||||
onHelp: Debounce(function (data) {
|
||||
this.$u.apiList.InsertHelpArticle(data).then((res) => {
|
||||
/* uni.showToast({
|
||||
title: "发布成功",
|
||||
duration: 2000,
|
||||
}); */
|
||||
this.$refs.uToast.show({
|
||||
title: '发布成功',
|
||||
type: 'success',
|
||||
})
|
||||
uni.$emit('helpAdd')
|
||||
setTimeout(() => {
|
||||
if (this.url) {
|
||||
uni.switchTab({
|
||||
url: '../../AlumniCircle/alumnus/alumnus?add=true'
|
||||
});
|
||||
} else {
|
||||
uni.switchTab({
|
||||
url: "../../../pages/my/my/my"
|
||||
});
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
}, 1000),
|
||||
onSuccess(res) {
|
||||
|
||||
this.imgData.push(res.data)
|
||||
},
|
||||
onRemove(index, lists) {
|
||||
let imgs = []
|
||||
lists.forEach(item => {
|
||||
imgs.push(item.response.data)
|
||||
})
|
||||
this.imgData = imgs
|
||||
},
|
||||
inputBlur() {
|
||||
;
|
||||
},
|
||||
shuru() {
|
||||
;
|
||||
},
|
||||
selemoji(m) {
|
||||
|
||||
this.content += m;
|
||||
},
|
||||
// 表情初始化
|
||||
emojiInit() {
|
||||
var number = emoji.length;
|
||||
// var page = Math.ceil(emoji.length / number);
|
||||
var page = 1;
|
||||
for (let i = 0; i < page; i++) {
|
||||
this.emojiData[i] = [];
|
||||
for (let k = 0; k < number; k++) {
|
||||
emoji[i * number + k] ?
|
||||
this.emojiData[i].push(emoji[i * number + k]) :
|
||||
"";
|
||||
}
|
||||
}
|
||||
},
|
||||
//返回上一级
|
||||
router() {
|
||||
if (this.url) {
|
||||
uni.switchTab({
|
||||
url: '../../AlumniCircle/alumnus/alumnus'
|
||||
});
|
||||
} else {
|
||||
uni.switchTab({
|
||||
url: '../../my/my/my'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.emojishow {
|
||||
height: 3rem !important;
|
||||
}
|
||||
|
||||
.back {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
background: #fff;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.slider {
|
||||
background: #fff;
|
||||
width: 7.75rem;
|
||||
height: 0rem;
|
||||
transition: all 0.3s;
|
||||
box-shadow: 0 0 4px #999;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
|
||||
.slider-emoji {
|
||||
overflow-y: scroll;
|
||||
width: 100vw !important;
|
||||
}
|
||||
|
||||
&-emoji {
|
||||
width: 6.75rem;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
&-icon {
|
||||
font-size: 0.265rem;
|
||||
display: inline-block;
|
||||
width: 11%;
|
||||
text-align: center;
|
||||
padding: 0.02rem 0;
|
||||
border-radius: 0.1rem;
|
||||
// border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
&-icon:active {
|
||||
background: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
// padding-bottom: 0.5rem;
|
||||
overflow-y: auto;
|
||||
width: calc(100% - 48rpx);
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
border-radius: 24rpx;
|
||||
margin: 28rpx auto 0;
|
||||
|
||||
.group {
|
||||
padding-top: 0.015rem;
|
||||
|
||||
.text-wrapper {
|
||||
padding: 20rpx 40rpx;
|
||||
background-color: rgb(255, 255, 255);
|
||||
box-shadow: 0.00018rem 0.005rem rgba(0, 0, 0, 0.1);
|
||||
|
||||
.text_1 {
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 32rpx;
|
||||
font-family: Adobe Heiti Std;
|
||||
line-height: 0.24rem;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.section_3 {
|
||||
margin-top: 0.015rem;
|
||||
padding: 0.13rem 0 0.24rem;
|
||||
background-color: rgb(255, 255, 255);
|
||||
box-shadow: 0.00018rem 0.005rem rgba(0, 0, 0, 0.03);
|
||||
|
||||
.group_1 {
|
||||
width: 100%;
|
||||
padding: 0 40rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.uping {
|
||||
width: 100%;
|
||||
padding: 0 40rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.section_4 {
|
||||
margin-top: 0.01rem;
|
||||
// padding: 0.12rem 0.28rem 0.14rem 0.2rem;
|
||||
padding: 30rpx 40rpx;
|
||||
background-color: rgb(255, 255, 255);
|
||||
box-shadow: 0.00018rem 0.005rem rgba(0, 0, 0, 0.03);
|
||||
// width: calc(100% - 0.44rem);
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
border-top: 1px solid #E7E7E7;
|
||||
|
||||
.image_2 {
|
||||
margin-top: 0.02rem;
|
||||
width: 0.23rem;
|
||||
height: 0.18rem;
|
||||
}
|
||||
|
||||
.expression-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 128rpx;
|
||||
height: 60rpx;
|
||||
background: #F6F8F9;
|
||||
border-radius: 200rpx 200rpx 200rpx 200rpx;
|
||||
}
|
||||
|
||||
.image_3 {
|
||||
margin-right: 8rpx;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
|
||||
.group_2 {
|
||||
margin-top: 0.01rem;
|
||||
|
||||
.group_4 {
|
||||
margin-left: 0.3rem;
|
||||
margin-bottom: 0.02rem;
|
||||
|
||||
.image_4 {
|
||||
flex-shrink: 0;
|
||||
width: 0.14rem;
|
||||
height: 0.21rem;
|
||||
}
|
||||
|
||||
.text_11 {
|
||||
margin-left: 0.06rem;
|
||||
align-self: center;
|
||||
color: rgb(160, 162, 172);
|
||||
font-size: 0.15rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
}
|
||||
|
||||
.text_9 {
|
||||
color: rgb(80, 80, 81);
|
||||
font-size: 0.24rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.24rem;
|
||||
}
|
||||
|
||||
.text_10 {
|
||||
margin-top: 0.03rem;
|
||||
// color: rgb(160, 162, 172);
|
||||
color: red;
|
||||
font-size: 0.15rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section_5 {
|
||||
margin-top: 0.06rem;
|
||||
padding: 30rpx 40rpx;
|
||||
background-color: rgb(255, 255, 255);
|
||||
box-shadow: 0.00018rem 0.005rem rgba(0, 0, 0, 0.03);
|
||||
// border:1px solid red;
|
||||
width: 100%;
|
||||
// width: 700rpx;
|
||||
|
||||
// overflow: hidden;
|
||||
.group_5 {
|
||||
|
||||
margin-top: 0.3rem;
|
||||
margin-bottom: 0.1rem;
|
||||
|
||||
.text-wrapper_1 {
|
||||
padding: 16rpx 20rpx;
|
||||
// background-color: rgb(255, 255, 255);
|
||||
background: #F6F8F9;
|
||||
border-radius: 200rpx;
|
||||
height: 0.3rem;
|
||||
margin-right: 20rpx;
|
||||
// border: solid 0.005rem rgb(193, 196, 204);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: row;
|
||||
|
||||
.image_3 {
|
||||
margin-right: 8rpx;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
|
||||
.text_13 {
|
||||
// color: #191919;
|
||||
color: rgba(0, 0, 0, 0.90);
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang;
|
||||
line-height: 0.16rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.view_1 {
|
||||
margin-left: 0.055rem;
|
||||
}
|
||||
|
||||
.text-wrapper_2 {
|
||||
background-color: #3cb4fb;
|
||||
border-radius: 200rpx;
|
||||
height: 0.3rem;
|
||||
margin-right: 20rpx;
|
||||
padding: 16rpx 20rpx;
|
||||
|
||||
.text_16 {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 0.13rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.16rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.text-wrapper_3 {
|
||||
margin-left: 0.055rem;
|
||||
padding: 0.07rem 0 0.06rem;
|
||||
flex: 1 1 0.79rem;
|
||||
background-color: rgb(255, 255, 255);
|
||||
border-radius: 0.05rem;
|
||||
height: 0.3rem;
|
||||
border: solid 0.005rem rgb(193, 196, 204);
|
||||
|
||||
.text_17 {
|
||||
color: rgb(160, 162, 172);
|
||||
font-size: 0.13rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.16rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.text-wrapper_4 {
|
||||
margin: 0.31rem 0.24rem 0 0.23rem;
|
||||
padding: 30rpx 0;
|
||||
background-color: #3cb4fb;
|
||||
border-radius: 50rpx;
|
||||
|
||||
.text_18 {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 0.15rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.16rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,854 @@
|
|||
<template>
|
||||
<view>
|
||||
<u-navbar :is-back="true" title="" :custom-back="router">
|
||||
<view class="slot-wrap flex-row search">
|
||||
<u-search v-model='searchText' :input-style="searchStyle" search-icon="search" @custom="search" :search='search' :show-action="false" >
|
||||
</u-search>
|
||||
<u-button style="width: 120rpx;height: 60rpx;border-radius: 50rpx;margin-left: 20rpx;" type="primary" @click="toSearch">搜索</u-button>
|
||||
</view>
|
||||
</u-navbar>
|
||||
<view class="flex-col group_1">
|
||||
<view class="flex-col section_1" v-if="!shoolList.length && !helpList.length && historyWord.length">
|
||||
<view class="section-title">
|
||||
<text class="text_1 text_2">历史记录</text>
|
||||
<image src="/static/common/img/delete.png" style="width: 50rpx;height: 50rpx;"
|
||||
@click="deleteHistory"></image>
|
||||
</view>
|
||||
<view class="justify-left group_2" style="margin-top:0.2rem;">
|
||||
<view class="flex-row" style='flex-wrap:wrap;' >
|
||||
<text class="text_1 text_5" @click='search(item)' v-for="(item, index) in historyWord"
|
||||
:key='index'>{{ item }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<information @clickImg="clickImg" @onStar="onStar" :list="shoolList" type="0" :bottom="bottomState2"
|
||||
v-if="current == 0">
|
||||
</information>
|
||||
<information @onStar="onStar" @clickImg="clickImg" :list="helpList" type="1" :bottom="bottomState" v-else
|
||||
@onSign="onSign">
|
||||
</information>
|
||||
<!-- <view class="flex-col section_2">
|
||||
<text class="text_1 text_6">可能认识的人</text>
|
||||
<view class="flex-col group_4">
|
||||
<scroll-view scroll-x="true" class="flex-row equal-division">
|
||||
<view class="flex-col items-center equal-division-item" @click="toDetil(item.userId)" v-for="(item, index) in mayKnowList"
|
||||
:key="index">
|
||||
<u-avatar :src="$u.http.config.imgUrl+item.imageUrl" class="image_2" ></u-avatar>
|
||||
<text class="text_1 text_7">{{item.name.length > 3? item.name.slice(0, 3) + "...": item.name}}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import noData from '@/components/NoData.vue'
|
||||
import information from "../../../components/Information.vue";
|
||||
export default {
|
||||
components: {
|
||||
noData,
|
||||
information
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchText: '',//搜索内容
|
||||
searchStyle: {
|
||||
width: "100%",
|
||||
},
|
||||
historyWord: [],
|
||||
|
||||
|
||||
searchList: [],
|
||||
isonShow: true,
|
||||
bottomState: false,
|
||||
bottomState2: false,
|
||||
helpList: [],
|
||||
shoolList: [],
|
||||
isLoad: false,
|
||||
PageIndex: 1,
|
||||
PageSize: 10,
|
||||
PageIndex2: 1,
|
||||
PageSize2: 10,
|
||||
Keyword: '全部',
|
||||
Title: "",
|
||||
current: 0,
|
||||
};
|
||||
},
|
||||
onLoad(e) {
|
||||
this.getSearchInfo()
|
||||
this.Keyword = e.class
|
||||
this.current = e.type
|
||||
console.log(this.Keyword, 'this.Keyword', this.current);
|
||||
},
|
||||
methods: {
|
||||
// 获取校友帮帮列表
|
||||
gethelpList() {
|
||||
this.isLoad = true
|
||||
const data = {
|
||||
PageIndex: this.PageIndex,
|
||||
PageSize: this.PageSize,
|
||||
Keyword: this.Keyword,
|
||||
// DateBegin:'',
|
||||
// DateEnd:'',
|
||||
// SkipCount:1,
|
||||
// key:,
|
||||
};
|
||||
if (this.Keyword != '全部') {
|
||||
data.Keyword = this.Keyword
|
||||
}
|
||||
if (this.Title) {
|
||||
// this.helpList = []
|
||||
data.Title = this.Title
|
||||
}
|
||||
|
||||
this.$u.api.GetHelpList(data).then((res) => {
|
||||
console.log(res, 'res--帮帮列表')
|
||||
this.isLoad = false
|
||||
this.total2 = res.total
|
||||
if (this.helpList.length >= this.total2) {
|
||||
this.bottomState = true;
|
||||
return
|
||||
}
|
||||
if (this.total2 == res.items.length) {
|
||||
this.bottomState = true;
|
||||
}
|
||||
this.helpList.push(...res.items)
|
||||
|
||||
});
|
||||
},
|
||||
// 获取学校资讯列表
|
||||
getShoolList() {
|
||||
const data = {
|
||||
PageIndex: this.PageIndex2,
|
||||
PageSize: this.PageSize2,
|
||||
// Keyword:this.Keyword,
|
||||
// DateBegin:'',
|
||||
// DateEnd:'',
|
||||
// SkipCount:1,
|
||||
// key:,
|
||||
};
|
||||
if (this.Title) {
|
||||
// this.shoolList = []
|
||||
data.Title = this.Title
|
||||
}
|
||||
this.$u.api.GetSchoolList(data).then((res) => {
|
||||
this.total1 = res.total
|
||||
if (this.shoolList.length >= this.total1) {
|
||||
this.bottomState2 = true;
|
||||
return
|
||||
}
|
||||
if (this.total1 == res.items.length) {
|
||||
this.bottomState2 = true;
|
||||
}
|
||||
this.shoolList.push(...res.items)
|
||||
});
|
||||
},
|
||||
getList() {
|
||||
if (this.current == 0) {
|
||||
this.shoolList = []
|
||||
this.PageIndex2 = 1
|
||||
this.PageSize2 = 10
|
||||
this.getShoolList();
|
||||
} else {
|
||||
this.helpList = []
|
||||
this.PageIndex = 1
|
||||
this.PageSize = 10
|
||||
if (!this.isLoad) {
|
||||
this.gethelpList();
|
||||
}
|
||||
}
|
||||
},
|
||||
//预览图片
|
||||
clickImg(item) {
|
||||
this.isonShow = false
|
||||
item = this.$u.http.config.imgUrl + item
|
||||
var images = [];
|
||||
images.push(item);
|
||||
uni.previewImage({ // 图片路径必须是一个数组 => ['']
|
||||
current: 0,
|
||||
urls: images,
|
||||
});
|
||||
},
|
||||
//收藏
|
||||
async onStar(val) {
|
||||
console.log('收藏--');
|
||||
// 判断当前学校是否认证,未认证不可收藏
|
||||
const req = {
|
||||
userId: this.vuex_user.id,
|
||||
}
|
||||
const res = await this.$u.apiList.MyPage(req)
|
||||
console.log(JSON.parse(JSON.stringify(res)), 'res')
|
||||
const edcationList = res.edcationList
|
||||
if (!edcationList.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: '认证后可进行收藏操作',
|
||||
type: 'none',
|
||||
})
|
||||
}
|
||||
const findRow = edcationList.find(x => x.isSelected === true);
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: '认证后可进行收藏操作',
|
||||
type: 'none',
|
||||
})
|
||||
}
|
||||
const data = {
|
||||
id: val.id,
|
||||
type: val.type
|
||||
}
|
||||
this.$u.apiList.LikeCollect(data)
|
||||
.then((res) => {
|
||||
if (val.isCllect) {
|
||||
if (val.collectCount > 0) {
|
||||
val.isCllect = false
|
||||
val.collectCount--
|
||||
this.$refs.uToast.show({
|
||||
title: '取消收藏成功',
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
} else {
|
||||
val.isCllect = true
|
||||
val.collectCount++
|
||||
this.$refs.uToast.show({
|
||||
title: '收藏成功',
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$refs.uToast.show({
|
||||
title: '收藏失败',
|
||||
type: 'error',
|
||||
})
|
||||
})
|
||||
},
|
||||
// 删除历史记录
|
||||
deleteHistory() {
|
||||
if (!this.historyWord.length) {
|
||||
this.$u.toast('暂无历史记录')
|
||||
return;
|
||||
}
|
||||
uni.showModal({
|
||||
// title: '提示',
|
||||
content: '是否清空历史记录?',
|
||||
success: (res) => {
|
||||
this.historyWord = []
|
||||
window.localStorage.setItem('searchHistory', JSON.stringify([]))
|
||||
}
|
||||
})
|
||||
},
|
||||
toSearch(){
|
||||
this.search(this.searchText)
|
||||
},
|
||||
|
||||
// 搜索
|
||||
search(value) {
|
||||
this.searchText = value
|
||||
if (!value) {
|
||||
this.$u.toast('请输入搜索词')
|
||||
return;
|
||||
}
|
||||
|
||||
this.Title = value
|
||||
if (this.current == 0) {
|
||||
this.shoolList = []
|
||||
this.getShoolList()
|
||||
} else {
|
||||
this.helpList = []
|
||||
this.gethelpList()
|
||||
}
|
||||
if (!this.historyWord.includes(value)) {
|
||||
this.historyWord.push(value)
|
||||
window.localStorage.setItem('searchHistory', JSON.stringify(this.historyWord))
|
||||
}
|
||||
|
||||
},
|
||||
router() {
|
||||
uni.switchTab({
|
||||
url: '../alumnus/alumnus'
|
||||
})
|
||||
},
|
||||
// 获取搜索界面数据
|
||||
getSearchInfo() {
|
||||
this.historyWord = JSON.parse(window.localStorage.getItem('searchHistory')) || []
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .u-avatar__sex {
|
||||
width: 0.1rem !important;
|
||||
height: 0.1rem !important;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep .u-slot-content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.search ::v-deep {
|
||||
padding: 0 20rpx;
|
||||
|
||||
// .u-content {
|
||||
// border-bottom-left-radius: 0 !important;
|
||||
// border-top-left-radius: 0 !important;
|
||||
// padding:0,
|
||||
// }
|
||||
|
||||
.u-input__input {
|
||||
width: 0.25rem;
|
||||
min-height: 0.32rem !important;
|
||||
padding-left: 0.1rem;
|
||||
font-size: 0.12rem;
|
||||
}
|
||||
|
||||
.u-input {
|
||||
background-color: rgb(242, 242, 242);
|
||||
border-radius: 50px;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
border-top-right-radius: 0 !important;
|
||||
padding-left: 0.05rem
|
||||
}
|
||||
}
|
||||
|
||||
.group_1 {
|
||||
padding: 0.14rem 0rem 0.2rem;
|
||||
flex: 1 1 auto;
|
||||
overflow-y: auto;
|
||||
|
||||
.section_1 {
|
||||
padding: 0.2rem 0.17rem;
|
||||
background-color: rgb(255, 255, 255);
|
||||
border-radius: 0.1rem;
|
||||
|
||||
.section-title {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.text_2 {
|
||||
color: rgb(56, 58, 63);
|
||||
font-size: 0.16rem;
|
||||
white-space: nowrap;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.group_2 {
|
||||
margin-top: 0.23rem;
|
||||
padding: 0 0.015rem;
|
||||
color: rgb(63, 63, 63);
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.13rem;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
|
||||
.text_3 {
|
||||
text-transform: uppercase;
|
||||
position: absolute;
|
||||
left: 0.015rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.text_5 {
|
||||
border: 2rpx solid rgba(0, 0, 0, 0.1);
|
||||
;
|
||||
border-radius: 40rpx;
|
||||
padding: 20rpx;
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section_2 {
|
||||
margin-top: 0.18rem;
|
||||
padding: 0.2rem 0.17rem;
|
||||
background-color: rgb(255, 255, 255);
|
||||
border-radius: 0.1rem;
|
||||
|
||||
.text_6 {
|
||||
// margin-left: 0.17rem;
|
||||
color: rgb(56, 58, 63);
|
||||
font-size: 0.16rem;
|
||||
line-height: 0.17rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.group_4 {
|
||||
margin-top: 0.15rem;
|
||||
|
||||
// padding: 0.8rem 0 0.01rem;
|
||||
// position: relative;
|
||||
// .section_3 {
|
||||
// margin-left: 0.17rem;
|
||||
// margin-right: 0.2rem;
|
||||
// background-image: url("https://codefun-proj-user-res-1256085488.cos.ap-guangzhou.myqcloud.com/6216dee45a7e3f031061d0f1/621c59e162a7d90011002985/16460344151483836600.png");
|
||||
// background-size: 100% 100%;
|
||||
// background-repeat: no-repeat;
|
||||
// height: 0.2rem;
|
||||
// }
|
||||
.equal-division {
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: auto;
|
||||
|
||||
::v-deep .uni-scroll-view-content {
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// position: absolute;
|
||||
.equal-division-item {
|
||||
padding: 0.065rem 0 0.05rem;
|
||||
margin-right: 6%;
|
||||
|
||||
.text_7 {
|
||||
margin-top: 0.095rem;
|
||||
color: rgb(63, 63, 63);
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.13rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text_8 {
|
||||
margin-top: 0.06rem;
|
||||
color: rgb(46, 155, 255);
|
||||
font-size: 0.1rem;
|
||||
line-height: 0.1rem;
|
||||
white-space: nowrap;
|
||||
background: #eaf5ff;
|
||||
border-radius: 0.2rem;
|
||||
padding: 0.05rem 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.equal-division-item_1 {
|
||||
padding: 0.065rem 0 0.055rem;
|
||||
flex: 1 1 0.66rem;
|
||||
|
||||
.text_9 {
|
||||
margin-top: 0.095rem;
|
||||
color: rgb(63, 63, 63);
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.13rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text_10 {
|
||||
margin-top: 0.15rem;
|
||||
color: rgb(46, 155, 255);
|
||||
font-size: 0.1rem;
|
||||
line-height: 0.1rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.equal-division-item_2 {
|
||||
padding: 0.065rem 0.035rem 0.06rem 0.14rem;
|
||||
flex: 1 1 0.66rem;
|
||||
|
||||
.text_11 {
|
||||
margin-top: 0.095rem;
|
||||
align-self: center;
|
||||
color: rgb(63, 63, 63);
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.13rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text_12 {
|
||||
margin-top: 0.15rem;
|
||||
align-self: center;
|
||||
color: rgb(46, 155, 255);
|
||||
font-size: 0.1rem;
|
||||
line-height: 0.095rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.equal-division-item_3 {
|
||||
padding: 0.05rem 0.065rem 0.06rem 0.14rem;
|
||||
flex: 1 1 0.66rem;
|
||||
|
||||
.text_13 {
|
||||
margin-top: 0.11rem;
|
||||
align-self: flex-end;
|
||||
color: rgb(63, 63, 63);
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.13rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text_14 {
|
||||
margin-right: 0.07rem;
|
||||
margin-top: 0.15rem;
|
||||
align-self: flex-end;
|
||||
color: rgb(46, 155, 255);
|
||||
font-size: 0.1rem;
|
||||
line-height: 0.095rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.equal-division-item_4 {
|
||||
padding: 0.05rem 0 0.06rem;
|
||||
flex: 1 1 0.66rem;
|
||||
|
||||
.text_15 {
|
||||
margin-top: 0.12rem;
|
||||
color: rgb(63, 63, 63);
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.13rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text_16 {
|
||||
margin-top: 0.15rem;
|
||||
color: rgb(46, 155, 255);
|
||||
font-size: 0.1rem;
|
||||
line-height: 0.095rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.image_2 {
|
||||
border-radius: 50%;
|
||||
width: 0.4rem;
|
||||
height: 0.4rem;
|
||||
box-shadow: 0 0 1px #6f6f6f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section_4 {
|
||||
margin-top: 0.14rem;
|
||||
padding: 0.14rem 0.21rem 0.25rem;
|
||||
background-color: rgb(255, 255, 255);
|
||||
border-radius: 0.1rem;
|
||||
|
||||
.text_17 {
|
||||
color: rgb(56, 58, 63);
|
||||
font-size: 0.18rem;
|
||||
line-height: 0.15rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.group_5 {
|
||||
margin-top: 0.22rem;
|
||||
padding: 0 0.28rem;
|
||||
|
||||
.section_5 {
|
||||
margin-top: 0.04rem;
|
||||
padding: 0.1rem 0.015rem 0.14rem 0.16rem;
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 0.09rem;
|
||||
line-height: 0.075rem;
|
||||
white-space: nowrap;
|
||||
background-image: url("https://codefun-proj-user-res-1256085488.cos.ap-guangzhou.myqcloud.com/6216dee45a7e3f031061d0f1/621c59e162a7d90011002985/16480042463399723422.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 1.16rem;
|
||||
height: 1.16rem;
|
||||
|
||||
.group_7 {
|
||||
margin-top: 0.29rem;
|
||||
|
||||
.text_22 {
|
||||
margin-top: 0.07rem;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
.text_18 {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.text_19 {
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.text_20 {
|
||||
margin-top: 0.07rem;
|
||||
align-self: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.group_8 {
|
||||
margin-bottom: 0.035rem;
|
||||
width: 0.96rem;
|
||||
|
||||
.text_23 {
|
||||
color: rgb(56, 58, 63);
|
||||
font-size: 0.15rem;
|
||||
line-height: 0.15rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.group_9 {
|
||||
color: rgb(56, 58, 63);
|
||||
font-size: 0.13rem;
|
||||
line-height: 0.15rem;
|
||||
white-space: nowrap;
|
||||
padding: 0 0.025rem;
|
||||
|
||||
.section_6 {
|
||||
margin: 0.025rem 0 0.02rem;
|
||||
background-color: rgb(255, 190, 11);
|
||||
width: 0.1rem;
|
||||
height: 0.1rem;
|
||||
}
|
||||
|
||||
.text_24 {
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
|
||||
.section_7 {
|
||||
margin: 0.015rem 0 0.03rem;
|
||||
background-color: rgb(251, 86, 7);
|
||||
width: 0.1rem;
|
||||
height: 0.1rem;
|
||||
}
|
||||
|
||||
.text_25 {
|
||||
margin-left: 0.095rem;
|
||||
}
|
||||
|
||||
.section_8 {
|
||||
margin: 0.025rem 0 0.02rem;
|
||||
background-color: rgb(131, 56, 236);
|
||||
width: 0.1rem;
|
||||
height: 0.1rem;
|
||||
}
|
||||
|
||||
.text_26 {
|
||||
margin-left: 0.095rem;
|
||||
}
|
||||
|
||||
.section_9 {
|
||||
margin: 0.015rem 0 0.03rem;
|
||||
background-color: rgb(58, 134, 255);
|
||||
width: 0.1rem;
|
||||
height: 0.1rem;
|
||||
}
|
||||
|
||||
.text_27 {
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
|
||||
.section_10 {
|
||||
margin: 0.015rem 0 0.03rem;
|
||||
background-color: rgb(83, 207, 142);
|
||||
width: 0.1rem;
|
||||
height: 0.1rem;
|
||||
}
|
||||
|
||||
.text_28 {
|
||||
margin-left: 0.095rem;
|
||||
}
|
||||
}
|
||||
|
||||
.view {
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.view_1 {
|
||||
margin-top: 0.045rem;
|
||||
}
|
||||
|
||||
.view_2 {
|
||||
margin-top: 0.03rem;
|
||||
}
|
||||
|
||||
.view_3 {
|
||||
margin-top: 0.045rem;
|
||||
}
|
||||
|
||||
.view_4 {
|
||||
margin-top: 0.035rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text_1 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.userList {
|
||||
background: #fff;
|
||||
|
||||
.list-item {
|
||||
padding-left: 0.2rem;
|
||||
}
|
||||
|
||||
.image_1 {
|
||||
align-self: center;
|
||||
width: 0.4rem;
|
||||
height: 0.4rem;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 1px #6f6f6f;
|
||||
}
|
||||
|
||||
.right-section {
|
||||
margin-left: 0.15rem;
|
||||
padding: 0.14rem 0 0.18rem;
|
||||
flex: 1 1 auto;
|
||||
box-shadow: 0px 0.005rem rgb(234, 234, 234);
|
||||
height: 0.66rem;
|
||||
}
|
||||
|
||||
.top-group {
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
|
||||
.text_6 {
|
||||
margin-top: 0.09rem;
|
||||
color: rgb(180, 182, 189);
|
||||
font-size: 0.12rem;
|
||||
line-height: 0.12rem;
|
||||
letter-spacing: 0.012rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text_2 {
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.15rem;
|
||||
line-height: 0.14rem;
|
||||
letter-spacing: 0.015rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text_4 {
|
||||
margin-bottom: 0.05rem;
|
||||
color: rgb(193, 196, 204);
|
||||
font-size: 0.12rem;
|
||||
line-height: 0.095rem;
|
||||
letter-spacing: 0.012rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text_11 {
|
||||
margin-bottom: 0.03rem;
|
||||
color: rgb(2, 2, 2);
|
||||
font-size: 0.15rem;
|
||||
line-height: 0.14rem;
|
||||
letter-spacing: 0.015rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.right-text-wrapper {
|
||||
padding: 0.035rem 0.08rem;
|
||||
color: rgb(115, 129, 255);
|
||||
margin-left: 0.1rem;
|
||||
font-size: 0.11rem;
|
||||
line-height: 0.11rem;
|
||||
letter-spacing: 0.011rem;
|
||||
white-space: nowrap;
|
||||
background-color: rgba(115, 129, 255, 0.1);
|
||||
border-radius: 0.09rem;
|
||||
height: 0.18rem;
|
||||
}
|
||||
|
||||
.text_13 {
|
||||
margin-right: 0.03rem;
|
||||
}
|
||||
|
||||
// .group_2 {
|
||||
// padding-bottom: 0.15rem;
|
||||
// flex: 1 1 auto;
|
||||
// overflow-y: auto;
|
||||
// }
|
||||
|
||||
.group_4 {
|
||||
padding: 0 0.01rem;
|
||||
padding-left: 0.2rem;
|
||||
}
|
||||
|
||||
.group_5 {
|
||||
padding-left: 0.2rem;
|
||||
margin-top: 0.015rem;
|
||||
}
|
||||
|
||||
.group_4:active,
|
||||
.group_5:active {
|
||||
background: #efefef;
|
||||
}
|
||||
|
||||
.group_8 {
|
||||
padding-left: initial;
|
||||
}
|
||||
|
||||
.view_2 {
|
||||
margin-left: 0.11rem;
|
||||
padding: 0.18rem 0.035rem 0.14rem;
|
||||
height: 0.67rem;
|
||||
margin-right: 0.03rem;
|
||||
}
|
||||
|
||||
.view_4 {
|
||||
margin-left: 0.16rem;
|
||||
padding: 0.15rem 0 0.14rem;
|
||||
height: 0.67rem;
|
||||
}
|
||||
|
||||
.view_3 {
|
||||
margin-right: initial;
|
||||
}
|
||||
|
||||
.view_5 {
|
||||
margin-right: initial;
|
||||
}
|
||||
|
||||
.text_16 {
|
||||
margin-top: 0.07rem;
|
||||
color: rgb(193, 196, 204);
|
||||
line-height: 0.095rem;
|
||||
margin-right: 0.095rem;
|
||||
}
|
||||
|
||||
.text_28 {
|
||||
margin-top: initial;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0.17rem;
|
||||
}
|
||||
|
||||
.text_8 {
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
|
||||
.text_9 {
|
||||
margin-right: 0.025rem;
|
||||
}
|
||||
|
||||
.view_6 {
|
||||
color: initial;
|
||||
font-size: initial;
|
||||
line-height: initial;
|
||||
letter-spacing: initial;
|
||||
white-space: initial;
|
||||
}
|
||||
|
||||
.text_15 {
|
||||
margin-bottom: initial;
|
||||
color: rgb(180, 182, 189);
|
||||
line-height: 0.12rem;
|
||||
margin-top: 0.08rem;
|
||||
}
|
||||
|
||||
.view_19 {
|
||||
margin-left: 0.045rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,812 @@
|
|||
<template>
|
||||
<view>
|
||||
<u-navbar back-text="" title="个人主页"></u-navbar>
|
||||
<!-- 用户信息详情 -->
|
||||
<view class="user-detail">
|
||||
<!-- 背景图 -->
|
||||
<view class="user-bg">
|
||||
<image :src="mybg"></image>
|
||||
</view>
|
||||
<!-- 详细信息 -->
|
||||
<view class="user-detail-info">
|
||||
<view class="user-detail-top">
|
||||
<!-- 头像 私信 关注 -->
|
||||
<view class="user-avatar-box">
|
||||
<view class="user-detail-info-avatar">
|
||||
<u-avatar class="image_2" size="144" :src="$u.http.config.imgUrl + userInfo.baseData.head">
|
||||
</u-avatar>
|
||||
</view>
|
||||
<view class="user-operate">
|
||||
<u-button shape="circle" v-if="userInfo.carewState&&vuex_user.id !== userId" :type="userInfo.carewState.includes('未关注') ? 'primary' : 'default'" @click="onFollow">{{
|
||||
userInfo.carewState.includes('未关注')?'关注':userInfo.carewState }}</u-button>
|
||||
<view class="user-message" @click="GoChat" v-if="vuex_user.id !== userId">
|
||||
<image src="/static/common/img/homepage/message.png"></image>
|
||||
</view>
|
||||
<view v-else style="height: 96rpx;"></view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 用户姓名 -->
|
||||
<view class="user-name">
|
||||
<text>{{ attestation.name||userInfo.baseData.name || "-" }}</text>
|
||||
<image v-if="userInfo.isCertifyStatus" src="/static/common/img/homepage/frame.png"></image>
|
||||
</view>
|
||||
<!-- 用户学校信息 -->
|
||||
<view class="user-school" v-if="baseShow === true && otherUserType === 0">
|
||||
<text>{{ findRow.schoolName || "-" }}</text>
|
||||
<!-- 学院 -->
|
||||
<text v-if="findRow.college">{{
|
||||
findRow.college
|
||||
}}</text>
|
||||
<text class="text_2" style="margin-right: 0.05rem" v-if="findRow.major">{{ findRow.major }}</text>
|
||||
<!-- 年级 -->
|
||||
<text class="text_2" v-if="findRow.startYear">{{
|
||||
findRow.startYear + "级"
|
||||
}}</text>
|
||||
</view>
|
||||
<!-- 用户地址 先不放开 -->
|
||||
<view class="user-identity"> </view>
|
||||
<!-- 获赞 粉丝 关注 -->
|
||||
<!-- <view class="user-like">
|
||||
<view class="likes" v-for="(item, index) in userlikes" :key="index">
|
||||
<text class="like-num">{{ item.num }}</text>
|
||||
<text class="like-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="user-tabs">
|
||||
<view class="user-tabs-item" :class="{ 'tabs-active': swiperCurrent == index }"
|
||||
v-for="(item, index) in userTabs" :key="index" @click="tabsChange(index)">
|
||||
<image :src="swiperCurrent == index ? item.selectedImage : item.image"></image>
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<view class="release-content" v-if="swiperCurrent == 0">
|
||||
<information :list="userList" @onStar="onStar" type="1" :schoolId="schoolId" route="2" :flag="type" :borderRadius="true">
|
||||
</information>
|
||||
</view>
|
||||
<view class="user-info" v-if="swiperCurrent == 1">
|
||||
|
||||
<view class="userinfo-box" v-if="userInfo">
|
||||
<view class="userinfo-title">
|
||||
<text>基本信息</text>
|
||||
</view>
|
||||
<view class="userinfo-detail">
|
||||
<view class="justify-between detail-row">
|
||||
<text class="detail-title">手机号码</text>
|
||||
<text class="detail-content">{{ userInfo.baseData.phone }}</text>
|
||||
</view>
|
||||
<view class="justify-between detail-row">
|
||||
<text class="detail-title">年龄</text>
|
||||
<text class="detail-content">{{
|
||||
userInfo.baseData.age
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="justify-between detail-row">
|
||||
<text class="detail-title">现居地(区)</text>
|
||||
<text class="detail-content">{{
|
||||
userInfo.baseData.address
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="justify-between detail-row">
|
||||
<text class="detail-title">工作领域</text>
|
||||
<text class="detail-content">{{
|
||||
userInfo.baseData.workField
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 教育经历 -->
|
||||
<view class="" v-if="userInfo && otherUserType === 0">
|
||||
<view class="userinfo-title"><text class="">教育经历</text>
|
||||
</view>
|
||||
<view class="userinfo-detail">
|
||||
<view class="detail-row school-row" v-for="(item, index) in userInfo.edcationList"
|
||||
v-if="item.certifyStatus == 1 || true" :key="index">
|
||||
<view class="detail-row-item">
|
||||
<image :src="$u.http.config.imgUrl + item.schoolLogo.slice(1)" />
|
||||
<view class="school-info">
|
||||
<view class="school-name">
|
||||
<view class="text_24">{{ item.schoolName }}</view>
|
||||
<view class="text_25 status-box" :class="item.certifyStatus == 0
|
||||
? 'color2'
|
||||
: item.certifyStatus == 1
|
||||
? 'color1'
|
||||
: 'color3'
|
||||
">{{ certifyArr[item.certifyStatus] }}</view>
|
||||
</view>
|
||||
<view class="professional-info">
|
||||
<view>{{ item.startYear }}届</view>
|
||||
<view class="text_27">{{ item.major }}</view>
|
||||
<view class="text_28">{{ item.educationStr }}生</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
<!-- 任职院校 -->
|
||||
<view class="" v-if="userInfo && otherUserType === 1">
|
||||
<view class="userinfo-title"><text class="text_21">任职院校</text>
|
||||
</view>
|
||||
<view class="userinfo-detail">
|
||||
<view class="detail-row school-row" v-for="(item, index) in userInfo.edcationList"
|
||||
v-if="item.certifyStatus == 1 || true" :key="index">
|
||||
|
||||
<view class="detail-row-item">
|
||||
<image :src="$u.http.config.imgUrl + item.logo.slice(1)" class="image_17" />
|
||||
<view class="school-info">
|
||||
<view class="school-name">
|
||||
<text class="text_24">{{ item.school }}</text>
|
||||
<text class="text_25 status-box" :class="item.certifyStatus == 0
|
||||
? 'color2'
|
||||
: item.certifyStatus == 1
|
||||
? 'color1'
|
||||
: 'color3'
|
||||
">{{ certifyArr[item.certifyStatus] }}</text>
|
||||
</view>
|
||||
<view class="flex-row group_20">
|
||||
<text>{{ item.schoolJob }}</text>
|
||||
<!-- <text>{{item.startYear}}年入学</text> -->
|
||||
<!-- <text class="text_27">{{item.major}}</text> -->
|
||||
<!-- <text class="text_28">{{item.educationStr}}</text> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-toast ref="uToast" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import information from "../../../components/Information.vue";
|
||||
import release from "@/static/common/img/homepage/released.png";
|
||||
import releaseSelected from "@/static/common/img/homepage/released-selected.png";
|
||||
import person from "@/static/common/img/homepage/person.png";
|
||||
import personSelected from "@/static/common/img/homepage/person-selected.png";
|
||||
import mybg1 from '@/static/common/img/my/mybg1.png'
|
||||
import mybg2 from '@/static/common/img/my/mybg2.png'
|
||||
import mybg3 from '@/static/common/img/my/mybg3.png'
|
||||
import mybg4 from '@/static/common/img/my/mybg4.png'
|
||||
import mybg5 from '@/static/common/img/my/mybg5.png'
|
||||
import mybg6 from '@/static/common/img/my/mybg6.png'
|
||||
import mybg7 from '@/static/common/img/my/mybg7.png'
|
||||
import mybg8 from '@/static/common/img/my/mybg8.png'
|
||||
import mybg9 from '@/static/common/img/my/mybg9.png'
|
||||
import mybg10 from '@/static/common/img/my/mybg10.png'
|
||||
import mybg11 from '@/static/common/img/my/mybg11.png'
|
||||
import mybg12 from '@/static/common/img/my/mybg12.png'
|
||||
import mybg13 from '@/static/common/img/my/mybg13.png'
|
||||
import mybg14 from '@/static/common/img/my/mybg14.png'
|
||||
import mybg15 from '@/static/common/img/my/mybg15.png'
|
||||
import mybg16 from '@/static/common/img/my/mybg16.png'
|
||||
import mybg17 from '@/static/common/img/my/mybg17.png'
|
||||
import mybg18 from '@/static/common/img/my/mybg18.png'
|
||||
import mybg19 from '@/static/common/img/my/mybg19.png'
|
||||
import mybg20 from '@/static/common/img/my/mybg20.png'
|
||||
export default {
|
||||
components: {
|
||||
information: information,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
userId: "",
|
||||
swiperCurrent: 0,
|
||||
current: 0,
|
||||
schoolId: "",
|
||||
type: "",
|
||||
userList: [],
|
||||
navList: [
|
||||
{
|
||||
name: "个人信息",
|
||||
},
|
||||
{
|
||||
name: "Ta的发布",
|
||||
},
|
||||
],
|
||||
certifyArr: {
|
||||
0: "未认证",
|
||||
1: "已认证",
|
||||
2: "审核中",
|
||||
},
|
||||
userInfo: {},
|
||||
word: "",
|
||||
otherUserType: true,
|
||||
attestation: {},
|
||||
// 基础信息
|
||||
findRow: {},
|
||||
// 企业信息
|
||||
qyRow: {},
|
||||
// 企业与基础信息切换
|
||||
baseShow: true,
|
||||
// 企业按钮是否存在
|
||||
qyShow: false,
|
||||
userlikes: [
|
||||
{
|
||||
num: 200,
|
||||
name: "获赞",
|
||||
},
|
||||
{
|
||||
num: 200,
|
||||
name: "粉丝",
|
||||
},
|
||||
{
|
||||
num: 200,
|
||||
name: "关注",
|
||||
},
|
||||
],
|
||||
userTabs: [
|
||||
{
|
||||
image: release,
|
||||
selectedImage: releaseSelected,
|
||||
name: "发布",
|
||||
},
|
||||
{
|
||||
image: person,
|
||||
selectedImage: personSelected,
|
||||
name: "个人信息",
|
||||
},
|
||||
],
|
||||
mybg1,
|
||||
mybg2,
|
||||
mybg3 ,
|
||||
mybg4 ,
|
||||
mybg5 ,
|
||||
mybg6 ,
|
||||
mybg7 ,
|
||||
mybg8 ,
|
||||
mybg9 ,
|
||||
mybg10,
|
||||
mybg11,
|
||||
mybg12,
|
||||
mybg13,
|
||||
mybg14,
|
||||
mybg15,
|
||||
mybg16,
|
||||
mybg17,
|
||||
mybg18,
|
||||
mybg19,
|
||||
mybg20,
|
||||
mybg: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
randomBg() {
|
||||
const bgArray = [
|
||||
this.mybg1, this.mybg2, this.mybg3, this.mybg4, this.mybg5,
|
||||
this.mybg6, this.mybg7, this.mybg8, this.mybg9, this.mybg10,
|
||||
this.mybg11, this.mybg12, this.mybg13, this.mybg14, this.mybg15,
|
||||
this.mybg16, this.mybg17, this.mybg18, this.mybg19, this.mybg20
|
||||
];
|
||||
const randomIndex = Math.floor(Math.random() * bgArray.length);
|
||||
return bgArray[randomIndex];
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.mybg = this.randomBg;
|
||||
},
|
||||
onLoad(e) {
|
||||
if (!e.id) {
|
||||
uni.switchTab({
|
||||
url: "../../main/index/index",
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.type = e.type;
|
||||
this.userId = e.id;
|
||||
this.word = e.word;
|
||||
// this.getDetail();
|
||||
// this.getUserSchool();
|
||||
},
|
||||
onShow() {
|
||||
|
||||
this.getDetail();
|
||||
this.mybg = this.randomBg;
|
||||
// 改为在getDetail中调接口
|
||||
/* if (this.current == 0) {
|
||||
setTimeout(() => {
|
||||
|
||||
this.getUserHelp();
|
||||
}, 500);
|
||||
} */
|
||||
},
|
||||
methods: {
|
||||
lookQY() {
|
||||
console.log(7777777);
|
||||
},
|
||||
getUserHelp() {
|
||||
console.log('this.findRow--------------',this.findRow);
|
||||
|
||||
const data = {
|
||||
userId: this.userId,
|
||||
schoolId:this.findRow.schoolId,
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
};
|
||||
this.$u.apiList.Publishs(data).then((res) => {
|
||||
this.userList = res.items;
|
||||
});
|
||||
// 改成只能看本校的
|
||||
/* this.$u.apiList.UserHelp(data).then((res) => {
|
||||
this.userList = res.items;
|
||||
}); */
|
||||
},
|
||||
getDetail() {
|
||||
this.$u.api
|
||||
.getUserInfo({
|
||||
userId: this.userId,
|
||||
})
|
||||
.then((res) => {
|
||||
console.log('res-----',res);
|
||||
|
||||
this.userInfo = res;
|
||||
this.attestation = Object.assign(this.attestation, res.attestation);
|
||||
this.otherUserType = res.userType;
|
||||
// console.log(this.userInfo, 1)
|
||||
this.findRow = res.edcationList[0];
|
||||
if (res.qyAttestation) {
|
||||
this.qyShow = true;
|
||||
this.qyRow = res.qyAttestation;
|
||||
}
|
||||
// 获取个人信息、拿到学校id之后 再查发布(需要学校id)
|
||||
this.getUserHelp();
|
||||
});
|
||||
},
|
||||
// 去聊天
|
||||
GoChat() {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"../../message/dialogBox/dialogBox?id=" + this.userId + "&chatType=0",
|
||||
});
|
||||
},
|
||||
// tabs通知swiper切换
|
||||
tabsChange(index) {
|
||||
if (index == 0) {
|
||||
this.getUserHelp();
|
||||
}
|
||||
this.swiperCurrent = index;
|
||||
},
|
||||
// swiper-item左右移动,通知tabs的滑块跟随移动
|
||||
transition(e) {
|
||||
let dx = e.detail.dx;
|
||||
this.$refs.uTabs.setDx(dx);
|
||||
},
|
||||
// 由于swiper的内部机制问速切题,快换swiper不会触发dx的连续变化,需要在结束时重置状态
|
||||
// swiper滑动结束,分别设置tabs和swiper的状态
|
||||
animationfinish(e) {
|
||||
let current = e.detail.current;
|
||||
this.$refs.uTabs.setFinishCurrent(current);
|
||||
this.swiperCurrent = current;
|
||||
this.current = current;
|
||||
},
|
||||
onFollow() {
|
||||
const data = {
|
||||
userId: this.vuex_user.id,
|
||||
carewId: this.userId,
|
||||
};
|
||||
this.$u.apiList.InsertOrDelFollow(data).then((res) => {
|
||||
this.getDetail();
|
||||
});
|
||||
},
|
||||
getUserSchool() {
|
||||
this.$u.apiList.GetUserSchool().then((res) => {
|
||||
// 学生时
|
||||
if ([0,2].includes(this.vuex_user.userType)) {
|
||||
this.schoolId = res.items.schoolId;
|
||||
}
|
||||
// 教师时
|
||||
if (this.vuex_user.userType === 1) {
|
||||
this.schoolId = res.jzgItems.schoolId;
|
||||
}
|
||||
});
|
||||
},
|
||||
async onStar(val) {
|
||||
console.log("收藏--");
|
||||
// 判断当前学校是否认证,未认证不可收藏
|
||||
const req = {
|
||||
userId: this.vuex_user.id,
|
||||
};
|
||||
const result = await this.$u.apiList.MyPage(req);
|
||||
console.log(JSON.parse(JSON.stringify(result)), "result");
|
||||
const edcationList = result.edcationList;
|
||||
if (!edcationList.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "认证后可进行收藏操作",
|
||||
type: "none",
|
||||
});
|
||||
}
|
||||
// const findRow = edcationList.find((x) => x.isSelected === true);
|
||||
const findRow = edcationList[0];
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "认证后可进行收藏操作",
|
||||
type: "none",
|
||||
});
|
||||
}
|
||||
// return
|
||||
const data = {
|
||||
id: val.id,
|
||||
type: val.type,
|
||||
};
|
||||
this.$u.apiList
|
||||
.LikeCollect(data)
|
||||
.then((res) => {
|
||||
if (val.type == 0) {
|
||||
if (val.isCllect) {
|
||||
val.isCllect = false;
|
||||
val.collectCount -= 1;
|
||||
this.$refs.uToast.show({
|
||||
title: "取消收藏成功",
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
val.isCllect = true;
|
||||
val.collectCount += 1;
|
||||
this.$refs.uToast.show({
|
||||
title: "收藏成功",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
} else if (val.type == 1) {
|
||||
if (val.isCllect) {
|
||||
val.isCllect = false;
|
||||
val.collectCount -= 1;
|
||||
this.$refs.uToast.show({
|
||||
title: "取消收藏成功",
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
val.isCllect = true;
|
||||
val.collectCount += 1;
|
||||
this.$refs.uToast.show({
|
||||
title: "收藏成功",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$refs.uToast.show({
|
||||
title: "收藏失败",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
//返回上一级
|
||||
router() {
|
||||
if (this.type == 0) {
|
||||
uni.switchTab({
|
||||
url: "../../message/msgList/msgList",
|
||||
});
|
||||
} else if (this.type == 1) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"../../message/dialogBox/dialogBox?id=" +
|
||||
this.userId +
|
||||
"&chatType=0&type=0",
|
||||
});
|
||||
} else if (this.type == 2) {
|
||||
this.$u.route({
|
||||
url: "pages/AlumniCircle/Alumni/Alumni",
|
||||
});
|
||||
} else if (this.type == 3) {
|
||||
let url = "pages/main/search/search";
|
||||
if (this.word) {
|
||||
url = "pages/main/search/search?word=" + this.word;
|
||||
}
|
||||
this.$u.route({
|
||||
url: url,
|
||||
});
|
||||
} else if (this.type == 4) {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
} else {
|
||||
uni.switchTab({
|
||||
url: "pages/main/index/index",
|
||||
});
|
||||
}
|
||||
},
|
||||
// scroll-view到底部加载更多
|
||||
onreachBottom() { },
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.user-detail {
|
||||
position: relative;
|
||||
background: #f6f8fa;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.user-bg {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 320rpx;
|
||||
overflow: hidden;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.user-detail-info {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 320rpx;
|
||||
|
||||
.user-detail-top {
|
||||
padding: 0 48rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.user-avatar-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
.user-operate {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
align-items: center;
|
||||
width: 300rpx;
|
||||
justify-content: space-between;
|
||||
padding-top: 20rpx;
|
||||
|
||||
.user-message {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
border-radius: 50%;
|
||||
background: #f6f8f9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
|
||||
image {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-detail-info-avatar {
|
||||
width: 154rpx;
|
||||
height: 154rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #fefcff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: -50rpx;
|
||||
left: 48rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.user-name {
|
||||
margin-top: 15rpx;
|
||||
margin-bottom: 16rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 800;
|
||||
color: #1f2232;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.user-school {
|
||||
text {
|
||||
display: inline-block;
|
||||
background: #f6f8f9;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
padding: 0 10rpx;
|
||||
margin-right: 16rpx;
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.user-like {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
padding: 30rpx 30rpx;
|
||||
|
||||
.likes {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.like-num {
|
||||
font-weight: 800;
|
||||
font-size: 36rpx;
|
||||
color: #1f2232;
|
||||
}
|
||||
|
||||
.like-name {
|
||||
font-weight: 500;
|
||||
font-size: 24rpx;
|
||||
color: #616977;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-tabs {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
.user-tabs-item {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-bottom: 4rpx solid #fff;
|
||||
padding-bottom: 20rpx;
|
||||
color: #8697ac;
|
||||
font-weight: bold;
|
||||
|
||||
image {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs-active {
|
||||
border-bottom: 4rpx solid #48adde;
|
||||
|
||||
text {
|
||||
color: #3cb5fb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-info {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.userinfo-title {
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
height: 60rpx;
|
||||
}
|
||||
|
||||
.userinfo-box {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.userinfo-detail {
|
||||
padding:10rpx 32rpx;
|
||||
background: #fff;
|
||||
border-radius: 32rpx;
|
||||
border: 3rpx solid;
|
||||
border-image: linear-gradient(180deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0), rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1)) 3 3;
|
||||
|
||||
.detail-row {
|
||||
height: 106rpx;
|
||||
line-height: 106rpx;
|
||||
border-bottom: 2rpx solid #F6F8F9;
|
||||
|
||||
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-size: 28rpx;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
font-size: 28rpx;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
image {
|
||||
width: 102rpx;
|
||||
height: 102rpx;
|
||||
}
|
||||
|
||||
.detail-row-item {
|
||||
height: 106rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.school-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 102rpx;
|
||||
|
||||
.school-name {
|
||||
// height: 50%;
|
||||
height: 51rpx;
|
||||
line-height: 51rpx;
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
|
||||
view {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.professional-info {
|
||||
height: 51rpx;
|
||||
line-height: 51rpx;
|
||||
|
||||
view {
|
||||
display: inline-block;
|
||||
margin-right: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #8697AC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.school-row {
|
||||
// line-height: 126rpx;
|
||||
height: 126rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.status-box{
|
||||
width: 100rpx;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
text-align: center;
|
||||
border-radius: 12rpx;
|
||||
font-size: 24rpx;
|
||||
margin-left: 20rpx;
|
||||
font-weight: normal;
|
||||
display: inline-block;
|
||||
|
||||
&.color1 {
|
||||
background-color: #3cb4fb;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.color2 {
|
||||
background-color: #ffeceb;
|
||||
color: #ff453a;
|
||||
}
|
||||
|
||||
&.color3 {
|
||||
background-color: #FFB800;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,367 @@
|
|||
const SCHOOL_CONFIG = {
|
||||
南昌理工: {
|
||||
ai: {
|
||||
name: "南小翼",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://sl.vrgon.com:2222/",
|
||||
type: "http",
|
||||
index: 0,
|
||||
},
|
||||
welcome: {
|
||||
name: "迎新",
|
||||
icon: "/static/common/img/homepage/icon_迎新.png",
|
||||
icon2: "/static/common/img/homepage/icon_迎新_gray.png",
|
||||
url: "https://yxxt.nut.edu.cn:8090/#/",
|
||||
type: "http",
|
||||
index: 4,
|
||||
},
|
||||
repair: {
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "https://bx.nut.edu.cn/#/",
|
||||
type: "http",
|
||||
index: 7,
|
||||
},
|
||||
score: {
|
||||
name: "成绩查询",
|
||||
icon: "/static/common/img/homepage/icon_就业帮助.png",
|
||||
icon2: "/static/common/img/homepage/icon_就业帮助_gray.png",
|
||||
url: "https://iwglxt.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 5,
|
||||
},
|
||||
oldStudent: {
|
||||
name: "老生缴费",
|
||||
icon: "/static/common/img/homepage/icon_缴费.png",
|
||||
icon2: "/static/common/img/homepage/icon_缴费_gray.png",
|
||||
url: "https://pay.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 1,
|
||||
},
|
||||
electricityBill: {
|
||||
name: "网上购电",
|
||||
icon: "/static/common/img/homepage/icon_网上购电.png",
|
||||
icon2: "/static/common/img/homepage/icon_网上购电_gray.png",
|
||||
url: "https://if.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 6,
|
||||
},
|
||||
},
|
||||
新能源: {
|
||||
ai: {
|
||||
name: "源小新",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://ai.tynxy.com:8001/",
|
||||
type: "http",
|
||||
index: 0,
|
||||
},
|
||||
welcome: {
|
||||
name: "迎新",
|
||||
icon: "/static/common/img/homepage/icon_迎新.png",
|
||||
icon2: "/static/common/img/homepage/icon_迎新_gray.png",
|
||||
url: "https://yx.tynxy.com:8090/#/login",
|
||||
type: "http",
|
||||
index: 4,
|
||||
},
|
||||
library: {
|
||||
name: "图书馆",
|
||||
icon: "/static/common/img/homepage/icon_图书借阅.png",
|
||||
icon2: "/static/common/img/homepage/icon_图书借阅_gray.png",
|
||||
url: "https://a.xiumi.us/stage/v5/33A6c/151995615#/",
|
||||
type: "http",
|
||||
index: 10,
|
||||
},
|
||||
score: {
|
||||
name: "成绩查询",
|
||||
icon: "/static/common/img/homepage/icon_就业帮助.png",
|
||||
icon2: "/static/common/img/homepage/icon_就业帮助_gray.png",
|
||||
url: "http://cas.tynxy.com:7171/cas/login/",
|
||||
type: "http",
|
||||
index: 5,
|
||||
},
|
||||
electricityBill: {
|
||||
name: "网上购电",
|
||||
icon: "/static/common/img/homepage/icon_网上购电.png",
|
||||
icon2: "/static/common/img/homepage/icon_网上购电_gray.png",
|
||||
url: "http://vpn.tynxy.com:10081/",
|
||||
type: "http",
|
||||
index: 6,
|
||||
},
|
||||
},
|
||||
亚视: {
|
||||
repair: {
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "http://gdysyx.gdatv.edu.cn:8099/#/",
|
||||
type: "http",
|
||||
index: 7,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取特定学校的所有功能配置
|
||||
* @param {string} schoolName - 学校名称
|
||||
* @returns {Object} - 该学校的所有功能配置
|
||||
*/
|
||||
export const getSchoolConfig = (schoolName = "") => {
|
||||
// 查找匹配的学校配置
|
||||
const matchedSchool = Object.keys(SCHOOL_CONFIG).find((key) =>
|
||||
schoolName.includes(key)
|
||||
);
|
||||
return matchedSchool ? SCHOOL_CONFIG[matchedSchool] : {};
|
||||
};
|
||||
|
||||
// 保留之前的单项获取函数,以便向后兼容(首页使用)
|
||||
export const getAIAssistantConfig = (schoolName = "") => {
|
||||
const config = getSchoolConfig(schoolName);
|
||||
return (
|
||||
config.ai || {
|
||||
name: "ai智能",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "",
|
||||
}
|
||||
);
|
||||
};
|
||||
export const getOldStudentConfig = (schoolName = "") => {
|
||||
const config = getSchoolConfig(schoolName);
|
||||
return (
|
||||
config.oldStudent || {
|
||||
name: "缴费",
|
||||
icon: "/static/common/img/homepage/icon_缴费.png",
|
||||
icon2: "/static/common/img/homepage/icon_缴费_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
}
|
||||
);
|
||||
};
|
||||
/**
|
||||
* 首页功能列表数据
|
||||
*/
|
||||
export const functionListing = [
|
||||
{
|
||||
name: "ai智能",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "",
|
||||
},
|
||||
{
|
||||
name: "缴费",
|
||||
icon: "/static/common/img/homepage/icon_缴费.png",
|
||||
icon2: "/static/common/img/homepage/icon_缴费_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "返校预约",
|
||||
icon: "/static/common/img/homepage/icon_返校预约.png",
|
||||
icon2: "/static/common/img/homepage/icon_返校预约_gray.png",
|
||||
url: "/pages/my/BackSchool/BackSchool",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "心愿单",
|
||||
icon: "/static/common/img/homepage/icon_心愿单.png",
|
||||
icon2: "/static/common/img/homepage/icon_心愿单_gray.png",
|
||||
url: "/pages/my/wishlist/wishlist",
|
||||
type: "page",
|
||||
},
|
||||
// {
|
||||
// name: "查询档案",
|
||||
// icon: "/static/common/img/homepage/icon_查询档案.png",
|
||||
// url: "",
|
||||
// type: "page",
|
||||
// },
|
||||
{
|
||||
name: "全部服务",
|
||||
icon: "/static/common/img/homepage/icon_全部服务.png",
|
||||
icon2: "/static/common/img/homepage/icon_全部服务.png",
|
||||
},
|
||||
];
|
||||
|
||||
// 教师首页配置 vuex_user.userType==1
|
||||
export const TEACHER_CONFIG = [
|
||||
{
|
||||
name: "南小翼",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://sl.vrgon.com:2222/",
|
||||
type: "http",
|
||||
index: 0,
|
||||
},
|
||||
{
|
||||
name: "心愿单",
|
||||
icon: "/static/common/img/homepage/icon_心愿单.png",
|
||||
icon2: "/static/common/img/homepage/icon_心愿单_gray.png",
|
||||
url: "/pages/my/wishlist/wishlist",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "https://bx.nut.edu.cn/#/",
|
||||
type: "http",
|
||||
index: 7,
|
||||
},
|
||||
{
|
||||
name: "DL",
|
||||
icon: "/static/common/img/homepage/icon_DL.png",
|
||||
icon2: "/static/common/img/homepage/icon_DL_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 全部服务
|
||||
*/
|
||||
export const functionListing2 = [
|
||||
{
|
||||
name: "ai智能",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "",
|
||||
},
|
||||
{
|
||||
name: "缴费",
|
||||
icon: "/static/common/img/homepage/icon_缴费.png",
|
||||
icon2: "/static/common/img/homepage/icon_缴费_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "返校预约",
|
||||
icon: "/static/common/img/homepage/icon_返校预约.png",
|
||||
icon2: "/static/common/img/homepage/icon_返校预约_gray.png",
|
||||
url: "/pages/my/BackSchool/BackSchool",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "心愿单",
|
||||
icon: "/static/common/img/homepage/icon_心愿单.png",
|
||||
icon2: "/static/common/img/homepage/icon_心愿单_gray.png",
|
||||
url: "/pages/my/wishlist/wishlist",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "迎新",
|
||||
icon: "/static/common/img/homepage/icon_迎新.png",
|
||||
icon2: "/static/common/img/homepage/icon_迎新_gray.png",
|
||||
url: "",
|
||||
type: "http",
|
||||
},
|
||||
{
|
||||
name: "就业帮助",
|
||||
icon: "/static/common/img/homepage/icon_就业帮助.png",
|
||||
icon2: "/static/common/img/homepage/icon_就业帮助_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "活动报名",
|
||||
icon: "/static/common/img/homepage/icon_活动报名.png",
|
||||
icon2: "/static/common/img/homepage/icon_活动报名_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "",
|
||||
type: "http",
|
||||
},
|
||||
{
|
||||
name: "勤工俭学",
|
||||
icon: "/static/common/img/homepage/icon_勤工俭学.png",
|
||||
icon2: "/static/common/img/homepage/icon_勤工俭学_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "办事指南",
|
||||
icon: "/static/common/img/homepage/icon_办事指南.png",
|
||||
icon2: "/static/common/img/homepage/icon_办事指南_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "图书借阅",
|
||||
icon: "/static/common/img/homepage/icon_图书借阅.png",
|
||||
icon2: "/static/common/img/homepage/icon_图书借阅_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "查询档案",
|
||||
icon: "/static/common/img/homepage/icon_查询档案.png",
|
||||
icon2: "/static/common/img/homepage/icon_查询档案_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "选课",
|
||||
icon: "/static/common/img/homepage/icon_选课.png",
|
||||
icon2: "/static/common/img/homepage/icon_选课_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "DL",
|
||||
icon: "/static/common/img/homepage/icon_DL.png",
|
||||
icon2: "/static/common/img/homepage/icon_DL_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校园跑",
|
||||
icon: "/static/common/img/homepage/icon_校园跑.png",
|
||||
icon2: "/static/common/img/homepage/icon_校园跑_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
];
|
||||
|
||||
export const functionListing3 = [
|
||||
{
|
||||
name: "校友名片",
|
||||
icon: "/static/common/img/homepage/icon_校友名片.png",
|
||||
icon2: "/static/common/img/homepage/icon_校友名片_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校友活动",
|
||||
icon: "/static/common/img/homepage/icon_校友活动.png",
|
||||
icon2: "/static/common/img/homepage/icon_校友活动_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "电子校友卡",
|
||||
icon: "/static/common/img/homepage/icon_电子校友卡.png",
|
||||
icon2: "/static/common/img/homepage/icon_电子校友卡_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校友会组织",
|
||||
icon: "/static/common/img/homepage/icon_校友会组织.png",
|
||||
icon2: "/static/common/img/homepage/icon_校友会组织_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "助力母校",
|
||||
icon: "/static/common/img/homepage/icon_助力母校.png",
|
||||
icon2: "/static/common/img/homepage/icon_助力母校_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
];
|
||||
|
|
@ -0,0 +1,596 @@
|
|||
const SCHOOL_CONFIG = {
|
||||
南昌理工: {
|
||||
ai: {
|
||||
name: "南小翼",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://sl.vrgon.com:2222/",
|
||||
type: "http",
|
||||
index: 0,
|
||||
},
|
||||
// welcome: {
|
||||
// name: "迎新",
|
||||
// icon: "/static/common/img/homepage/icon_迎新.png",
|
||||
// icon2: "/static/common/img/homepage/icon_迎新_gray.png",
|
||||
// url: "https://yxxt.nut.edu.cn:8090/#/",
|
||||
// type: "http",
|
||||
// index: 4,
|
||||
// },
|
||||
repair: {
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "https://bx.nut.edu.cn/#/",
|
||||
type: "http",
|
||||
index: 6,
|
||||
},
|
||||
score: {
|
||||
name: "成绩查询",
|
||||
icon: "/static/common/img/homepage/icon_就业帮助.png",
|
||||
icon2: "/static/common/img/homepage/icon_就业帮助_gray.png",
|
||||
url: "https://iwglxt.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 4,
|
||||
},
|
||||
oldStudent: {
|
||||
name: "老生缴费",
|
||||
icon: "/static/common/img/homepage/icon_缴费.png",
|
||||
icon2: "/static/common/img/homepage/icon_缴费_gray.png",
|
||||
url: "https://pay.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 1,
|
||||
},
|
||||
electricityBill: {
|
||||
name: "网上购电",
|
||||
icon: "/static/common/img/homepage/icon_网上购电.png",
|
||||
icon2: "/static/common/img/homepage/icon_网上购电_gray.png",
|
||||
url: "https://if.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 5,
|
||||
},
|
||||
},
|
||||
新能源: {
|
||||
ai: {
|
||||
name: "源小新",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://ai.tynxy.com:8001/",
|
||||
type: "http",
|
||||
index: 0,
|
||||
},
|
||||
// welcome: {
|
||||
// name: "迎新",
|
||||
// icon: "/static/common/img/homepage/icon_迎新.png",
|
||||
// icon2: "/static/common/img/homepage/icon_迎新_gray.png",
|
||||
// url: "https://yx.tynxy.com:8090/#/login",
|
||||
// type: "http",
|
||||
// index: 4,
|
||||
// },
|
||||
library: {
|
||||
name: "图书馆",
|
||||
icon: "/static/common/img/homepage/icon_图书借阅.png",
|
||||
icon2: "/static/common/img/homepage/icon_图书借阅_gray.png",
|
||||
url: "https://a.xiumi.us/stage/v5/33A6c/151995615#/",
|
||||
type: "http",
|
||||
index: 9,
|
||||
},
|
||||
score: {
|
||||
name: "成绩查询",
|
||||
icon: "/static/common/img/homepage/icon_就业帮助.png",
|
||||
icon2: "/static/common/img/homepage/icon_就业帮助_gray.png",
|
||||
url: "http://cas.tynxy.com:7171/cas/login/",
|
||||
type: "http",
|
||||
index: 4,
|
||||
},
|
||||
electricityBill: {
|
||||
name: "网上购电",
|
||||
icon: "/static/common/img/homepage/icon_网上购电.png",
|
||||
icon2: "/static/common/img/homepage/icon_网上购电_gray.png",
|
||||
url: "http://vpn.tynxy.com:10081/",
|
||||
type: "http",
|
||||
index: 5,
|
||||
},
|
||||
},
|
||||
亚视: {
|
||||
ai: {
|
||||
name: "广小演",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://gxy.gdatv.edu.cn:8103/",
|
||||
type: "http",
|
||||
index: 0,
|
||||
},
|
||||
electricityBill: {
|
||||
name: "网上购电",
|
||||
icon: "/static/common/img/homepage/icon_网上购电.png",
|
||||
icon2: "/static/common/img/homepage/icon_网上购电_gray.png",
|
||||
url: "https://payment.gdatv.edu.cn/df?code=021aLZZv3Knm753sCR0w3k1W7w3aLZZu&state=1",
|
||||
type: "http",
|
||||
index: 5,
|
||||
},
|
||||
repair: {
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "http://gdysyx.gdatv.edu.cn:8099/#/",
|
||||
type: "http",
|
||||
index: 6,
|
||||
},
|
||||
library: {
|
||||
name: "图书馆",
|
||||
icon: "/static/common/img/homepage/icon_图书借阅.png",
|
||||
icon2: "/static/common/img/homepage/icon_图书借阅_gray.png",
|
||||
url: "https://v1.chaoxing.com/wechatSet/mobileIndex?fidEnc=edb7ce62838ef070&pageId=2572",
|
||||
type: "http",
|
||||
index: 9,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取特定学校的所有功能配置
|
||||
* @param {string} schoolName - 学校名称
|
||||
* @returns {Object} - 该学校的所有功能配置
|
||||
*/
|
||||
export const getSchoolConfig = (schoolName = "") => {
|
||||
// 查找匹配的学校配置
|
||||
const matchedSchool = Object.keys(SCHOOL_CONFIG).find((key) =>
|
||||
schoolName.includes(key)
|
||||
);
|
||||
return matchedSchool ? SCHOOL_CONFIG[matchedSchool] : {};
|
||||
};
|
||||
|
||||
// 保留之前的单项获取函数,以便向后兼容(首页使用)
|
||||
export const getAIAssistantConfig = (schoolName = "") => {
|
||||
const config = getSchoolConfig(schoolName);
|
||||
return (
|
||||
config.ai || {
|
||||
name: "ai智能",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "",
|
||||
}
|
||||
);
|
||||
};
|
||||
export const getOldStudentConfig = (schoolName = "") => {
|
||||
const config = getSchoolConfig(schoolName);
|
||||
return (
|
||||
config.oldStudent || {
|
||||
name: "缴费",
|
||||
icon: "/static/common/img/homepage/icon_缴费.png",
|
||||
icon2: "/static/common/img/homepage/icon_缴费_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
}
|
||||
);
|
||||
};
|
||||
/**
|
||||
* 首页功能列表数据
|
||||
*/
|
||||
export const functionListing = [
|
||||
{
|
||||
name: "ai智能",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "",
|
||||
},
|
||||
{
|
||||
name: "缴费",
|
||||
icon: "/static/common/img/homepage/icon_缴费.png",
|
||||
icon2: "/static/common/img/homepage/icon_缴费_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "返校预约",
|
||||
icon: "/static/common/img/homepage/icon_返校预约.png",
|
||||
icon2: "/static/common/img/homepage/icon_返校预约_gray.png",
|
||||
url: "/pages/my/BackSchool/BackSchool",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "心愿单",
|
||||
icon: "/static/common/img/homepage/icon_心愿单.png",
|
||||
icon2: "/static/common/img/homepage/icon_心愿单_gray.png",
|
||||
url: "/pages/my/wishlist/wishlist",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "全部服务",
|
||||
icon: "/static/common/img/homepage/icon_全部服务.png",
|
||||
icon2: "/static/common/img/homepage/icon_全部服务.png",
|
||||
},
|
||||
];
|
||||
|
||||
// 教师首页配置 vuex_user.userType==1
|
||||
export const TEACHER_CONFIG = [
|
||||
{
|
||||
name: "南小翼",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://sl.vrgon.com:2222/",
|
||||
type: "http",
|
||||
index: 0,
|
||||
},
|
||||
{
|
||||
name: "心愿单",
|
||||
icon: "/static/common/img/homepage/icon_心愿单.png",
|
||||
icon2: "/static/common/img/homepage/icon_心愿单_gray.png",
|
||||
url: "/pages/my/wishlist/wishlist",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "https://bx.nut.edu.cn/#/",
|
||||
type: "http",
|
||||
index: 7,
|
||||
},
|
||||
{
|
||||
name: "图书馆",
|
||||
icon: "/static/common/img/homepage/icon_图书借阅.png",
|
||||
icon2: "/static/common/img/homepage/icon_图书借阅_gray.png",
|
||||
url: "https://book.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 9,
|
||||
},
|
||||
];
|
||||
|
||||
// 南昌理工学院配置
|
||||
export const NANCHANG_CONFIG = {
|
||||
在校生: [
|
||||
{
|
||||
name: "南小翼",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://sl.vrgon.com:2222/",
|
||||
type: "http",
|
||||
},
|
||||
{
|
||||
name: "老生缴费",
|
||||
icon: "/static/common/img/homepage/icon_缴费.png",
|
||||
icon2: "/static/common/img/homepage/icon_缴费_gray.png",
|
||||
url: "https://pay.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 1,
|
||||
},
|
||||
{
|
||||
name: "网上购电",
|
||||
icon: "/static/common/img/homepage/icon_网上购电.png",
|
||||
icon2: "/static/common/img/homepage/icon_网上购电_gray.png",
|
||||
url: "https://if.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 5,
|
||||
},
|
||||
{
|
||||
name: "成绩查询",
|
||||
icon: "/static/common/img/homepage/icon_就业帮助.png",
|
||||
icon2: "/static/common/img/homepage/icon_就业帮助_gray.png",
|
||||
url: "https://iwglxt.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 4,
|
||||
},
|
||||
{
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "https://bx.nut.edu.cn/#/",
|
||||
type: "http",
|
||||
index: 6,
|
||||
},
|
||||
{
|
||||
name: "心愿单",
|
||||
icon: "/static/common/img/homepage/icon_心愿单.png",
|
||||
icon2: "/static/common/img/homepage/icon_心愿单_gray.png",
|
||||
url: "/pages/my/wishlist/wishlist",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "图书馆",
|
||||
icon: "/static/common/img/homepage/icon_图书借阅.png",
|
||||
icon2: "/static/common/img/homepage/icon_图书借阅_gray.png",
|
||||
url: "https://book.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 9,
|
||||
},
|
||||
{
|
||||
name: "选课",
|
||||
icon: "/static/common/img/homepage/icon_选课.png",
|
||||
icon2: "/static/common/img/homepage/icon_选课_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "办事指南",
|
||||
icon: "/static/common/img/homepage/icon_办事指南.png",
|
||||
icon2: "/static/common/img/homepage/icon_办事指南_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "勤工俭学",
|
||||
icon: "/static/common/img/homepage/icon_勤工俭学.png",
|
||||
icon2: "/static/common/img/homepage/icon_勤工俭学_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校园跑",
|
||||
icon: "/static/common/img/homepage/icon_校园跑.png",
|
||||
icon2: "/static/common/img/homepage/icon_校园跑_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "查询档案",
|
||||
icon: "/static/common/img/homepage/icon_查询档案.png",
|
||||
icon2: "/static/common/img/homepage/icon_查询档案_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
],
|
||||
毕业生: [
|
||||
{
|
||||
name: "南小翼",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://sl.vrgon.com:2222/",
|
||||
type: "http",
|
||||
},
|
||||
{
|
||||
name: "返校预约",
|
||||
icon: "/static/common/img/homepage/icon_返校预约.png",
|
||||
icon2: "/static/common/img/homepage/icon_返校预约_gray.png",
|
||||
url: "/pages/my/BackSchool/BackSchool",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "图书馆",
|
||||
icon: "/static/common/img/homepage/icon_图书借阅.png",
|
||||
icon2: "/static/common/img/homepage/icon_图书借阅_gray.png",
|
||||
url: "https://book.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 9,
|
||||
},
|
||||
{
|
||||
name: "心愿单",
|
||||
icon: "/static/common/img/homepage/icon_心愿单.png",
|
||||
icon2: "/static/common/img/homepage/icon_心愿单_gray.png",
|
||||
url: "/pages/my/wishlist/wishlist",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "DL",
|
||||
icon: "/static/common/img/homepage/icon_DL.png",
|
||||
icon2: "/static/common/img/homepage/icon_DL_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校友名片",
|
||||
icon: "/static/common/img/homepage/icon_校友名片.png",
|
||||
icon2: "/static/common/img/homepage/icon_校友名片_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校友活动",
|
||||
icon: "/static/common/img/homepage/icon_校友活动.png",
|
||||
icon2: "/static/common/img/homepage/icon_校友活动_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "电子校友卡",
|
||||
icon: "/static/common/img/homepage/icon_电子校友卡.png",
|
||||
icon2: "/static/common/img/homepage/icon_电子校友卡_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校友会组织",
|
||||
icon: "/static/common/img/homepage/icon_校友会组织.png",
|
||||
icon2: "/static/common/img/homepage/icon_校友会组织_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "助力母校",
|
||||
icon: "/static/common/img/homepage/icon_助力母校.png",
|
||||
icon2: "/static/common/img/homepage/icon_助力母校_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
],
|
||||
教师: [
|
||||
{
|
||||
name: "南小翼",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "http://sl.vrgon.com:2222/",
|
||||
type: "http",
|
||||
index: 0,
|
||||
},
|
||||
{
|
||||
name: "心愿单",
|
||||
icon: "/static/common/img/homepage/icon_心愿单.png",
|
||||
icon2: "/static/common/img/homepage/icon_心愿单_gray.png",
|
||||
url: "/pages/my/wishlist/wishlist",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "https://bx.nut.edu.cn/#/",
|
||||
type: "http",
|
||||
index: 7,
|
||||
},
|
||||
{
|
||||
name: "图书馆",
|
||||
icon: "/static/common/img/homepage/icon_图书借阅.png",
|
||||
icon2: "/static/common/img/homepage/icon_图书借阅_gray.png",
|
||||
url: "https://book.nut.edu.cn/",
|
||||
type: "http",
|
||||
index: 9,
|
||||
},
|
||||
// {
|
||||
// name: "DL",
|
||||
// icon: "/static/common/img/homepage/icon_DL.png",
|
||||
// icon2: "/static/common/img/homepage/icon_DL_gray.png",
|
||||
// url: "",
|
||||
// type: "page",
|
||||
// },
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* 全部服务
|
||||
*/
|
||||
export const functionListing2 = [
|
||||
{
|
||||
name: "ai智能",
|
||||
icon: "/static/common/img/homepage/icon_南小翼.png",
|
||||
icon2: "/static/common/img/homepage/icon_南小翼_gray.png",
|
||||
url: "",
|
||||
},
|
||||
{
|
||||
name: "缴费",
|
||||
icon: "/static/common/img/homepage/icon_缴费.png",
|
||||
icon2: "/static/common/img/homepage/icon_缴费_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "返校预约",
|
||||
icon: "/static/common/img/homepage/icon_返校预约.png",
|
||||
icon2: "/static/common/img/homepage/icon_返校预约_gray.png",
|
||||
url: "/pages/my/BackSchool/BackSchool",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "心愿单",
|
||||
icon: "/static/common/img/homepage/icon_心愿单.png",
|
||||
icon2: "/static/common/img/homepage/icon_心愿单_gray.png",
|
||||
url: "/pages/my/wishlist/wishlist",
|
||||
type: "page",
|
||||
},
|
||||
// {
|
||||
// name: "迎新",
|
||||
// icon: "/static/common/img/homepage/icon_迎新.png",
|
||||
// icon2: "/static/common/img/homepage/icon_迎新_gray.png",
|
||||
// url: "",
|
||||
// type: "http",
|
||||
// },
|
||||
{
|
||||
name: "就业帮助",
|
||||
icon: "/static/common/img/homepage/icon_就业帮助.png",
|
||||
icon2: "/static/common/img/homepage/icon_就业帮助_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "活动报名",
|
||||
icon: "/static/common/img/homepage/icon_活动报名.png",
|
||||
icon2: "/static/common/img/homepage/icon_活动报名_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "报修",
|
||||
icon: "/static/common/img/homepage/icon_报修.png",
|
||||
icon2: "/static/common/img/homepage/icon_报修_gray.png",
|
||||
url: "",
|
||||
type: "http",
|
||||
},
|
||||
{
|
||||
name: "勤工俭学",
|
||||
icon: "/static/common/img/homepage/icon_勤工俭学.png",
|
||||
icon2: "/static/common/img/homepage/icon_勤工俭学_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "办事指南",
|
||||
icon: "/static/common/img/homepage/icon_办事指南.png",
|
||||
icon2: "/static/common/img/homepage/icon_办事指南_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "图书馆",
|
||||
icon: "/static/common/img/homepage/icon_图书借阅.png",
|
||||
icon2: "/static/common/img/homepage/icon_图书借阅_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "查询档案",
|
||||
icon: "/static/common/img/homepage/icon_查询档案.png",
|
||||
icon2: "/static/common/img/homepage/icon_查询档案_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "选课",
|
||||
icon: "/static/common/img/homepage/icon_选课.png",
|
||||
icon2: "/static/common/img/homepage/icon_选课_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "DL",
|
||||
icon: "/static/common/img/homepage/icon_DL.png",
|
||||
icon2: "/static/common/img/homepage/icon_DL_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校园跑",
|
||||
icon: "/static/common/img/homepage/icon_校园跑.png",
|
||||
icon2: "/static/common/img/homepage/icon_校园跑_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
// {},
|
||||
];
|
||||
|
||||
// 毕业生敬请期待
|
||||
export const functionListing3 = [
|
||||
{
|
||||
name: "校友名片",
|
||||
icon: "/static/common/img/homepage/icon_校友名片.png",
|
||||
icon2: "/static/common/img/homepage/icon_校友名片_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校友活动",
|
||||
icon: "/static/common/img/homepage/icon_校友活动.png",
|
||||
icon2: "/static/common/img/homepage/icon_校友活动_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "电子校友卡",
|
||||
icon: "/static/common/img/homepage/icon_电子校友卡.png",
|
||||
icon2: "/static/common/img/homepage/icon_电子校友卡_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "校友会组织",
|
||||
icon: "/static/common/img/homepage/icon_校友会组织.png",
|
||||
icon2: "/static/common/img/homepage/icon_校友会组织_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
{
|
||||
name: "助力母校",
|
||||
icon: "/static/common/img/homepage/icon_助力母校.png",
|
||||
icon2: "/static/common/img/homepage/icon_助力母校_gray.png",
|
||||
url: "",
|
||||
type: "page",
|
||||
},
|
||||
];
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
<template>
|
||||
<!-- 首页-校园资讯组件 -->
|
||||
<view class="campus-info-page">
|
||||
<!-- 使用内容卡片组件 -->
|
||||
<content-card
|
||||
v-for="(card, index) in contentCards"
|
||||
:key="index"
|
||||
:cardData="card"
|
||||
></content-card>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ContentCard from "@/components/ContentCard.vue";
|
||||
export default {
|
||||
name: "CampusInfo",
|
||||
components: {
|
||||
ContentCard,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 内容卡片数据
|
||||
contentCards: [
|
||||
// 图片类型卡片示例
|
||||
{
|
||||
user: {
|
||||
avatar: "/static/common/img/homepage/avatar3.png",
|
||||
name: "calista33",
|
||||
meta: "2小时前 北京大学",
|
||||
},
|
||||
content: "今日份走停停的小确幸。",
|
||||
type: "image",
|
||||
images: [
|
||||
"/static/common/img/homepage/image-photo1.png",
|
||||
"/static/common/img/homepage/image-photo2.png",
|
||||
"/static/common/img/homepage/image-photo3.png",
|
||||
],
|
||||
stats: {
|
||||
forward: 102,
|
||||
comment: 102,
|
||||
like: 212,
|
||||
favorite: 62,
|
||||
},
|
||||
},
|
||||
// 视频类型卡片示例
|
||||
{
|
||||
user: {
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
name: "Kohaku",
|
||||
meta: "2小时前 北京大学",
|
||||
},
|
||||
content: "看看我拍的这个视频•",
|
||||
type: "video",
|
||||
cover: "/static/images/video-cover.png",
|
||||
videoUrl: "https://example.com/video.mp4",
|
||||
duration: 145, // 2分25秒
|
||||
stats: {
|
||||
forward: 102,
|
||||
comment: 102,
|
||||
like: 212,
|
||||
favorite: 62,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
goContentDetail(card) {
|
||||
console.log(card);
|
||||
this.$u.route({
|
||||
url: "/pages/home/home/components/contentDetail/index",
|
||||
// params: {
|
||||
// card,
|
||||
// },
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.campus-info-page {
|
||||
padding: 32rpx 8rpx 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,668 @@
|
|||
<template>
|
||||
<view class="comment-section">
|
||||
<!-- 评论统计 -->
|
||||
<view class="comment-count">评论 {{ comments.length }}</view>
|
||||
|
||||
<!-- 评论列表 -->
|
||||
<view class="comment-list">
|
||||
<view
|
||||
class="comment-item"
|
||||
v-for="(comment, index) in comments"
|
||||
:key="index"
|
||||
>
|
||||
<image
|
||||
class="comment-avatar"
|
||||
:src="comment.author.avatar"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="comment-content">
|
||||
<view class="comment-user">
|
||||
<text class="comment-username">{{ comment.author.name }}</text>
|
||||
<text class="comment-school">{{ comment.author.school }}</text>
|
||||
<text class="comment-time">{{ comment.time }}</text>
|
||||
</view>
|
||||
<view class="comment-text">{{ comment.content }}</view>
|
||||
<view class="comment-actions">
|
||||
<view
|
||||
class="reply-count"
|
||||
v-if="comment.replyCount"
|
||||
@click="handleViewReplies(comment)"
|
||||
>
|
||||
{{ comment.replyCount }}回复 >
|
||||
</view>
|
||||
<view class="like-btn" @click="handleLikeComment(index)">
|
||||
<u-icon
|
||||
name="heart"
|
||||
:size="36"
|
||||
:color="comment.isLiked ? '#ff5555' : '#999'"
|
||||
></u-icon>
|
||||
|
||||
<text v-if="comment.likes">{{ comment.likes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作栏 - 修改为上下两行布局 -->
|
||||
<view class="footer-actions">
|
||||
<!-- 上方输入框区域 -->
|
||||
<view class="input-container">
|
||||
<view class="comment-input" @click="handleShowCommentInput">
|
||||
<text>高楼平地起,评论全靠你...</text>
|
||||
</view>
|
||||
<view class="send-btn">
|
||||
<!-- <u-icon name="arrow-right" :size="44" color="#4ca2ff"></u-icon> -->
|
||||
<image
|
||||
src="/static/common/img/homepage/icon-send.png"
|
||||
mode="aspectFill"
|
||||
style="width: 72rpx; height: 72rpx"
|
||||
></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 下方操作按钮区域 -->
|
||||
<view class="interaction-bar">
|
||||
<view
|
||||
class="action-item"
|
||||
v-for="(item, index) in actionButtons"
|
||||
:key="index"
|
||||
@click="handleAction(item.action)"
|
||||
>
|
||||
<image
|
||||
:src="item.icon"
|
||||
mode="aspectFill"
|
||||
style="width: 40rpx; height: 40rpx"
|
||||
></image>
|
||||
<text>{{ item.stat }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "CommentSection",
|
||||
props: {
|
||||
// 评论列表
|
||||
comments: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 分享数
|
||||
shareCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 评论数
|
||||
commentCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 点赞数
|
||||
likeCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 收藏数
|
||||
favoriteCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 是否已点赞
|
||||
isLiked: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 是否已收藏
|
||||
isFavorite: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 帖子ID
|
||||
postId: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 内部维护的状态,避免直接修改props
|
||||
innerStats: {
|
||||
shares: this.shareCount,
|
||||
comments: this.commentCount,
|
||||
likes: this.likeCount,
|
||||
favorites: this.favoriteCount,
|
||||
isLiked: this.isLiked,
|
||||
isFavorite: this.isFavorite,
|
||||
},
|
||||
// 内部评论列表的副本
|
||||
localComments: [],
|
||||
// 添加操作按钮配置
|
||||
actionButtons: [
|
||||
{
|
||||
icon: "/static/common/img/homepage/reply.png",
|
||||
action: "forward",
|
||||
stat: "102",
|
||||
},
|
||||
{
|
||||
icon: "/static/common/img/homepage/comment.png",
|
||||
action: "comment",
|
||||
stat: "102",
|
||||
},
|
||||
{
|
||||
icon: "/static/common/img/homepage/like.png",
|
||||
action: "like",
|
||||
stat: "212",
|
||||
},
|
||||
{
|
||||
icon: "/static/common/img/homepage/star.png",
|
||||
action: "favorite",
|
||||
stat: "62",
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
// 监听外部传入的数据变化,更新内部状态
|
||||
comments: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
this.localComments = JSON.parse(JSON.stringify(newVal));
|
||||
},
|
||||
},
|
||||
shareCount(newVal) {
|
||||
this.innerStats.shares = newVal;
|
||||
},
|
||||
commentCount(newVal) {
|
||||
this.innerStats.comments = newVal;
|
||||
},
|
||||
likeCount(newVal) {
|
||||
this.innerStats.likes = newVal;
|
||||
},
|
||||
favoriteCount(newVal) {
|
||||
this.innerStats.favorites = newVal;
|
||||
},
|
||||
isLiked(newVal) {
|
||||
this.innerStats.isLiked = newVal;
|
||||
},
|
||||
isFavorite(newVal) {
|
||||
this.innerStats.isFavorite = newVal;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 处理查看评论回复
|
||||
handleViewReplies(comment) {
|
||||
// 跳转到回复详情页
|
||||
uni.navigateTo({
|
||||
url: `/pages/comment/replies?commentId=${comment.id}&postId=${this.postId}`,
|
||||
});
|
||||
|
||||
// 通知父组件(可选)
|
||||
this.$emit("view-replies", comment);
|
||||
},
|
||||
|
||||
// 处理点赞评论
|
||||
handleLikeComment(index) {
|
||||
// 直接在本地处理点赞逻辑
|
||||
const comment = this.localComments[index];
|
||||
comment.isLiked = !comment.isLiked;
|
||||
|
||||
if (comment.isLiked) {
|
||||
comment.likes++;
|
||||
} else if (comment.likes > 0) {
|
||||
comment.likes--;
|
||||
}
|
||||
|
||||
// 调用API更新点赞状态
|
||||
this.updateCommentLikeStatus(comment.id, comment.isLiked);
|
||||
|
||||
// 通知父组件(可选)
|
||||
this.$emit("like-comment", { index, comment });
|
||||
},
|
||||
|
||||
// 处理显示评论输入框
|
||||
handleShowCommentInput() {
|
||||
// 显示评论输入弹窗
|
||||
this.showCommentPopup();
|
||||
|
||||
// 通知父组件(可选)
|
||||
this.$emit("show-comment-input");
|
||||
},
|
||||
|
||||
// 处理分享帖子
|
||||
handleSharePost() {
|
||||
// 显示分享选项
|
||||
uni.showActionSheet({
|
||||
itemList: ["分享到朋友圈", "分享给朋友", "复制链接", "收藏"],
|
||||
success: (res) => {
|
||||
const { tapIndex } = res;
|
||||
let message = "";
|
||||
|
||||
switch (tapIndex) {
|
||||
case 0:
|
||||
message = "分享到朋友圈";
|
||||
break;
|
||||
case 1:
|
||||
message = "分享给朋友";
|
||||
break;
|
||||
case 2:
|
||||
uni.setClipboardData({
|
||||
data: `https://yourapp.com/post/${this.postId}`,
|
||||
success: () => {
|
||||
message = "链接已复制";
|
||||
},
|
||||
});
|
||||
break;
|
||||
case 3:
|
||||
this.handleFavoritePost();
|
||||
return;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: "none",
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// 通知父组件(可选)
|
||||
this.$emit("share");
|
||||
},
|
||||
|
||||
// 处理评论帖子
|
||||
handleCommentPost() {
|
||||
// 直接调用显示评论输入框
|
||||
this.handleShowCommentInput();
|
||||
},
|
||||
|
||||
// 处理点赞帖子
|
||||
handleLikePost() {
|
||||
// 更新内部状态
|
||||
this.innerStats.isLiked = !this.innerStats.isLiked;
|
||||
|
||||
if (this.innerStats.isLiked) {
|
||||
this.innerStats.likes++;
|
||||
} else if (this.innerStats.likes > 0) {
|
||||
this.innerStats.likes--;
|
||||
}
|
||||
|
||||
// 调用API更新点赞状态
|
||||
this.updatePostLikeStatus(this.postId, this.innerStats.isLiked);
|
||||
|
||||
// 通知父组件
|
||||
this.$emit("like", {
|
||||
isLiked: this.innerStats.isLiked,
|
||||
likeCount: this.innerStats.likes,
|
||||
});
|
||||
},
|
||||
|
||||
// 处理收藏帖子
|
||||
handleFavoritePost() {
|
||||
// 更新内部状态
|
||||
this.innerStats.isFavorite = !this.innerStats.isFavorite;
|
||||
|
||||
if (this.innerStats.isFavorite) {
|
||||
this.innerStats.favorites++;
|
||||
} else if (this.innerStats.favorites > 0) {
|
||||
this.innerStats.favorites--;
|
||||
}
|
||||
|
||||
// 调用API更新收藏状态
|
||||
this.updatePostFavoriteStatus(this.postId, this.innerStats.isFavorite);
|
||||
|
||||
// 通知父组件
|
||||
this.$emit("favorite", {
|
||||
isFavorite: this.innerStats.isFavorite,
|
||||
favoriteCount: this.innerStats.favorites,
|
||||
});
|
||||
},
|
||||
|
||||
// ========== API调用方法 ==========
|
||||
|
||||
// 更新评论点赞状态
|
||||
updateCommentLikeStatus(commentId, isLiked) {
|
||||
// 实际项目中这里会调用API
|
||||
console.log(`更新评论(${commentId})点赞状态: ${isLiked}`);
|
||||
|
||||
// 模拟API调用
|
||||
/*
|
||||
uni.request({
|
||||
url: '/api/comment/like',
|
||||
method: 'POST',
|
||||
data: {
|
||||
commentId,
|
||||
action: isLiked ? 'like' : 'unlike'
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('评论点赞状态更新成功', res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('评论点赞状态更新失败', err);
|
||||
// 更新失败,恢复UI状态
|
||||
this.rollbackCommentLike(commentId);
|
||||
}
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
// 更新帖子点赞状态
|
||||
updatePostLikeStatus(postId, isLiked) {
|
||||
// 实际项目中这里会调用API
|
||||
console.log(`更新帖子(${postId})点赞状态: ${isLiked}`);
|
||||
|
||||
// 模拟API调用
|
||||
/*
|
||||
uni.request({
|
||||
url: '/api/post/like',
|
||||
method: 'POST',
|
||||
data: {
|
||||
postId,
|
||||
action: isLiked ? 'like' : 'unlike'
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('帖子点赞状态更新成功', res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('帖子点赞状态更新失败', err);
|
||||
// 更新失败,恢复UI状态
|
||||
this.rollbackPostLike();
|
||||
}
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
// 更新帖子收藏状态
|
||||
updatePostFavoriteStatus(postId, isFavorite) {
|
||||
// 实际项目中这里会调用API
|
||||
console.log(`更新帖子(${postId})收藏状态: ${isFavorite}`);
|
||||
|
||||
// 模拟API调用
|
||||
/*
|
||||
uni.request({
|
||||
url: '/api/post/favorite',
|
||||
method: 'POST',
|
||||
data: {
|
||||
postId,
|
||||
action: isFavorite ? 'favorite' : 'unfavorite'
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('帖子收藏状态更新成功', res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('帖子收藏状态更新失败', err);
|
||||
// 更新失败,恢复UI状态
|
||||
this.rollbackPostFavorite();
|
||||
}
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
// 显示评论输入弹窗
|
||||
showCommentPopup() {
|
||||
// 这里可以显示一个自定义的评论输入弹窗
|
||||
uni.showModal({
|
||||
// title: "发表评论",
|
||||
editable: true,
|
||||
placeholderText: "说点什么吧...",
|
||||
success: (res) => {
|
||||
if (res.confirm && res.content) {
|
||||
// 提交评论
|
||||
this.submitComment(res.content);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 提交评论
|
||||
submitComment(content) {
|
||||
if (!content.trim()) return;
|
||||
|
||||
// 实际项目中这里会调用API
|
||||
console.log(`提交评论到帖子(${this.postId}): ${content}`);
|
||||
|
||||
// 模拟评论成功
|
||||
const newComment = {
|
||||
id: Date.now().toString(),
|
||||
author: {
|
||||
id: "current-user-id",
|
||||
name: "我",
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
school: "我的学校",
|
||||
},
|
||||
time: "刚刚",
|
||||
content: content,
|
||||
likes: 0,
|
||||
isLiked: false,
|
||||
replyCount: 0,
|
||||
};
|
||||
|
||||
// 添加到本地评论列表
|
||||
this.localComments.unshift(newComment);
|
||||
|
||||
// 更新评论计数
|
||||
this.innerStats.comments++;
|
||||
|
||||
// 通知父组件
|
||||
this.$emit("comment-added", {
|
||||
comment: newComment,
|
||||
commentCount: this.innerStats.comments,
|
||||
});
|
||||
|
||||
// 显示成功提示
|
||||
uni.showToast({
|
||||
title: "评论发表成功",
|
||||
icon: "success",
|
||||
});
|
||||
},
|
||||
|
||||
// 回退操作(当API调用失败时恢复UI状态)
|
||||
rollbackCommentLike(commentId) {
|
||||
const index = this.localComments.findIndex((c) => c.id === commentId);
|
||||
if (index > -1) {
|
||||
const comment = this.localComments[index];
|
||||
comment.isLiked = !comment.isLiked;
|
||||
if (comment.isLiked) {
|
||||
comment.likes++;
|
||||
} else if (comment.likes > 0) {
|
||||
comment.likes--;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
rollbackPostLike() {
|
||||
this.innerStats.isLiked = !this.innerStats.isLiked;
|
||||
if (this.innerStats.isLiked) {
|
||||
this.innerStats.likes++;
|
||||
} else if (this.innerStats.likes > 0) {
|
||||
this.innerStats.likes--;
|
||||
}
|
||||
},
|
||||
|
||||
rollbackPostFavorite() {
|
||||
this.innerStats.isFavorite = !this.innerStats.isFavorite;
|
||||
if (this.innerStats.isFavorite) {
|
||||
this.innerStats.favorites++;
|
||||
} else if (this.innerStats.favorites > 0) {
|
||||
this.innerStats.favorites--;
|
||||
}
|
||||
},
|
||||
|
||||
// 添加统一的操作处理方法
|
||||
handleAction(action) {
|
||||
switch (action) {
|
||||
case "forward":
|
||||
this.handleForward();
|
||||
break;
|
||||
case "comment":
|
||||
this.handleComment();
|
||||
break;
|
||||
case "like":
|
||||
this.handleLike();
|
||||
break;
|
||||
case "favorite":
|
||||
this.handleFavorite();
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.comment-section {
|
||||
margin-top: 30rpx;
|
||||
// 评论统计
|
||||
.comment-count {
|
||||
font-size: 32rpx;
|
||||
color: rgba(0,0,0,0.9);
|
||||
font-weight: bold;
|
||||
padding: 30rpx 0 20rpx;
|
||||
// border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
|
||||
// 评论列表
|
||||
.comment-list {
|
||||
padding: 0;
|
||||
|
||||
.comment-item {
|
||||
display: flex;
|
||||
padding: 30rpx 0;
|
||||
// border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
.comment-avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.comment-content {
|
||||
flex: 1;
|
||||
|
||||
.comment-user {
|
||||
margin-bottom: 12rpx;
|
||||
|
||||
.comment-username {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.comment-school {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.comment-time {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-text {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.comment-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
|
||||
.reply-count {
|
||||
background-color: #f5f5f5;
|
||||
// flex: 1;
|
||||
padding: 10rpx 16rpx;
|
||||
color: #666;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.like-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 底部操作栏 - 修改为上下两行布局
|
||||
.footer-actions {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #fff;
|
||||
padding: 16rpx 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 -1rpx 6rpx rgba(0, 0, 0, 0.05);
|
||||
z-index: 100;
|
||||
|
||||
// 上方输入框区域
|
||||
.input-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0 10rpx;
|
||||
|
||||
.comment-input {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 36rpx;
|
||||
padding: 0 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
margin-left: 20rpx;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
// 下方操作按钮区域
|
||||
.interaction-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 16rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 适当增加页面底部留白,避免内容被底部操作栏遮挡
|
||||
padding-bottom: 220rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,337 @@
|
|||
<template>
|
||||
<view class="content-detail-page">
|
||||
<u-navbar title="" :border-bottom="false" :is-back="true"></u-navbar>
|
||||
|
||||
<!-- 帖子内容区域 -->
|
||||
<view class="post-container">
|
||||
<!-- 用户信息 -->
|
||||
<view class="user-info">
|
||||
<image
|
||||
class="avatar"
|
||||
:src="post.author.avatar"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="user-meta">
|
||||
<view class="username">{{ post.author.name }}</view>
|
||||
<view class="post-meta"
|
||||
>{{ post.time }} {{ post.author.school }}</view
|
||||
>
|
||||
</view>
|
||||
<view class="follow-btn" @click="followUser">
|
||||
<text>+</text>
|
||||
<text>关注</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 帖子文本内容 -->
|
||||
<view class="post-content">
|
||||
<text>{{ post.content }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 帖子话题标签 -->
|
||||
<view class="post-tags" v-if="post.tags && post.tags.length">
|
||||
<view
|
||||
class="tag-item"
|
||||
v-for="(tag, index) in post.tags"
|
||||
:key="index"
|
||||
@click="goToTopic(tag)"
|
||||
>
|
||||
#{{ tag }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 帖子图片内容 -->
|
||||
<view class="post-images" v-if="post.images && post.images.length">
|
||||
<view
|
||||
class="image-grid"
|
||||
:class="getImageLayoutClass(post.images.length)"
|
||||
>
|
||||
<image
|
||||
v-for="(img, index) in post.images"
|
||||
:key="index"
|
||||
:src="img"
|
||||
mode="aspectFill"
|
||||
@click="previewImage(index)"
|
||||
class="post-image"
|
||||
></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 使用评论区组件 - 简化后的接口 -->
|
||||
<comment-section
|
||||
:comments="post.comments"
|
||||
:share-count="post.shares"
|
||||
:comment-count="post.commentCount"
|
||||
:like-count="post.likes"
|
||||
:favorite-count="post.favorites"
|
||||
:is-liked="post.isLiked"
|
||||
:is-favorite="post.isFavorite"
|
||||
:post-id="post.id"
|
||||
@like="updateLikeStatus"
|
||||
@favorite="updateFavoriteStatus"
|
||||
@comment-added="handleCommentAdded"
|
||||
></comment-section>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommentSection from './commentSection.vue';
|
||||
|
||||
export default {
|
||||
name: "ContentDetail",
|
||||
components: {
|
||||
CommentSection
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
post: {
|
||||
id: "12345",
|
||||
author: {
|
||||
id: "1001",
|
||||
name: "Kohaku",
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
school: "北京大学",
|
||||
isFollowed: false,
|
||||
},
|
||||
time: "2小时前",
|
||||
content:
|
||||
"美国对现行的全球化十分不满,从这次关税大战就可以看得出来,但是美国人就是不愿意代价自己,因为没有全球化的商品贸易体系,也就不会有美元如今的国际地位。\n美国本身加关税,看近来是想保护本国产业,但实际上牺牲了一个错位的,他们想保持美元的国际地位,又想把制造业搬回国内。\n这两件事其实完全矛盾的,美元之所以值钱,正是因为全球贸易都在用它结算,如果美国自己把贸易门门关小,美元的地位自然也会影响。\n现实情况是,美国超市里很多东西都依赖进口,华尔街的金融生意也需全球资金流动。\n现在美欢加关税,短期内可能看不出问题,但几个月后的压力会传到普通消费者。",
|
||||
images: [
|
||||
"/static/common/img/homepage/image-photo1.png",
|
||||
"/static/common/img/homepage/image-photo2.png",
|
||||
"/static/common/img/homepage/image-photo3.png",
|
||||
],
|
||||
tags: ["看到最文艺的话"],
|
||||
commentCount: 102,
|
||||
shares: 102,
|
||||
likes: 212,
|
||||
favorites: 62,
|
||||
isLiked: false,
|
||||
isFavorite: false,
|
||||
comments: [
|
||||
{
|
||||
id: "10001",
|
||||
author: {
|
||||
id: "2001",
|
||||
name: "Totoro",
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
school: "北京大学",
|
||||
},
|
||||
time: "6小时前",
|
||||
content:
|
||||
"美国在全球贸易秩序上是想保护本国产业,但实际上牺牲了一个错位的,他们想维持美元的国际地位,又想把制造业搬回国内。",
|
||||
likes: 12,
|
||||
isLiked: false,
|
||||
replyCount: 12,
|
||||
},
|
||||
{
|
||||
id: "10002",
|
||||
author: {
|
||||
id: "2002",
|
||||
name: "calista33",
|
||||
avatar: "/static/common/img/homepage/avatar2.png",
|
||||
school: "北京大学",
|
||||
},
|
||||
time: "6小时前",
|
||||
content:
|
||||
"现在美欢加关税,短期内可能看不出问题,但几个月后的压力会传到普通消费者。",
|
||||
likes: 12,
|
||||
isLiked: false,
|
||||
replyCount: 12,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 获取图片布局类名
|
||||
getImageLayoutClass(count) {
|
||||
if (count === 1) return "single-image";
|
||||
if (count === 2) return "double-image";
|
||||
if (count === 3) return "triple-image";
|
||||
if (count === 4) return "four-image";
|
||||
return "multi-image";
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage(index) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: this.post.images,
|
||||
});
|
||||
},
|
||||
|
||||
// 关注用户
|
||||
followUser() {
|
||||
this.post.author.isFollowed = !this.post.author.isFollowed;
|
||||
uni.showToast({
|
||||
title: this.post.author.isFollowed ? "已关注" : "已取消关注",
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
|
||||
// 前往话题页
|
||||
goToTopic(tag) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/home/home/components/topic/topicDetail?tag=${encodeURIComponent(
|
||||
tag
|
||||
)}`,
|
||||
});
|
||||
},
|
||||
|
||||
// 只需要处理关键更新
|
||||
updateLikeStatus(data) {
|
||||
this.post.isLiked = data.isLiked;
|
||||
this.post.likes = data.likeCount;
|
||||
},
|
||||
|
||||
updateFavoriteStatus(data) {
|
||||
this.post.isFavorite = data.isFavorite;
|
||||
this.post.favorites = data.favoriteCount;
|
||||
},
|
||||
|
||||
handleCommentAdded(data) {
|
||||
// 可以选择性地更新全局状态
|
||||
this.post.commentCount = data.commentCount;
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
// 这里可以根据传入的帖子ID获取帖子详情
|
||||
const postId = options.id;
|
||||
if (postId) {
|
||||
// 调用API获取帖子详情
|
||||
console.log("获取帖子ID:", postId);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content-detail-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f8f8f8;
|
||||
padding-bottom: 120rpx; // 为底部操作栏留出空间
|
||||
|
||||
// 帖子容器
|
||||
.post-container {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
|
||||
// 用户信息区域
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.user-meta {
|
||||
flex: 1;
|
||||
|
||||
.username {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.follow-btn {
|
||||
background-color: #00aaff;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
padding: 8rpx 20rpx;
|
||||
border-radius: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
text:first-child {
|
||||
margin-right: 4rpx;
|
||||
font-size: 32rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 帖子内容区域
|
||||
.post-content {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 30rpx;
|
||||
white-space: pre-line; // 保留换行符
|
||||
}
|
||||
|
||||
// 帖子标签区域
|
||||
.post-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.tag-item {
|
||||
color: #00aaff;
|
||||
font-size: 28rpx;
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 帖子图片区域
|
||||
.post-images {
|
||||
margin-bottom: a30rpx;
|
||||
|
||||
.image-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.post-image {
|
||||
border-radius: 12rpx;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
&.single-image {
|
||||
.post-image {
|
||||
width: 100%;
|
||||
max-height: 500rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.double-image {
|
||||
.post-image {
|
||||
width: 49%;
|
||||
height: 300rpx;
|
||||
margin-right: 2%;
|
||||
|
||||
&:nth-child(2n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.triple-image {
|
||||
.post-image {
|
||||
width: 32%;
|
||||
height: 240rpx;
|
||||
margin-right: 2%;
|
||||
|
||||
&:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<div>回复</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
<template>
|
||||
<!-- 首页-本校组件 -->
|
||||
<view class="our-school-page">
|
||||
<!-- 校园活动 -->
|
||||
<view class="school-activity-section">
|
||||
<view class="section-header">
|
||||
<text>校园活动</text>
|
||||
<text class="more">查看更多</text>
|
||||
</view>
|
||||
|
||||
<!-- 校园活动列表 -->
|
||||
<scroll-view scroll-x class="school-activity-list">
|
||||
<view
|
||||
class="school-activity-item"
|
||||
v-for="(user, index) in schoolActivityList"
|
||||
:key="index"
|
||||
>
|
||||
<view class="avatar-wrapper">
|
||||
<image :src="user.avatar" class="avatar"></image>
|
||||
</view>
|
||||
<view class="info-wrapper">
|
||||
<text class="name">{{ user.name }}</text>
|
||||
<text class="desc">{{ user.desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 校园动态 -->
|
||||
<view class="school-dynamic-section">
|
||||
<view class="section-header"> 校园动态 </view>
|
||||
</view>
|
||||
|
||||
<!-- 使用内容卡片组件 -->
|
||||
<content-card
|
||||
v-for="(card, index) in contentCards"
|
||||
:key="index"
|
||||
:cardData="card"
|
||||
></content-card>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ContentCard from "@/components/ContentCard.vue";
|
||||
export default {
|
||||
name: "OurSchool",
|
||||
components: {
|
||||
ContentCard,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
schoolActivityList: [
|
||||
{
|
||||
name: "2025届校园运动会12",
|
||||
avatar: "/static/common/img/homepage/image-photo2.png",
|
||||
desc: "浙江大学校运动场4月28日-30日将举行盛大的运动会,请同学们积极报名参加,积极报名,积极报名",
|
||||
},
|
||||
{
|
||||
name: "2025届校园运动会",
|
||||
avatar: "/static/common/img/homepage/image-photo1.png",
|
||||
desc: "浙江大学校运动场4月28日-30日将举行盛大的运动会,请同学们积极报名参加",
|
||||
},
|
||||
],
|
||||
|
||||
// 内容卡片数据
|
||||
contentCards: [
|
||||
// 图片类型卡片示例
|
||||
{
|
||||
user: {
|
||||
avatar: "/static/common/img/homepage/avatar3.png",
|
||||
name: "calista33",
|
||||
meta: "2小时前 北京大学",
|
||||
},
|
||||
content: "今日份走停停的小确幸。",
|
||||
type: "image",
|
||||
images: [
|
||||
"/static/common/img/homepage/image-photo1.png",
|
||||
"/static/common/img/homepage/image-photo2.png",
|
||||
"/static/common/img/homepage/image-photo3.png",
|
||||
],
|
||||
stats: {
|
||||
forward: 102,
|
||||
comment: 102,
|
||||
like: 212,
|
||||
favorite: 62,
|
||||
},
|
||||
},
|
||||
// 视频类型卡片示例
|
||||
{
|
||||
user: {
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
name: "Kohaku",
|
||||
meta: "2小时前 北京大学",
|
||||
},
|
||||
content: "看看我拍的这个视频•",
|
||||
type: "video",
|
||||
cover: "/static/images/video-cover.png",
|
||||
videoUrl: "https://example.com/video.mp4",
|
||||
duration: 145, // 2分25秒
|
||||
stats: {
|
||||
forward: 102,
|
||||
comment: 102,
|
||||
like: 212,
|
||||
favorite: 62,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.our-school-page {
|
||||
padding: 8rpx 8rpx 0;
|
||||
.school-activity-section {
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 30rpx 0;
|
||||
|
||||
text {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.school-activity-list {
|
||||
white-space: nowrap;
|
||||
|
||||
.school-activity-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
width: 512rpx;
|
||||
height: 232rpx;
|
||||
margin-right: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
|
||||
.avatar-wrapper {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 24rpx;
|
||||
|
||||
.avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.info-wrapper {
|
||||
width: 256rpx;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #1f2232;
|
||||
font-weight: bold;
|
||||
margin-bottom: 16rpx;
|
||||
overflow: hidden; /* 隐藏溢出内容 */
|
||||
text-overflow: ellipsis; /* 溢出显示省略号 */
|
||||
white-space: nowrap; /* 文本不换行 */
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 24rpx;
|
||||
line-height: 32rpx;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
white-space: wrap;
|
||||
-webkit-line-clamp: 4; /* 显示2行 */
|
||||
-webkit-box-orient: vertical;
|
||||
word-break: break-all; /* 允许在任意字符间断行 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.school-dynamic-section {
|
||||
.section-header {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin: 30rpx 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
<template>
|
||||
<view class="all-services-page">
|
||||
<u-navbar title="全部服务" :border-bottom="false"></u-navbar>
|
||||
|
||||
<!-- 校园服务区域 -->
|
||||
<view class="service-section">
|
||||
<view class="section-title">校园服务</view>
|
||||
<view class="service-grid">
|
||||
<view
|
||||
class="service-item"
|
||||
v-for="(item, index) in campusServices"
|
||||
:key="index"
|
||||
@click="navigateToService(item)"
|
||||
>
|
||||
<view class="icon-box">
|
||||
<image :src="item.url?item.icon:item.icon2" mode="aspectFit" class="icon-image"></image>
|
||||
<!-- <view v-if="!item.url" class="mark-box"></view> -->
|
||||
</view>
|
||||
<text class="service-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 校友服务区域 -->
|
||||
<view class="service-section">
|
||||
<view class="section-title">校友服务</view>
|
||||
<view class="service-grid">
|
||||
<view
|
||||
class="service-item"
|
||||
v-for="(item, index) in alumniServices"
|
||||
:key="index"
|
||||
@click="navigateToService(item)"
|
||||
>
|
||||
<view class="icon-box">
|
||||
<image :src="item.url?item.icon:item.icon2" mode="aspectFit" class="icon-image"></image>
|
||||
<!-- <view v-if="!item.url" class="mark-box"></view> -->
|
||||
</view>
|
||||
<text class="service-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-top-tips ref="uTips" :navbar-height="0"></u-top-tips>
|
||||
<u-toast ref="uToast" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
functionListing2,
|
||||
functionListing3,
|
||||
getSchoolConfig,
|
||||
} from "../../../data";
|
||||
|
||||
export default {
|
||||
name: "AllServices",
|
||||
data() {
|
||||
return {
|
||||
// 校园服务数据
|
||||
campusServices: JSON.parse(JSON.stringify(functionListing2)),
|
||||
|
||||
// 校友服务数据
|
||||
alumniServices: functionListing3,
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
vuex_schoolName: {
|
||||
handler(newVal) {
|
||||
this.updateSchoolConfigs(newVal);
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 更新学校相关配置
|
||||
updateSchoolConfigs(schoolName) {
|
||||
// 获取学校的所有配置
|
||||
const schoolConfig = getSchoolConfig(schoolName);
|
||||
|
||||
// 如果找到了学校配置
|
||||
if (Object.keys(schoolConfig).length > 0) {
|
||||
// 遍历学校的所有功能配置
|
||||
Object.values(schoolConfig).forEach((config) => {
|
||||
// 根据index替换对应位置的功能项
|
||||
if (
|
||||
typeof config.index === "number" &&
|
||||
config.index >= 0 &&
|
||||
config.index < this.campusServices.length
|
||||
) {
|
||||
this.$set(this.campusServices, config.index, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 跳转到对应服务页面
|
||||
navigateToService(service) {
|
||||
if (service.url == "") {
|
||||
console.log(this);
|
||||
// return this.$tips("暂未开放","warning");
|
||||
return this.$refs.uToast.show({
|
||||
title: "暂未开放",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
|
||||
if (service.type == "http") {
|
||||
// 外部链接,使用web-view打开
|
||||
const itemData = encodeURIComponent(JSON.stringify(service));
|
||||
this.$u.route({
|
||||
url: `/pages/webview/index?data=${itemData}`,
|
||||
});
|
||||
} else {
|
||||
// 如果是学生
|
||||
if ([0,2].includes(this.vuex_user.userType)) {
|
||||
if (!this.vuex_education.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行教育经历认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
const findRow = this.vuex_education.find(
|
||||
(x) => x.isSelected === true
|
||||
);
|
||||
if (!findRow) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先绑定学校",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行教育经历认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
// 如果是教师
|
||||
if ([1].includes(this.vuex_user.userType)) {
|
||||
// 校验当前学校是否审核通过
|
||||
if (!this.vuex_education.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行任职学校认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
const findRow = this.vuex_education.find(
|
||||
(x) => x.isSelected === true
|
||||
);
|
||||
if (!findRow) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先绑定学校",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行任职学校认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 内部页面,直接跳转
|
||||
this.$u.route({
|
||||
url: service.url,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.all-services-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f8f8f8;
|
||||
padding: 30rpx;
|
||||
|
||||
// 服务区域样式
|
||||
.service-section {
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
// 服务网格
|
||||
.service-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
// 服务项目
|
||||
.service-item {
|
||||
width: 20%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
// 图标容器
|
||||
.icon-box {
|
||||
width: 92rpx;
|
||||
height: 92rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16rpx;
|
||||
position: relative;
|
||||
|
||||
// 图标图片
|
||||
.icon-image {
|
||||
width: 92rpx;
|
||||
height: 92rpx;
|
||||
}
|
||||
|
||||
.mark-box {
|
||||
width: 92rpx;
|
||||
height: 92rpx;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 36rpx;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 服务名称
|
||||
.service-name {
|
||||
font-size: 24rpx;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
<template>
|
||||
<view class="all-services-page">
|
||||
<u-navbar title="全部服务" :border-bottom="false"></u-navbar>
|
||||
|
||||
<!-- 校园服务区域 -->
|
||||
<view class="service-section">
|
||||
<view class="section-title">{{
|
||||
isStudent ? "校园服务" : "校友服务"
|
||||
}}</view>
|
||||
<view class="service-grid">
|
||||
<view
|
||||
class="service-item"
|
||||
v-for="(item, index) in availableServices"
|
||||
:key="index"
|
||||
@click="navigateToService(item)"
|
||||
>
|
||||
<view class="icon-box">
|
||||
<image
|
||||
:src="item.url ? item.icon : item.icon2"
|
||||
mode="aspectFit"
|
||||
class="icon-image"
|
||||
></image>
|
||||
</view>
|
||||
<text class="service-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 校友服务区域 -->
|
||||
<view class="service-section">
|
||||
<view class="section-title">敬请期待</view>
|
||||
<view class="service-grid">
|
||||
<view
|
||||
class="service-item"
|
||||
v-for="(item, index) in waitingServices"
|
||||
:key="index"
|
||||
@click="navigateToService(item)"
|
||||
>
|
||||
<view class="icon-box">
|
||||
<image
|
||||
:src="item.url ? item.icon : item.icon2"
|
||||
mode="aspectFit"
|
||||
class="icon-image"
|
||||
></image>
|
||||
</view>
|
||||
<text class="service-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 模态框 -->
|
||||
<u-modal
|
||||
ref="uModal"
|
||||
v-model="modalShow"
|
||||
:content="modalContent"
|
||||
:show-cancel-button="true"
|
||||
@cancel="modalCancel"
|
||||
@confirm="modalConfirm"
|
||||
:async-close="true"
|
||||
></u-modal>
|
||||
<u-top-tips ref="uTips" :navbar-height="0"></u-top-tips>
|
||||
<u-toast ref="uToast" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
functionListing2,
|
||||
functionListing3,
|
||||
getSchoolConfig,
|
||||
NANCHANG_CONFIG,
|
||||
} from "../../../data";
|
||||
|
||||
export default {
|
||||
name: "AllServices",
|
||||
data() {
|
||||
return {
|
||||
modalShow: false,
|
||||
modalContent: "即将跳转第三方页面,是否继续跳转",
|
||||
currentUrl: null,
|
||||
|
||||
// 校园服务数据
|
||||
availableServices: JSON.parse(JSON.stringify(functionListing2)),
|
||||
|
||||
// 待开启服务数据
|
||||
waitingServices: [],
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
// 0 学生 2 毕业生
|
||||
isStudent() {
|
||||
return this.vuex_user.userType == 0 ? true : false;
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
vuex_schoolName: {
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
this.updateSchoolConfigs(newVal);
|
||||
} else {
|
||||
// 获取教育经历
|
||||
this.getEducation();
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 更新学校相关配置
|
||||
updateSchoolConfigs(schoolName) {
|
||||
// 南昌理工学院特殊处理
|
||||
if (schoolName.includes("南昌理工")) {
|
||||
// 根据用户类型选择配置(在校生或毕业生)
|
||||
const configType = this.isStudent ? "在校生" : "毕业生";
|
||||
|
||||
// 根据URL是否存在分类服务
|
||||
this.availableServices = NANCHANG_CONFIG[configType].filter(
|
||||
(service) => service.url
|
||||
);
|
||||
this.waitingServices = NANCHANG_CONFIG[configType].filter(
|
||||
(service) => !service.url
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 其他学校处理
|
||||
const schoolConfig = getSchoolConfig(schoolName);
|
||||
|
||||
// 创建服务列表副本
|
||||
const servicesCopy = [...this.availableServices];
|
||||
|
||||
// 遍历学校的所有功能配置并替换
|
||||
if (Object.keys(schoolConfig).length > 0) {
|
||||
Object.values(schoolConfig).forEach((config) => {
|
||||
if (
|
||||
typeof config.index === "number" &&
|
||||
config.index >= 0 &&
|
||||
config.index < servicesCopy.length
|
||||
) {
|
||||
this.$set(servicesCopy, config.index, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 根据URL是否存在分类服务
|
||||
const filteredServices = servicesCopy.filter((service) => service.url);
|
||||
const unfilteredServices = servicesCopy.filter((service) => !service.url);
|
||||
|
||||
// 更新可用和等待服务
|
||||
this.availableServices = filteredServices;
|
||||
this.waitingServices = unfilteredServices;
|
||||
|
||||
// 毕业生特殊处理,添加额外的等待服务
|
||||
if (!this.isStudent) {
|
||||
this.waitingServices = [...unfilteredServices, ...functionListing3];
|
||||
}
|
||||
},
|
||||
|
||||
// 跳转到对应服务页面
|
||||
navigateToService(service) {
|
||||
if (service.url == "") {
|
||||
console.log(this);
|
||||
// return this.$tips("暂未开放","warning");
|
||||
return this.$refs.uToast.show({
|
||||
title: "暂未开放",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
|
||||
if (service.type == "http") {
|
||||
this.currentUrl = service.url;
|
||||
|
||||
this.modalShow = true;
|
||||
|
||||
return;
|
||||
// 外部链接,使用web-view打开
|
||||
const itemData = encodeURIComponent(JSON.stringify(service));
|
||||
this.$u.route({
|
||||
url: `/pages/webview/index?data=${itemData}`,
|
||||
});
|
||||
} else {
|
||||
// 如果是学生
|
||||
if ([0, 2].includes(this.vuex_user.userType)) {
|
||||
if (!this.vuex_education.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行教育经历认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
const findRow = this.vuex_education.find(
|
||||
(x) => x.isSelected === true
|
||||
);
|
||||
if (!findRow) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先绑定学校",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行教育经历认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
// 如果是教师
|
||||
if ([1].includes(this.vuex_user.userType)) {
|
||||
// 校验当前学校是否审核通过
|
||||
if (!this.vuex_education.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行任职学校认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
const findRow = this.vuex_education.find(
|
||||
(x) => x.isSelected === true
|
||||
);
|
||||
if (!findRow) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先绑定学校",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行任职学校认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 内部页面,直接跳转
|
||||
this.$u.route({
|
||||
url: service.url,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
modalCancel() {
|
||||
this.modalShow = false;
|
||||
},
|
||||
|
||||
modalConfirm() {
|
||||
this.modalShow = false;
|
||||
|
||||
// 显示加载中提示和遮罩层
|
||||
uni.showLoading({
|
||||
title: "正在跳转...",
|
||||
mask: true, // 显示遮罩层,阻止用户操作
|
||||
});
|
||||
|
||||
// 直接跳转到第三方页面
|
||||
window.location.href = this.currentUrl;
|
||||
},
|
||||
|
||||
getEducation() {
|
||||
const data = {
|
||||
userId: this.vuex_user.id,
|
||||
};
|
||||
this.$u.apiList.MyPage(data).then((res) => {
|
||||
// 获取学校名称
|
||||
const schoolName =
|
||||
res.edcationList.length > 0
|
||||
? res.edcationList[0].schoolName || res.edcationList[0].school
|
||||
: "";
|
||||
this.$u.vuex("vuex_schoolName", schoolName);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.all-services-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f8f8f8;
|
||||
padding: 30rpx;
|
||||
|
||||
// 服务区域样式
|
||||
.service-section {
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
// 服务网格
|
||||
.service-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
// justify-content: space-between;
|
||||
justify-content: flex-start;
|
||||
|
||||
// 服务项目
|
||||
.service-item {
|
||||
width: 20%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
// 图标容器
|
||||
.icon-box {
|
||||
width: 92rpx;
|
||||
height: 92rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16rpx;
|
||||
position: relative;
|
||||
|
||||
// 图标图片
|
||||
.icon-image {
|
||||
width: 92rpx;
|
||||
height: 92rpx;
|
||||
}
|
||||
|
||||
.mark-box {
|
||||
width: 92rpx;
|
||||
height: 92rpx;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 36rpx;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 服务名称
|
||||
.service-name {
|
||||
font-size: 24rpx;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,885 @@
|
|||
<template>
|
||||
<!-- 首页-推荐组件 -->
|
||||
<view class="recommend-page">
|
||||
<u-top-tips ref="uTips" style="top: 0"></u-top-tips>
|
||||
<!-- Banner图 -->
|
||||
<view class="banner">
|
||||
<image
|
||||
src="/static/common/img/homepage/banner.jpg"
|
||||
mode="widthFix"
|
||||
></image>
|
||||
</view>
|
||||
|
||||
<!-- 功能图标区 -->
|
||||
<view class="function-icons">
|
||||
<view class="function-list-wrapper" :class="{ teacher_class: isTeacher }">
|
||||
<view
|
||||
class="function-item"
|
||||
v-for="(item, index) in isTeacher
|
||||
? functionListTeacher
|
||||
: functionList"
|
||||
:key="index"
|
||||
@click="handleFunctionClick(item)"
|
||||
>
|
||||
<view class="icon-box">
|
||||
<image
|
||||
:src="item.url ? item.icon : item.icon2"
|
||||
mode="widthFix"
|
||||
style="width: 92rpx; height: 92rpx"
|
||||
></image>
|
||||
</view>
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 指示点 -->
|
||||
<!-- <view class="indicator">
|
||||
<view class="dot active"></view>
|
||||
<view class="dot"></view>
|
||||
<view class="dot"></view>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<!-- 为你推荐 -->
|
||||
<view class="recommend-section">
|
||||
<view class="section-header">
|
||||
<text>为你推荐</text>
|
||||
<text class="more" @click="toAlumniPage">查看更多</text>
|
||||
</view>
|
||||
|
||||
<!-- 推荐人列表 -->
|
||||
<scroll-view
|
||||
scroll-x
|
||||
class="recommend-users"
|
||||
v-if="recommendUsers.length !== 0"
|
||||
>
|
||||
<view
|
||||
class="user-item"
|
||||
v-for="(user, index) in recommendUsers"
|
||||
:key="index"
|
||||
@click="toUserDetail(user.userId)"
|
||||
>
|
||||
<!-- <image
|
||||
:src="$u.http.config.imgUrl + user.imageUrl"
|
||||
class="avatar"
|
||||
></image> -->
|
||||
<u-avatar
|
||||
:src="$u.http.config.imgUrl + user.imageUrl"
|
||||
class="avatar"
|
||||
></u-avatar>
|
||||
<text class="name">{{ user.name }}</text>
|
||||
<!-- <text class="desc">{{ user.workFieldName }}</text> -->
|
||||
|
||||
<!-- <button
|
||||
class="follow-btn"
|
||||
:class="{ followed: user.isFollowed }"
|
||||
@click.stop="handleFollow(user.userId)"
|
||||
>
|
||||
{{ user.isFollowed ? "已关注" : "关注" }}
|
||||
</button> -->
|
||||
<view
|
||||
class="follow-btn"
|
||||
:class="{ followed: user.isFollowed }"
|
||||
@click.stop="handleFollow(user.userId)"
|
||||
>
|
||||
<image
|
||||
v-if="!user.isFollowed"
|
||||
src="/static/common/img/homepage/icon-follow.png"
|
||||
mode="scaleToFill"
|
||||
style="width: 28rpx; height: 28rpx; margin-right: 6rpx"
|
||||
/>
|
||||
<span>{{ user.isFollowed ? "已关注" : "关注" }}</span>
|
||||
</view>
|
||||
<!-- <image
|
||||
class="close-btn"
|
||||
src="/static/common/img/homepage/icon-close-circle.png"
|
||||
mode="widthFix"
|
||||
style="width: 28rpx; height: 28rpx"
|
||||
></image> -->
|
||||
</view>
|
||||
</scroll-view>
|
||||
<no-data v-else></no-data>
|
||||
</view>
|
||||
|
||||
<!-- 校园资讯 横板,展示三条 -->
|
||||
<view class="campus-info-section">
|
||||
<view class="section-header">
|
||||
<text>校园资讯</text>
|
||||
<text class="more" @click="toAlumnusPage">查看更多</text>
|
||||
</view>
|
||||
|
||||
<!-- 校园资讯 -->
|
||||
<scroll-view
|
||||
scroll-x
|
||||
class="school-activity-list"
|
||||
v-if="schoolActivityList.length !== 0"
|
||||
>
|
||||
<view
|
||||
class="school-activity-item"
|
||||
v-for="(item, index) in schoolActivityList"
|
||||
:key="index"
|
||||
@click="toSchoolActivityDetail(item)"
|
||||
>
|
||||
<view class="avatar-wrapper">
|
||||
<!-- $u.http.config.imgUrl + item.imageUrl || -->
|
||||
<!-- 图片无法正常展示,先用默认图片 -->
|
||||
<image
|
||||
:src="'/static/common/img/homepage/activity-default.png'"
|
||||
class="avatar"
|
||||
></image>
|
||||
</view>
|
||||
<view class="info-wrapper">
|
||||
<text class="name">{{ item.title }}</text>
|
||||
<text class="desc">{{ item.content }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<!-- <no-data v-else></no-data> -->
|
||||
|
||||
<!-- -->
|
||||
<information
|
||||
@onStar="onStar"
|
||||
@clickImg="clickImg"
|
||||
:list="helpList"
|
||||
type="1"
|
||||
:bottom="bottomState"
|
||||
:borderNoPadding="true"
|
||||
:noShowEmpty="true"
|
||||
>
|
||||
</information>
|
||||
</view>
|
||||
|
||||
<!-- 模态框 -->
|
||||
<u-modal
|
||||
ref="uModal"
|
||||
v-model="modalShow"
|
||||
:content="modalContent"
|
||||
:show-cancel-button="true"
|
||||
@cancel="modalCancel"
|
||||
@confirm="modalConfirm"
|
||||
:async-close="true"
|
||||
></u-modal>
|
||||
<u-top-tips ref="uTips" :navbar-height="0"></u-top-tips>
|
||||
<u-toast ref="uToast" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
functionListing,
|
||||
getAIAssistantConfig,
|
||||
getOldStudentConfig,
|
||||
TEACHER_CONFIG,
|
||||
NANCHANG_CONFIG,
|
||||
getSchoolConfig,
|
||||
functionListing2,
|
||||
} from "../../../data";
|
||||
// 引入内容卡片组件
|
||||
import ContentCard from "@/components/ContentCard.vue";
|
||||
import information from "@/components/Information.vue";
|
||||
import NoData from "@/components/NoData.vue";
|
||||
import { computed } from "vue";
|
||||
export default {
|
||||
name: "Recommend",
|
||||
components: {
|
||||
ContentCard,
|
||||
NoData,
|
||||
information,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modalShow: false,
|
||||
modalContent: "即将跳转第三方页面,是否继续跳转",
|
||||
currentUrl: null,
|
||||
functionList: JSON.parse(JSON.stringify(functionListing)), // 深拷贝避免修改原始数据
|
||||
functionList2: JSON.parse(JSON.stringify(functionListing2)), // 深拷贝避免修改原始数据
|
||||
functionListTeacher: TEACHER_CONFIG, // 教师
|
||||
|
||||
recommendUsers: [
|
||||
/* {
|
||||
name: "李雪",
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
desc: "对二次元我似乎都关注了Ta",
|
||||
isFollowed: false,
|
||||
}, */
|
||||
],
|
||||
|
||||
schoolActivityList: [
|
||||
/* {
|
||||
title: "2025届校园运动会12",
|
||||
imageUrl: "/static/common/img/homepage/activity-default.png",
|
||||
content:
|
||||
"浙江大学校运动场4月28日-30日将举行盛大的运动会,请同学们积极报名参加,积极报名,积极报名",
|
||||
}, */
|
||||
],
|
||||
|
||||
currentRow: {},
|
||||
flag: null,
|
||||
route: null,
|
||||
type: "0",
|
||||
id: null,
|
||||
nolink: false,
|
||||
|
||||
bottomState: false,
|
||||
helpList: [],
|
||||
total2: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否是教师
|
||||
isTeacher() {
|
||||
return this.vuex_user.userType == 1 ? true : false;
|
||||
},
|
||||
// 0 学生 2 毕业生
|
||||
isStudent() {
|
||||
return this.vuex_user.userType == 0 ? true : false;
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
vuex_schoolName: {
|
||||
handler(newVal) {
|
||||
// 当schoolName有值时更新AI助手配置
|
||||
if (newVal) {
|
||||
this.updateAIConfig(newVal);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 更新AI助手配置
|
||||
updateAIConfig(schoolName) {
|
||||
// 处理学生用户
|
||||
if (this.vuex_user.userType !== 1) {
|
||||
const lastItem = this.functionList[4]; // 保存第5项(全部服务)
|
||||
|
||||
// 南昌理工学院特殊处理
|
||||
if (schoolName.includes("南昌理工")) {
|
||||
// 根据用户类型选择配置(在校生或毕业生)
|
||||
const configType = this.isStudent ? "在校生" : "毕业生";
|
||||
// 获取有URL的服务
|
||||
const filteredServices = NANCHANG_CONFIG[configType].filter(
|
||||
(service) => service.url
|
||||
);
|
||||
// 替换前4项,保留第5项
|
||||
this.functionList = [...filteredServices.slice(0, 4), lastItem];
|
||||
return;
|
||||
}
|
||||
|
||||
// 其他学校处理
|
||||
const schoolConfig = getSchoolConfig(schoolName);
|
||||
// 创建功能列表副本
|
||||
const functionList2Copy = [...this.functionList2];
|
||||
// 如果找到了学校配置
|
||||
if (Object.keys(schoolConfig).length > 0) {
|
||||
// 遍历学校的所有功能配置并替换
|
||||
Object.values(schoolConfig).forEach((config) => {
|
||||
if (
|
||||
typeof config.index === "number" &&
|
||||
config.index >= 0 &&
|
||||
config.index < functionList2Copy.length
|
||||
) {
|
||||
this.$set(functionList2Copy, config.index, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
// 过滤有URL的服务
|
||||
const filteredServices = functionList2Copy.filter(
|
||||
(service) => service.url
|
||||
);
|
||||
// 替换前4项,保留第5项
|
||||
this.functionList = [...filteredServices.slice(0, 4), lastItem];
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理教师用户
|
||||
if (schoolName.includes("南昌理工")) {
|
||||
this.functionListTeacher = NANCHANG_CONFIG["教师"];
|
||||
return;
|
||||
}
|
||||
|
||||
// 教师用户其他学校处理
|
||||
const schoolConfig = getSchoolConfig(schoolName);
|
||||
// 创建功能列表副本
|
||||
const functionList3Copy = [...this.functionList2];
|
||||
if (Object.keys(schoolConfig).length > 0) {
|
||||
// 遍历学校的所有功能配置并替换
|
||||
Object.values(schoolConfig).forEach((config) => {
|
||||
if (
|
||||
typeof config.index === "number" &&
|
||||
config.index >= 0 &&
|
||||
config.index < functionList3Copy.length
|
||||
) {
|
||||
this.$set(functionList3Copy, config.index, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.functionListTeacher = functionList3Copy.slice(0, 4);
|
||||
},
|
||||
|
||||
// 点击功能图标
|
||||
handleFunctionClick(item) {
|
||||
console.log("点击功能图标", item);
|
||||
|
||||
if (item.name === "全部服务") {
|
||||
this.$u.route({
|
||||
url: "/pages/home/home/components/recommend/allServices",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.url == "") {
|
||||
// this.$tips("暂未开放", "warning");
|
||||
this.$refs.uToast.show({
|
||||
title: "暂未开放",
|
||||
type: "warning",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.type == "http") {
|
||||
// 外部链接,使用web-view打开
|
||||
// this.$u.route({
|
||||
// url: `/pages/webview/index?url=${encodeURIComponent(item)}`,
|
||||
// });
|
||||
|
||||
this.currentUrl = item.url;
|
||||
|
||||
this.modalShow = true;
|
||||
|
||||
return;
|
||||
|
||||
const itemData = encodeURIComponent(JSON.stringify(item));
|
||||
this.$u.route({
|
||||
url: `/pages/webview/index?data=${itemData}`,
|
||||
});
|
||||
} else {
|
||||
// 如果是学生
|
||||
if ([0, 2].includes(this.vuex_user.userType)) {
|
||||
if (!this.vuex_education.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行教育经历认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
const findRow = this.vuex_education.find(
|
||||
(x) => x.isSelected === true
|
||||
);
|
||||
if (!findRow) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先绑定学校",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行教育经历认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
// 如果是教师
|
||||
if ([1].includes(this.vuex_user.userType)) {
|
||||
// 校验当前学校是否审核通过
|
||||
if (!this.vuex_education.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行任职学校认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
const findRow = this.vuex_education.find(
|
||||
(x) => x.isSelected === true
|
||||
);
|
||||
if (!findRow) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先绑定学校",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请先进行任职学校认证",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 内部页面,直接跳转
|
||||
this.$u.route({
|
||||
url: item.url,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
modalCancel() {
|
||||
this.modalShow = false;
|
||||
},
|
||||
|
||||
modalConfirm() {
|
||||
this.modalShow = false;
|
||||
|
||||
// 显示加载中提示和遮罩层
|
||||
uni.showLoading({
|
||||
title: "正在跳转...",
|
||||
mask: true, // 显示遮罩层,阻止用户操作
|
||||
});
|
||||
|
||||
// 直接跳转到第三方页面
|
||||
window.location.href = this.currentUrl;
|
||||
},
|
||||
|
||||
// 添加统一的刷新方法,集中调用所有需要刷新的方法
|
||||
refreshAll() {
|
||||
this.getAlumnSearch();
|
||||
this.getSchoolActivity();
|
||||
this.gethelpList();
|
||||
},
|
||||
|
||||
// 获取校友推荐
|
||||
getAlumnSearch() {
|
||||
this.$u.api.getAlumnSearch().then((res) => {
|
||||
this.recommendUsers = res;
|
||||
});
|
||||
},
|
||||
|
||||
// 获取校园资讯
|
||||
getSchoolActivity() {
|
||||
this.$u.api
|
||||
.GetSchoolList({
|
||||
PageIndex: 1,
|
||||
PageSize: 3,
|
||||
})
|
||||
.then((res) => {
|
||||
this.schoolActivityList = res.items;
|
||||
});
|
||||
},
|
||||
|
||||
// 点击推荐人
|
||||
toUserDetail(id) {
|
||||
this.$u.route({
|
||||
url: "/pages/AlumniCircle/userDetail/userDetail?id=" + id,
|
||||
});
|
||||
},
|
||||
|
||||
// 点击关注
|
||||
handleFollow(id) {
|
||||
const data = {
|
||||
userId: this.vuex_user.id,
|
||||
carewId: id,
|
||||
};
|
||||
this.$u.apiList.InsertOrDelFollow(data).then((res) => {
|
||||
if (res.succeed) {
|
||||
this.$refs.uToast.show({
|
||||
title: "已关注!",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
this.getAlumnSearch();
|
||||
});
|
||||
},
|
||||
|
||||
// 更多推荐人
|
||||
toAlumniPage() {
|
||||
this.$u.route({
|
||||
url: "/pages/AlumniCircle/Alumni/Alumni",
|
||||
});
|
||||
},
|
||||
|
||||
// 校园资讯查看更多
|
||||
toAlumnusPage() {
|
||||
uni.switchTab({
|
||||
url: "/pages/AlumniCircle/alumnus/alumnus",
|
||||
});
|
||||
},
|
||||
|
||||
// 校园资讯详情
|
||||
toSchoolActivityDetail(item) {
|
||||
this.currentRow = item;
|
||||
uni.$off("echoList");
|
||||
uni.$on("echoList", (result) => {
|
||||
// console.log('echoList----')
|
||||
// 收藏
|
||||
if (result.type === "star") {
|
||||
console.log("%c%s", "color:red", "收藏回显");
|
||||
console.log(result, "result");
|
||||
this.currentRow.isCllect = result.data.isCllect;
|
||||
console.log(result.isCllect, "result.isCllect");
|
||||
if (result.data.isCllect === true) {
|
||||
this.currentRow.collectCount++;
|
||||
}
|
||||
if (result.data.isCllect === false) {
|
||||
this.currentRow.collectCount && this.currentRow.collectCount--;
|
||||
}
|
||||
}
|
||||
// 评价
|
||||
if (result.type === "evaluate") {
|
||||
console.log("%c%s", "color:red", "评价回显");
|
||||
console.log(result, "result");
|
||||
this.currentRow.commentCount = result.data.commentCount;
|
||||
}
|
||||
});
|
||||
// return
|
||||
if (this.nolink) {
|
||||
return;
|
||||
}
|
||||
if (item.isDelete) {
|
||||
return;
|
||||
}
|
||||
item.flag = this.flag;
|
||||
item.route = this.route;
|
||||
item.mytype = this.type;
|
||||
item.myschoolId = this.id;
|
||||
if (this.type == 3) {
|
||||
item.mytype = item.type;
|
||||
}
|
||||
|
||||
this.$u.route({
|
||||
url: "/pages/AlumniCircle/ArticleDetails/ArticleDetails",
|
||||
params: {
|
||||
data: JSON.stringify(item),
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 获取校友帮帮列表
|
||||
gethelpList() {
|
||||
const data = {
|
||||
PageIndex: 1,
|
||||
PageSize: 10,
|
||||
IsForward: true, // 传 true 过滤转发数据
|
||||
Keyword: "全部",
|
||||
};
|
||||
this.helpList = [];
|
||||
|
||||
this.$u.api.GetHelpList(data).then((res) => {
|
||||
this.total2 = res.total;
|
||||
if (this.helpList.length >= this.total2) {
|
||||
this.bottomState = true;
|
||||
return;
|
||||
}
|
||||
if (this.total2 == res.items.length) {
|
||||
this.bottomState = true;
|
||||
}
|
||||
this.helpList.push(...res.items);
|
||||
});
|
||||
},
|
||||
|
||||
//收藏
|
||||
async onStar(val) {
|
||||
console.log("收藏--");
|
||||
// 判断当前学校是否认证,未认证不可收藏
|
||||
const req = {
|
||||
userId: this.vuex_user.id,
|
||||
};
|
||||
const res = await this.$u.apiList.MyPage(req);
|
||||
console.log(JSON.parse(JSON.stringify(res)), "res");
|
||||
const edcationList = res.edcationList;
|
||||
if (!edcationList.length) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "认证后可进行收藏操作",
|
||||
type: "none",
|
||||
});
|
||||
}
|
||||
const findRow = edcationList.find((x) => x.isSelected === true);
|
||||
if ([0, 2].includes(findRow.certifyStatus)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "认证后可进行收藏操作",
|
||||
type: "none",
|
||||
});
|
||||
}
|
||||
const data = {
|
||||
id: val.id,
|
||||
type: val.type,
|
||||
};
|
||||
this.$u.apiList
|
||||
.LikeCollect(data)
|
||||
.then((res) => {
|
||||
if (val.isCllect) {
|
||||
if (val.collectCount > 0) {
|
||||
val.isCllect = false;
|
||||
val.collectCount--;
|
||||
this.$refs.uToast.show({
|
||||
title: "取消收藏成功",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
val.isCllect = true;
|
||||
val.collectCount++;
|
||||
this.$refs.uToast.show({
|
||||
title: "收藏成功",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$refs.uToast.show({
|
||||
title: "收藏失败",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
//预览图片
|
||||
clickImg(item) {
|
||||
this.isonShow = false;
|
||||
item = this.$u.http.config.imgUrl + item;
|
||||
var images = [];
|
||||
images.push(item);
|
||||
uni.previewImage({
|
||||
// 图片路径必须是一个数组 => ['']
|
||||
current: 0,
|
||||
urls: images,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.recommend-page {
|
||||
.banner {
|
||||
width: 100%;
|
||||
height: 300rpx; // 356rpx
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.function-icons {
|
||||
// height: 248rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
|
||||
.function-list-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
// margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.teacher_class {
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.function-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.indicator {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
// margin: 20rpx 0;
|
||||
|
||||
.dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #ddd;
|
||||
margin: 0 8rpx;
|
||||
|
||||
&.active {
|
||||
background-color: #2979ff;
|
||||
width: 20rpx;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.recommend-section {
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 30rpx 0;
|
||||
|
||||
text {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.recommend-users {
|
||||
white-space: nowrap;
|
||||
|
||||
.user-item {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 280rpx;
|
||||
// height: 356rpx;
|
||||
height: 290rpx;
|
||||
margin-right: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx;
|
||||
position: relative;
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 16rpx;
|
||||
top: 16rpx;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin: 10rpx 0 20rpx;
|
||||
}
|
||||
|
||||
.desc {
|
||||
height: 70rpx;
|
||||
margin: 10rpx 0 16rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
white-space: wrap;
|
||||
-webkit-line-clamp: 2;
|
||||
/* 显示2行 */
|
||||
-webkit-box-orient: vertical;
|
||||
word-break: break-all;
|
||||
/* 允许在任意字符间断行 */
|
||||
}
|
||||
|
||||
.follow-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24rpx;
|
||||
width: 230rpx;
|
||||
height: 56rpx;
|
||||
background: linear-gradient(
|
||||
to bottom right,
|
||||
#3cb5fb 0%,
|
||||
#06e1fa 100%
|
||||
);
|
||||
border-radius: 28rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.followed {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
// border: none;
|
||||
background: #f6f8f9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.campus-info-section {
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 30rpx 0;
|
||||
|
||||
text {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.school-activity-list {
|
||||
white-space: nowrap;
|
||||
|
||||
.school-activity-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
width: 512rpx;
|
||||
height: 232rpx;
|
||||
margin-right: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
|
||||
.avatar-wrapper {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 24rpx;
|
||||
|
||||
.avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.info-wrapper {
|
||||
width: 256rpx;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #1f2232;
|
||||
font-weight: bold;
|
||||
margin-bottom: 16rpx;
|
||||
overflow: hidden;
|
||||
/* 隐藏溢出内容 */
|
||||
text-overflow: ellipsis;
|
||||
/* 溢出显示省略号 */
|
||||
white-space: nowrap;
|
||||
/* 文本不换行 */
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 24rpx;
|
||||
line-height: 32rpx;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
white-space: wrap;
|
||||
-webkit-line-clamp: 4;
|
||||
/* 显示2行 */
|
||||
-webkit-box-orient: vertical;
|
||||
word-break: break-all;
|
||||
/* 允许在任意字符间断行 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
<template>
|
||||
<view class="more-friends-page">
|
||||
<u-navbar title="更多推荐好友" :border-bottom="false"></u-navbar>
|
||||
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-container">
|
||||
<view class="search-box">
|
||||
<u-icon name="search" size="40rpx" color="#999"></u-icon>
|
||||
<input type="text" placeholder="搜索校友" v-model="searchKeyword" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 推荐好友列表 -->
|
||||
<view class="friends-list">
|
||||
<view
|
||||
class="friend-item"
|
||||
v-for="(friend, index) in filteredFriends"
|
||||
:key="index"
|
||||
>
|
||||
<!-- 头像 -->
|
||||
<image class="avatar" :src="friend.avatar" mode="aspectFill"></image>
|
||||
|
||||
<!-- 用户信息 -->
|
||||
<view class="user-info">
|
||||
<text class="username">{{ friend.name }}</text>
|
||||
<text class="school">{{ friend.school }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 关注按钮 -->
|
||||
<view
|
||||
class="follow-btn"
|
||||
:class="{ followed: friend.isFollowed }"
|
||||
@click="toggleFollow(index)"
|
||||
>
|
||||
{{ friend.isFollowed ? "已关注" : "关注" }}
|
||||
</view>
|
||||
|
||||
<!-- 移除按钮 -->
|
||||
<view class="remove-btn" @click="removeUser(index)">
|
||||
<u-icon name="close" size="32rpx" color="#666"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MoreFriends",
|
||||
data() {
|
||||
return {
|
||||
searchKeyword: "",
|
||||
recommendFriends: [
|
||||
{
|
||||
name: "小年轻",
|
||||
school: "浙江大学",
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
isFollowed: true,
|
||||
},
|
||||
{
|
||||
name: "小年轻",
|
||||
school: "浙江大学",
|
||||
avatar: "/static/common/img/homepage/avatar2.png",
|
||||
isFollowed: true,
|
||||
},
|
||||
{
|
||||
name: "Alice_琛璃",
|
||||
school: "浙江大学",
|
||||
avatar: "/static/common/img/homepage/avatar3.png",
|
||||
isFollowed: true,
|
||||
},
|
||||
{
|
||||
name: "Alice_琛璃",
|
||||
school: "浙江大学",
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
isFollowed: true,
|
||||
},
|
||||
{
|
||||
name: "Alice_琛璃",
|
||||
school: "浙江大学",
|
||||
avatar: "/static/common/img/homepage/avatar3.png",
|
||||
isFollowed: false,
|
||||
},
|
||||
{
|
||||
name: "别墨暝",
|
||||
school: "浙江大学",
|
||||
avatar: "/static/common/img/homepage/avatar2.png",
|
||||
isFollowed: false,
|
||||
},
|
||||
{
|
||||
name: "小六",
|
||||
school: "浙江大学",
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
isFollowed: false,
|
||||
},
|
||||
{
|
||||
name: "小年轻",
|
||||
school: "浙江大学",
|
||||
avatar: "/static/common/img/homepage/avatar3.png",
|
||||
isFollowed: false,
|
||||
},
|
||||
{
|
||||
name: "别墨暝",
|
||||
school: "浙江大学",
|
||||
avatar: "/static/common/img/homepage/avatar2.png",
|
||||
isFollowed: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 过滤后的好友列表,根据搜索关键词过滤
|
||||
filteredFriends() {
|
||||
if (!this.searchKeyword) {
|
||||
return this.recommendFriends;
|
||||
}
|
||||
|
||||
return this.recommendFriends.filter(
|
||||
(friend) =>
|
||||
friend.name
|
||||
.toLowerCase()
|
||||
.includes(this.searchKeyword.toLowerCase()) ||
|
||||
friend.school.toLowerCase().includes(this.searchKeyword.toLowerCase())
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 切换关注状态
|
||||
toggleFollow(index) {
|
||||
this.recommendFriends[index].isFollowed =
|
||||
!this.recommendFriends[index].isFollowed;
|
||||
|
||||
// 这里可以添加调用关注/取消关注API的逻辑
|
||||
const friend = this.recommendFriends[index];
|
||||
const action = friend.isFollowed ? "关注" : "取消关注";
|
||||
|
||||
uni.showToast({
|
||||
title: `${action}成功`,
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
|
||||
// 移除用户
|
||||
removeUser(index) {
|
||||
uni.showModal({
|
||||
// title: "提示",
|
||||
content: "确定不再推荐此用户吗?",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.recommendFriends.splice(index, 1);
|
||||
uni.showToast({
|
||||
title: "已移除此推荐",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.more-friends-page {
|
||||
min-height: 100vh;
|
||||
background-color: #fff;
|
||||
padding-bottom: 30rpx;
|
||||
|
||||
// 搜索框样式
|
||||
.search-container {
|
||||
padding: 20rpx 30rpx;
|
||||
|
||||
.search-box {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 36rpx;
|
||||
padding: 16rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
margin-left: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 好友列表样式
|
||||
.friends-list {
|
||||
.friend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx 30rpx;
|
||||
// border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
// 头像样式
|
||||
.avatar {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
// 用户信息样式
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
|
||||
.username {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.school {
|
||||
font-size: 24rpx;
|
||||
color: #3cb5fb;
|
||||
background-color: rgba(41, 151, 255, 0.1);
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 关注按钮样式
|
||||
.follow-btn {
|
||||
width: 120rpx;
|
||||
height: 64rpx;
|
||||
line-height: 64rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
border-radius: 36rpx;
|
||||
margin-right: 24rpx;
|
||||
color: #3cb5fb;
|
||||
border: 1rpx solid #3cb5fb;
|
||||
|
||||
&.followed {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
border: 1rpx solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
// 移除按钮样式
|
||||
.remove-btn {
|
||||
padding: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
<template>
|
||||
<view class="search-page">
|
||||
<!-- 头部搜索区域 -->
|
||||
<view class="search-header">
|
||||
<!-- 返回按钮 -->
|
||||
<view class="back-btn" @click="goBack">
|
||||
<image
|
||||
src="/static/common/img/homepage/icon-back.png"
|
||||
mode="widthFix"
|
||||
style="width: 48rpx; height: 48rpx"
|
||||
></image>
|
||||
</view>
|
||||
|
||||
<!-- 搜索输入框 -->
|
||||
<view class="search-input">
|
||||
<u-icon name="search" size="36rpx" color="#999"></u-icon>
|
||||
<input
|
||||
type="text"
|
||||
v-model="searchValue"
|
||||
placeholder="搜索"
|
||||
confirm-type="search"
|
||||
@confirm="handleSearch"
|
||||
focus
|
||||
clearable
|
||||
/>
|
||||
<u-icon
|
||||
v-if="searchValue"
|
||||
name="close"
|
||||
size="36rpx"
|
||||
color="#999"
|
||||
@click="clearSearch"
|
||||
></u-icon>
|
||||
</view>
|
||||
|
||||
<!-- 右侧功能图标 -->
|
||||
<!-- <view class="action-btns">
|
||||
<u-icon name="more-dot-fill" size="44rpx" color="#333"></u-icon>
|
||||
<u-icon name="plus-circle" size="44rpx" color="#333" class="ml-20"></u-icon>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<!-- 历史记录区域 -->
|
||||
<view class="search-history">
|
||||
<view class="history-header">
|
||||
<text class="section-title">历史记录</text>
|
||||
<!-- <u-icon
|
||||
name="trash"
|
||||
size="40rpx"
|
||||
color="#999"
|
||||
></u-icon> -->
|
||||
<image
|
||||
src="/static/common/img/homepage/icon-delete.png"
|
||||
mode="widthFix"
|
||||
style="width: 48rpx; height: 48rpx"
|
||||
@click="clearHistory"
|
||||
></image>
|
||||
</view>
|
||||
|
||||
<!-- 历史标签列表 -->
|
||||
<view class="history-tags">
|
||||
<view
|
||||
class="tag-item"
|
||||
v-for="(tag, index) in historyTags"
|
||||
:key="index"
|
||||
@click="searchByTag(tag)"
|
||||
>
|
||||
{{ tag }}
|
||||
</view>
|
||||
|
||||
<view class="tag-item more" @click="toggleMoreTags">
|
||||
<u-icon name="arrow-down" size="28rpx" color="#333"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 猜你想搜区域 -->
|
||||
<view class="search-suggestion">
|
||||
<view class="suggestion-header">
|
||||
<text class="section-title">猜你想搜</text>
|
||||
<!-- <u-icon name="reload" size="36rpx" color="#999"></u-icon> -->
|
||||
<image
|
||||
src="/static/common/img/homepage/icon-refresh.png"
|
||||
mode="widthFix"
|
||||
style="width: 48rpx; height: 48rpx"
|
||||
@click="refreshSuggestions"
|
||||
></image>
|
||||
</view>
|
||||
|
||||
<!-- 推荐搜索列表 -->
|
||||
<view class="suggestion-list">
|
||||
<view
|
||||
class="suggestion-item"
|
||||
v-for="(item, index) in suggestions"
|
||||
:key="index"
|
||||
@click="searchByTag(item)"
|
||||
>
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SearchPage",
|
||||
|
||||
data() {
|
||||
return {
|
||||
searchValue: "",
|
||||
historyTags: [
|
||||
"时尚",
|
||||
"游戏",
|
||||
"南小翼",
|
||||
"返校预约",
|
||||
"查询档案",
|
||||
"查询档案",
|
||||
"校友卡",
|
||||
],
|
||||
suggestions: [
|
||||
"友问答租属小京跳舞",
|
||||
"哪吒cos自创",
|
||||
"真人机甲对战",
|
||||
"马克摩音乐完整版",
|
||||
"跑步心率最高多少",
|
||||
"友问答租属小京跳舞",
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 返回上一页
|
||||
goBack() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
|
||||
// 处理搜索
|
||||
handleSearch() {
|
||||
if (!this.searchValue.trim()) return;
|
||||
|
||||
// 添加到历史记录
|
||||
if (!this.historyTags.includes(this.searchValue)) {
|
||||
this.historyTags.unshift(this.searchValue);
|
||||
// 保留最近的10条记录
|
||||
if (this.historyTags.length > 10) {
|
||||
this.historyTags = this.historyTags.slice(0, 10);
|
||||
}
|
||||
// 保存到本地存储
|
||||
uni.setStorageSync("searchHistory", JSON.stringify(this.historyTags));
|
||||
}
|
||||
|
||||
// 执行搜索
|
||||
this.doSearch(this.searchValue);
|
||||
},
|
||||
|
||||
// 清空搜索框
|
||||
clearSearch() {
|
||||
this.searchValue = "";
|
||||
},
|
||||
|
||||
// 清空历史记录
|
||||
clearHistory() {
|
||||
uni.showModal({
|
||||
// title: "提示",
|
||||
content: "确定清空搜索历史?",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.historyTags = [];
|
||||
uni.removeStorageSync("searchHistory");
|
||||
uni.showToast({
|
||||
title: "已清空历史记录",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 使用标签搜索
|
||||
searchByTag(tag) {
|
||||
this.searchValue = tag;
|
||||
this.handleSearch();
|
||||
},
|
||||
|
||||
// 切换更多标签
|
||||
toggleMoreTags() {
|
||||
// 这里可以实现展开更多历史标签的逻辑
|
||||
uni.showToast({
|
||||
title: "展开更多标签",
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
|
||||
// 刷新推荐
|
||||
refreshSuggestions() {
|
||||
// 这里可以实现刷新推荐搜索的逻辑
|
||||
uni.showToast({
|
||||
title: "已刷新推荐",
|
||||
icon: "none",
|
||||
});
|
||||
|
||||
// 模拟刷新效果
|
||||
this.suggestions = this.suggestions.sort(() => Math.random() - 0.5);
|
||||
},
|
||||
|
||||
// 执行搜索
|
||||
doSearch(keyword) {
|
||||
console.log("搜索:", keyword);
|
||||
// 这里可以跳转到搜索结果页或者显示搜索结果
|
||||
uni.showToast({
|
||||
title: `搜索: ${keyword}`,
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
// 从本地存储加载历史记录
|
||||
const history = uni.getStorageSync("searchHistory");
|
||||
if (history) {
|
||||
try {
|
||||
this.historyTags = JSON.parse(history);
|
||||
} catch (e) {
|
||||
console.error("解析历史记录失败:", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-page {
|
||||
min-height: 100vh;
|
||||
background-color: #ffffff;
|
||||
padding: 0 24rpx;
|
||||
|
||||
// 头部搜索区域
|
||||
.search-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
|
||||
.back-btn {
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 380rpx;
|
||||
height: 72rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 36rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20rpx;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
font-size: 28rpx;
|
||||
margin: 0 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.action-btns {
|
||||
display: flex;
|
||||
margin-left: 20rpx;
|
||||
|
||||
.ml-20 {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 历史记录区域
|
||||
.search-history {
|
||||
margin-top: 30rpx;
|
||||
|
||||
.history-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.history-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.tag-item {
|
||||
height: 64rpx;
|
||||
padding: 0 30rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 32rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border: 2rpx solid rgba(0, 0, 0, 0.1);
|
||||
|
||||
&.more {
|
||||
padding: 0;
|
||||
width: 64rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 猜你想搜区域
|
||||
.search-suggestion {
|
||||
margin-top: 40rpx;
|
||||
|
||||
.suggestion-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.suggestion-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.suggestion-item {
|
||||
width: 50%;
|
||||
padding: 10rpx 0;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
<template>
|
||||
<!-- 首页-话题组件 -->
|
||||
<view class="topic-page">
|
||||
<!-- 顶部分类标签 -->
|
||||
<scroll-view scroll-x class="category-tabs" show-scrollbar="false">
|
||||
<view
|
||||
v-for="(item, index) in categories"
|
||||
:key="index"
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === index }"
|
||||
@click="switchTab(item,index)"
|
||||
:style="{ backgroundImage: `url(${item.image})` }"
|
||||
>
|
||||
<view class="tab-overlay"></view>
|
||||
<text>{{ item.name }}</text>
|
||||
<text class="sub-text">{{ item.subtitle }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 热门话题区域 -->
|
||||
<view class="hot-topics-container">
|
||||
<view class="section-title">热门话题</view>
|
||||
<view class="hot-topics">
|
||||
<!-- 使用循环渲染热门话题项目 -->
|
||||
<view
|
||||
class="topic-item"
|
||||
v-for="(item, index) in hotTopics"
|
||||
:key="index"
|
||||
>
|
||||
<view class="tag-text">#</view>
|
||||
|
||||
<view>
|
||||
<view class="topic-tag">
|
||||
<text class="tag-title">{{ item.title }}</text>
|
||||
<text
|
||||
v-if="item.tag"
|
||||
class="tag-hot"
|
||||
:class="{ orange: item.tag === '新' }"
|
||||
>{{ item.tag }}</text
|
||||
>
|
||||
</view>
|
||||
<view class="topic-desc">{{ item.description }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 关注的话题区域 -->
|
||||
<view class="followed-topics-container">
|
||||
<view class="section-title">关注的话题</view>
|
||||
<view class="followed-topics">
|
||||
<!-- 使用循环渲染关注话题项目 -->
|
||||
<view
|
||||
class="followed-topic-item"
|
||||
v-for="(item, index) in followedTopics"
|
||||
:key="index"
|
||||
>
|
||||
<image
|
||||
class="topic-image"
|
||||
:src="item.image"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="topic-content">
|
||||
<view class="topic-title">{{ item.title }}</view>
|
||||
<view class="topic-subtitle">{{ item.subtitle }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Topic",
|
||||
data() {
|
||||
return {
|
||||
activeTab: 0,
|
||||
categories: [
|
||||
{
|
||||
name: "广场",
|
||||
subtitle: "全部话题",
|
||||
image: "/static/common/img/homepage/image-photo1.png",
|
||||
},
|
||||
{
|
||||
name: "游戏",
|
||||
subtitle: "一起开黑",
|
||||
image: "/static/common/img/homepage/image-photo2.png",
|
||||
},
|
||||
{
|
||||
name: "学习",
|
||||
subtitle: "天天向上",
|
||||
image: "/static/common/img/homepage/image-photo1.png",
|
||||
},
|
||||
{
|
||||
name: "社交",
|
||||
subtitle: "校园交友",
|
||||
image: "/static/common/img/homepage/image-photo2.png",
|
||||
},
|
||||
],
|
||||
hotTopics: [
|
||||
{ title: "准大学生你好", description: "开学季来了", tag: "热" },
|
||||
{ title: "准大学生你好", description: "开学季来了", tag: "热" },
|
||||
{ title: "军训晒黑了吗", description: "各大高校谁最黑", tag: "热" },
|
||||
{ title: "军训晒黑了吗", description: "各大高校谁最黑", tag: "新" },
|
||||
{ title: "防晒霜推荐", description: "我是最靓的仔" },
|
||||
{ title: "防晒霜推荐", description: "我是最靓的仔" },
|
||||
],
|
||||
followedTopics: [
|
||||
{
|
||||
image: "/static/common/img/homepage/image-photo1.png",
|
||||
title: "看到最文艺的话",
|
||||
subtitle: "生活中常见的文艺文字...",
|
||||
},
|
||||
{
|
||||
image: "/static/common/img/homepage/image-photo2.png",
|
||||
title: "用来装通的冷知识",
|
||||
subtitle: "不知道的冷知识,还怎么装...",
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
switchTab(item,index) {
|
||||
this.activeTab = index;
|
||||
|
||||
|
||||
console.log(item, index);
|
||||
if(index == 0){
|
||||
this.$u.route({
|
||||
url: "/pages/home/home/components/topic/topicSquare",
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.topic-page {
|
||||
padding: 24rpx 8rpx 0;
|
||||
|
||||
// 顶部分类标签
|
||||
.category-tabs {
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
margin: 20rpx 0;
|
||||
|
||||
.tab-item {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
border-radius: 18rpx;
|
||||
padding-left: 32rpx;
|
||||
margin-right: 20rpx;
|
||||
width: 200rpx;
|
||||
height: 160rpx;
|
||||
position: relative;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
|
||||
// 添加覆盖层,用于控制背景图片亮度和颜色
|
||||
.tab-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(230, 247, 252, 0.55); // 基础背景色带透明度
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&.active .tab-overlay {
|
||||
background-color: rgba(0, 194, 255, 0.85); // 激活状态的背景色带透明度
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
// font-weight: 600;
|
||||
position: relative; // 确保文字在覆盖层之上
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.sub-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-top: 10rpx;
|
||||
position: relative; // 确保文字在覆盖层之上
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&.active {
|
||||
text,
|
||||
.sub-text {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 公共部分标题样式
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
}
|
||||
|
||||
.hot-topics-container {
|
||||
background-color: #fff;
|
||||
padding: 0 24rpx 24rpx 32rpx;
|
||||
border-radius: 24rpx;
|
||||
|
||||
// 热门话题区域
|
||||
.hot-topics {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.topic-item {
|
||||
width: 49%;
|
||||
margin-bottom: 24rpx;
|
||||
display: flex;
|
||||
|
||||
.tag-text {
|
||||
color: #00c2ff;
|
||||
font-weight: bold;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.topic-tag {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.tag-title {
|
||||
font-size: 32rpx;
|
||||
color: #1f2232;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tag-hot {
|
||||
font-size: 22rpx;
|
||||
color: #fff;
|
||||
background-color: #ff4d4f;
|
||||
border-radius: 8rpx;
|
||||
padding: 2rpx 8rpx;
|
||||
margin-left: 12rpx;
|
||||
|
||||
&.orange {
|
||||
background-color: #ff9500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topic-desc {
|
||||
font-size: 24rpx;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 关注的话题区域
|
||||
.followed-topics-container {
|
||||
background-color: #fff;
|
||||
padding: 0 24rpx 24rpx 32rpx;
|
||||
border-radius: 24rpx;
|
||||
margin-top: 24rpx;
|
||||
.followed-topics {
|
||||
.followed-topic-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1px solid #f6f8f9;
|
||||
|
||||
.topic-image {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 12rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.topic-content {
|
||||
flex: 1;
|
||||
|
||||
.topic-title {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.topic-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
<template>
|
||||
<view class="topic-detail-page">
|
||||
<u-navbar
|
||||
title=""
|
||||
:border-bottom="false"
|
||||
back-icon-color="#fff"
|
||||
:background="{ background: 'transparent' }"
|
||||
></u-navbar>
|
||||
|
||||
<!-- 话题头部信息 -->
|
||||
<view class="topic-header">
|
||||
<!-- 话题标题和描述 -->
|
||||
<view class="topic-info">
|
||||
<!-- 话题缩略图 -->
|
||||
<image
|
||||
class="topic-thumbnail"
|
||||
src="/static/common/img/homepage/image-photo1.png"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
|
||||
<view class="topic-info-content">
|
||||
<view class="topic-title">
|
||||
<text class="hash">#</text>看到最文艺的话
|
||||
</view>
|
||||
<view class="topic-description">
|
||||
生活中经常看到的文艺的文字,记录下来,摒组品体其中的每一个字眼,生活中经常看到的文艺的文字,记录下来,
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="topic-stats-container">
|
||||
<!-- 话题统计 -->
|
||||
<view class="topic-stats">
|
||||
<text class="stat-item">233267关注</text>
|
||||
<text class="stat-item">25216动态</text>
|
||||
</view>
|
||||
|
||||
<!-- 关注按钮 -->
|
||||
<view class="follow-btn">
|
||||
<u-icon name="plus" size="22rpx" color="#fff"></u-icon> 关注
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 内容分类标签 -->
|
||||
<view class="nav-container">
|
||||
<view
|
||||
v-for="(item, index) in tabs"
|
||||
:key="index"
|
||||
class="nav-item"
|
||||
:class="{ active: activeTab === index }"
|
||||
@click="switchTab(index)"
|
||||
>
|
||||
{{ item }}
|
||||
<view v-if="activeTab === index" class="active-line"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 话题内容列表 -->
|
||||
<view class="topic-content">
|
||||
<!-- 这里可以放置话题内容列表组件 -->
|
||||
<content-card
|
||||
v-for="(card, index) in contentCards"
|
||||
:key="index"
|
||||
:cardData="card"
|
||||
></content-card>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ContentCard from "@/components/ContentCard.vue";
|
||||
|
||||
export default {
|
||||
name: "TopicDetail",
|
||||
components: {
|
||||
ContentCard,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
topic: {
|
||||
id: "1",
|
||||
title: "看到最文艺的话",
|
||||
description:
|
||||
"生活中经常看到的文艺的文字,记录下来,摒组品体其中的每一个字眼,",
|
||||
followers: 233267,
|
||||
posts: 25216,
|
||||
isFollowed: false,
|
||||
thumbnail: "/static/common/img/homepage/image-photo1.png",
|
||||
},
|
||||
activeTab: 0,
|
||||
tabs: ["推荐", "最新"],
|
||||
|
||||
// 内容卡片数据
|
||||
contentCards: [
|
||||
// 图片类型卡片示例
|
||||
{
|
||||
user: {
|
||||
avatar: "/static/common/img/homepage/avatar3.png",
|
||||
name: "calista33",
|
||||
meta: "2小时前 北京大学",
|
||||
},
|
||||
content: "今日份走停停的小确幸。",
|
||||
type: "image",
|
||||
images: [
|
||||
"/static/common/img/homepage/image-photo1.png",
|
||||
"/static/common/img/homepage/image-photo2.png",
|
||||
"/static/common/img/homepage/image-photo3.png",
|
||||
],
|
||||
stats: {
|
||||
forward: 102,
|
||||
comment: 102,
|
||||
like: 212,
|
||||
favorite: 62,
|
||||
},
|
||||
},
|
||||
// 视频类型卡片示例
|
||||
{
|
||||
user: {
|
||||
avatar: "/static/common/img/homepage/avatar.png",
|
||||
name: "Kohaku",
|
||||
meta: "2小时前 北京大学",
|
||||
},
|
||||
content: "看看我拍的这个视频•",
|
||||
type: "video",
|
||||
cover: "/static/images/video-cover.png",
|
||||
videoUrl: "https://example.com/video.mp4",
|
||||
duration: 145, // 2分25秒
|
||||
stats: {
|
||||
forward: 102,
|
||||
comment: 102,
|
||||
like: 212,
|
||||
favorite: 62,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
switchTab(index) {
|
||||
this.activeTab = index;
|
||||
},
|
||||
|
||||
toggleFollow() {
|
||||
this.topic.isFollowed = !this.topic.isFollowed;
|
||||
|
||||
// 这里可以调用关注/取消关注的API
|
||||
uni.showToast({
|
||||
title: this.topic.isFollowed ? "已关注" : "已取消关注",
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.topic-detail-page {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: url("/static/common/img/homepage/image-topic-bg.png") no-repeat
|
||||
top center;
|
||||
background-size: 100% 592rpx;
|
||||
|
||||
// 话题头部信息
|
||||
.topic-header {
|
||||
padding: 40rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
// 话题信息
|
||||
.topic-info {
|
||||
// flex: 1;
|
||||
display: flex;
|
||||
// align-items: center;
|
||||
color: #fff;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
// 话题缩略图
|
||||
.topic-thumbnail {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.topic-info-content {
|
||||
width: calc(100% - 180rpx);
|
||||
|
||||
.topic-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
.hash {
|
||||
font-weight: normal;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.topic-description {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
line-height: 1.5;
|
||||
display: -webkit-box;
|
||||
white-space: wrap;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topic-stats-container {
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.topic-stats {
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
|
||||
.stat-item {
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 关注按钮
|
||||
.follow-btn {
|
||||
width: 120rpx;
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
background: linear-gradient(178deg, #3cb5fb 0%, #06e1fa 100%);
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 内容分类标签
|
||||
.nav-container {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
border-radius: 30rpx 30rpx 0 0;
|
||||
background-color: #fff;
|
||||
padding: 0 20rpx;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
min-width: 120rpx;
|
||||
padding: 0 20rpx;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
transition: all 0.3s ease; /* 添加过渡效果 */
|
||||
transform-origin: center bottom; /* 设置变换原点在底部中心 */
|
||||
|
||||
&.active {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.active-line {
|
||||
position: absolute;
|
||||
left: 50%; /* 将左边距设为50% */
|
||||
transform: translateX(-50%); /* 向左偏移自身宽度的50%,实现水平居中 */
|
||||
bottom: 25rpx;
|
||||
width: 60rpx;
|
||||
height: 12rpx;
|
||||
background: linear-gradient(
|
||||
116deg,
|
||||
rgba(60, 181, 251, 0) 0%,
|
||||
#28c6fb 45%,
|
||||
#06e1fa 100%
|
||||
);
|
||||
border-radius: 2rpx;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 话题内容区域
|
||||
.topic-content {
|
||||
background-color: #f6f8f9;
|
||||
height: 830rpx;
|
||||
overflow-y: auto;
|
||||
padding: 24rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,345 @@
|
|||
<template>
|
||||
<view class="topic-square-page">
|
||||
<u-navbar title="话题广场" :border-bottom="false"></u-navbar>
|
||||
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-container">
|
||||
<view class="search-box">
|
||||
<u-icon name="search" size="40rpx" color="#999"></u-icon>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="搜索要查找的话题"
|
||||
v-model="searchKeyword"
|
||||
/>
|
||||
</view>
|
||||
<view class="search-add-btn">
|
||||
<u-icon name="plus" size="40rpx" color="#333"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 类别导航 -->
|
||||
<scroll-view
|
||||
scroll-x
|
||||
class="category-nav"
|
||||
:show-scrollbar="false"
|
||||
:enhanced="true"
|
||||
:paging-enabled="false"
|
||||
>
|
||||
<view class="nav-container">
|
||||
<view
|
||||
v-for="(item, index) in categories"
|
||||
:key="index"
|
||||
class="nav-item"
|
||||
:class="{ active: activeCategory === index }"
|
||||
@click="switchCategory(index)"
|
||||
>
|
||||
{{ item }}
|
||||
<view v-if="activeCategory === index" class="active-line"></view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 话题列表 -->
|
||||
<view class="topic-list">
|
||||
<view
|
||||
class="topic-item"
|
||||
v-for="(item, index) in filteredTopics"
|
||||
:key="index"
|
||||
@click="goToTopicDetail(item)"
|
||||
>
|
||||
<!-- 话题图片 -->
|
||||
<image class="topic-image" :src="item.image" mode="aspectFill"></image>
|
||||
|
||||
<!-- 话题内容 -->
|
||||
<view class="topic-content">
|
||||
<view class="topic-title">{{ item.title }}</view>
|
||||
<view class="topic-desc">{{ item.description }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 关注按钮 -->
|
||||
<view
|
||||
class="follow-btn"
|
||||
:class="{ followed: item.isFollowed }"
|
||||
@click="toggleFollow(index)"
|
||||
>
|
||||
<view v-if="item.isFollowed">已关注</view>
|
||||
<view v-else
|
||||
><u-icon name="plus" size="22rpx" color="#fff"></u-icon> 关注</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "TopicSquare",
|
||||
data() {
|
||||
return {
|
||||
searchKeyword: "",
|
||||
activeCategory: 0,
|
||||
categories: [
|
||||
"全部",
|
||||
"学校",
|
||||
"社团",
|
||||
"学习",
|
||||
"游戏",
|
||||
"恋爱",
|
||||
"生活",
|
||||
"其他",
|
||||
],
|
||||
topics: [
|
||||
{
|
||||
title: "看到最文艺的话",
|
||||
description: "生活中常见的文艺文字...",
|
||||
image: "/static/common/img/homepage/image-photo1.png",
|
||||
isFollowed: true,
|
||||
category: 0,
|
||||
},
|
||||
{
|
||||
title: "看到最文艺的话",
|
||||
description: "生活中常见的文艺文字...",
|
||||
image: "/static/common/img/homepage/image-photo2.png",
|
||||
isFollowed: true,
|
||||
category: 1,
|
||||
},
|
||||
{
|
||||
title: "用来装通的冷知识",
|
||||
description: "不知道的冷知识,还怎么装...",
|
||||
image: "/static/common/img/homepage/image-photo3.png",
|
||||
isFollowed: true,
|
||||
category: 2,
|
||||
},
|
||||
{
|
||||
title: "看到最文艺的话",
|
||||
description: "生活中常见的文艺文字...",
|
||||
image: "/static/common/img/homepage/image-photo1.png",
|
||||
isFollowed: false,
|
||||
category: 3,
|
||||
},
|
||||
{
|
||||
title: "用来装通的冷知识",
|
||||
description: "不知道的冷知识,还怎么装...",
|
||||
image: "/static/common/img/homepage/image-photo2.png",
|
||||
isFollowed: false,
|
||||
category: 4,
|
||||
},
|
||||
{
|
||||
title: "看到最文艺的话",
|
||||
description: "生活中常见的文艺文字...",
|
||||
image: "/static/common/img/homepage/image-photo3.png",
|
||||
isFollowed: false,
|
||||
category: 0,
|
||||
},
|
||||
{
|
||||
title: "看到最文艺的话",
|
||||
description: "生活中常见的文艺文字...",
|
||||
image: "/static/common/img/homepage/image-photo2.png",
|
||||
isFollowed: false,
|
||||
category: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
filteredTopics() {
|
||||
// 先按分类筛选
|
||||
let result = this.topics;
|
||||
if (this.activeCategory !== 0) {
|
||||
result = result.filter(
|
||||
(topic) => topic.category === this.activeCategory
|
||||
);
|
||||
}
|
||||
|
||||
// 再按搜索关键词筛选
|
||||
if (this.searchKeyword.trim()) {
|
||||
const keyword = this.searchKeyword.toLowerCase();
|
||||
result = result.filter(
|
||||
(topic) =>
|
||||
topic.title.toLowerCase().includes(keyword) ||
|
||||
topic.description.toLowerCase().includes(keyword)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 切换分类
|
||||
switchCategory(index) {
|
||||
this.activeCategory = index;
|
||||
},
|
||||
|
||||
// 切换关注状态
|
||||
toggleFollow(index) {
|
||||
const topicIndex = this.topics.findIndex(
|
||||
(topic) => topic === this.filteredTopics[index]
|
||||
);
|
||||
if (topicIndex !== -1) {
|
||||
this.topics[topicIndex].isFollowed =
|
||||
!this.topics[topicIndex].isFollowed;
|
||||
|
||||
// 这里可以添加关注/取消关注的API调用
|
||||
uni.showToast({
|
||||
title: this.topics[topicIndex].isFollowed ? "已关注" : "已取消关注",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 跳转话题详情
|
||||
goToTopicDetail(item) {
|
||||
this.$u.route({
|
||||
url: `/pages/home/home/components/topic/topicDetail`,
|
||||
// url: `/pages/home/home/components/topic/topicDetail?topicId=${item.id}`,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.topic-square-page {
|
||||
min-height: 100vh;
|
||||
background-color: #fff;
|
||||
|
||||
// 搜索框样式
|
||||
.search-container {
|
||||
padding: 20rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.search-box {
|
||||
flex: 1;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 36rpx;
|
||||
padding: 16rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
margin-left: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.search-add-btn {
|
||||
background-color: #f5f5f5;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
border-radius: 36rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 类别导航样式
|
||||
.category-nav {
|
||||
white-space: nowrap;
|
||||
margin: 20rpx 0;
|
||||
|
||||
.nav-container {
|
||||
padding: 0 20rpx;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
min-width: 120rpx;
|
||||
padding: 0 20rpx;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
transition: all 0.3s ease; /* 添加过渡效果 */
|
||||
transform-origin: center bottom; /* 设置变换原点在底部中心 */
|
||||
|
||||
&.active {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.active-line {
|
||||
position: absolute;
|
||||
left: 50%; /* 将左边距设为50% */
|
||||
transform: translateX(-50%); /* 向左偏移自身宽度的50%,实现水平居中 */
|
||||
bottom: 4rpx;
|
||||
width: 60rpx;
|
||||
height: 12rpx;
|
||||
background: linear-gradient(
|
||||
116deg,
|
||||
rgba(60, 181, 251, 0) 0%,
|
||||
#28c6fb 45%,
|
||||
#06e1fa 100%
|
||||
);
|
||||
border-radius: 2rpx;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 话题列表样式
|
||||
.topic-list {
|
||||
padding: 20rpx 36rpx;
|
||||
|
||||
.topic-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx 0;
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
border-bottom: 1rpx solid #f6f8f9;
|
||||
|
||||
.topic-image {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 12rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.topic-content {
|
||||
flex: 1;
|
||||
|
||||
.topic-title {
|
||||
font-size: 32rpx;
|
||||
color: #1f2232;
|
||||
// font-weight: bold;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.topic-desc {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.follow-btn {
|
||||
width: 104rpx;
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
background: linear-gradient(178deg, #3cb5fb 0%, #06e1fa 100%);
|
||||
border-radius: 30rpx;
|
||||
|
||||
&.followed {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
background: #fff;
|
||||
border: 1rpx solid rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
<template>
|
||||
<view class="home-page">
|
||||
<!-- 顶部搜索栏 5/20 隐藏 -->
|
||||
<view class="home-search" @click="goSearch">
|
||||
<u-search
|
||||
placeholder="搜索"
|
||||
search-icon="search"
|
||||
:show-action="false"
|
||||
bg-color="#fff"
|
||||
>
|
||||
</u-search>
|
||||
</view>
|
||||
|
||||
<!-- 顶部导航栏 5/20 隐藏 -->
|
||||
<!-- <view class="nav-tabs">
|
||||
<view
|
||||
v-for="(item, index) in tabList"
|
||||
:key="index"
|
||||
class="tab"
|
||||
:class="{ active: currentTab === index }"
|
||||
@click="switchTab(index)"
|
||||
>
|
||||
{{ item }}
|
||||
<view v-if="currentTab === index" class="active-line"></view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 推荐组件 -->
|
||||
<recommend v-if="currentTab === 0" ref="recommendComp"></recommend>
|
||||
|
||||
<!-- 本校组件 -->
|
||||
<our-school
|
||||
v-if="false && currentTab === 1"
|
||||
ref="ourSchoolComp"
|
||||
></our-school>
|
||||
|
||||
<!-- 校园资讯组件 -->
|
||||
<campus-info
|
||||
v-if="false && currentTab === 2"
|
||||
ref="campusInfoComp"
|
||||
></campus-info>
|
||||
|
||||
<!-- 话题组件 -->
|
||||
<topic v-if="false && currentTab === 3" ref="topicComp"></topic>
|
||||
|
||||
<!-- 空盒子 -->
|
||||
<view class="empty-box"></view>
|
||||
|
||||
<u-tabbar
|
||||
:list="vuex_tabbar"
|
||||
:class="{ phone: vuex_iPhone }"
|
||||
:active-color="vuex_tabbar_config.activeColor"
|
||||
:inactive-color="vuex_tabbar_config.inactiveColor"
|
||||
></u-tabbar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Recommend from "./components/recommend/index.vue";
|
||||
import OurSchool from "./components/ourSchool/index.vue";
|
||||
import CampusInfo from "./components/campusInfo/index.vue";
|
||||
import Topic from "./components/topic/index.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Recommend,
|
||||
OurSchool,
|
||||
CampusInfo,
|
||||
Topic,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentTab: 0,
|
||||
tabList: ["推荐", "本校", "校园资讯", "话题"],
|
||||
|
||||
// 定义不同标签对应的背景色
|
||||
tabBackgrounds: [
|
||||
"linear-gradient(180deg, #b6e4ff 0%, #f6f8f9 45%, #f6f8f9 100%)", // 推荐
|
||||
"linear-gradient( 180deg, #c2e8fe 0%, #F6F8F9 15%, #F6F8F9 45%, #F6F8F9 100%)", // 其他
|
||||
],
|
||||
|
||||
// 定义tab对应的组件ref和刷新方法
|
||||
tabConfig: [
|
||||
{ ref: "recommendComp", refreshMethod: "refreshAll" },
|
||||
{ ref: "ourSchoolComp", refreshMethod: "refreshAll" },
|
||||
{ ref: "campusInfoComp", refreshMethod: "refreshAll" },
|
||||
{ ref: "topicComp", refreshMethod: "refreshAll" },
|
||||
],
|
||||
EdcationList: [], // 教育经历列表
|
||||
schoolName: "", // 学校名称
|
||||
};
|
||||
},
|
||||
onLoad(e) {},
|
||||
onShow() {
|
||||
// 页面显示时刷新当前tab
|
||||
this.refreshCurrentTab();
|
||||
// 获取教育经历
|
||||
this.getEducation();
|
||||
},
|
||||
computed: {
|
||||
// 计算当前页面样式
|
||||
pageStyle() {
|
||||
return {
|
||||
background:
|
||||
this.currentTab === 0
|
||||
? this.tabBackgrounds[0]
|
||||
: this.tabBackgrounds[1],
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 5/20 隐藏
|
||||
// switchTab(index) {
|
||||
// this.currentTab = index;
|
||||
|
||||
// // 刷新当前选中的tab
|
||||
// this.refreshCurrentTab();
|
||||
// },
|
||||
|
||||
// 5/20 隐藏
|
||||
// 2/28 放开
|
||||
goSearch() {
|
||||
// console.log("goSearch");
|
||||
// this.$u.route({
|
||||
// url: "/pages/home/home/components/searchPage/index",
|
||||
// });
|
||||
if (this.vuex_user.isAttestationXY || true) {
|
||||
this.$u.route({
|
||||
url: "/pages/main/search/search",
|
||||
params: {
|
||||
type: "home",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.$refs.uToast.show({
|
||||
title: "认证后才能进行搜索哦",
|
||||
url: "/pages/my/ShoolList/ShoolList",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 刷新当前选中的tab
|
||||
refreshCurrentTab() {
|
||||
this.$nextTick(() => {
|
||||
const config = this.tabConfig[this.currentTab];
|
||||
if (
|
||||
this.$refs[config.ref] &&
|
||||
typeof this.$refs[config.ref][config.refreshMethod] === "function"
|
||||
) {
|
||||
this.$refs[config.ref][config.refreshMethod]();
|
||||
}
|
||||
});
|
||||
},
|
||||
getEducation() {
|
||||
const data = {
|
||||
userId: this.vuex_user.id,
|
||||
};
|
||||
this.$u.apiList.MyPage(data).then((res) => {
|
||||
// 获取学校名称
|
||||
this.schoolName =
|
||||
res.edcationList.length > 0
|
||||
? res.edcationList[0].schoolName || res.edcationList[0].school
|
||||
: "";
|
||||
// 教育经历列表
|
||||
this.EdcationList = res.edcationList || [];
|
||||
this.$u.vuex("vuex_schoolName", this.schoolName);
|
||||
this.$u.vuex("vuex_education", this.EdcationList);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.home-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 24rpx 24rpx;
|
||||
background: linear-gradient(180deg, #b6e4ff 0%, #f6f8f9 45%, #f6f8f9 100%);
|
||||
transition: background 0.3 ease; // 添加背景色过渡效果
|
||||
|
||||
.home-search {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// justify-content: space-between;
|
||||
// padding: 24rpx 0;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
// .top-icons {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
|
||||
// .ml-15 {
|
||||
// margin-left: 15rpx;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 20rpx 0;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.tab {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
transition: all 0.3s ease; /* 添加过渡效果 */
|
||||
transform-origin: center bottom; /* 设置变换原点在底部中心 */
|
||||
|
||||
&.active {
|
||||
// font-size: 36rpx;
|
||||
transform: scale(1.125); /* 36/32 = 1.125,用scale替代font-size变化 */
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.active-line {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 4rpx;
|
||||
width: 100%;
|
||||
height: 12rpx;
|
||||
background: linear-gradient(
|
||||
116deg,
|
||||
rgba(60, 181, 251, 0) 0%,
|
||||
#28c6fb 45%,
|
||||
#06e1fa 100%
|
||||
);
|
||||
border-radius: 2rpx;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-box {
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,425 @@
|
|||
<template>
|
||||
<view class="flex-col page">
|
||||
<!-- <image src="/static/common/img/16530269846087107196.png" class="image"/> -->
|
||||
<u-navbar title="重置密码"></u-navbar>
|
||||
<view class="flex-col group" v-if="state === 1">
|
||||
<text class="text">重置密码</text>
|
||||
<view class="flex-col group_7">
|
||||
<view class="flex-col">
|
||||
<!-- <text class="text_1">手机号</text> -->
|
||||
<view class="text-wrapper flex-row view">
|
||||
<u-input
|
||||
v-model="phone"
|
||||
:disabled="disabled"
|
||||
placeholder="请输入手机号"
|
||||
type="text"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-col group_6">
|
||||
<!-- <text class="text_1">短信验证码</text> -->
|
||||
<view class="text-wrapper flex-row view" style="padding: 0">
|
||||
<u-input
|
||||
v-model="code"
|
||||
placeholder="请输入短信验证码"
|
||||
type="text"
|
||||
/>
|
||||
<u-button
|
||||
:disabled="!(send == '发送验证码')"
|
||||
class="custom-style"
|
||||
style="background: transparent"
|
||||
@click="sendCode"
|
||||
>{{ send }}
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <navigator class="text_6" url="/pages/login/login/login">登录</navigator> -->
|
||||
<u-button
|
||||
class="flex-col items-center text-wrapper_1"
|
||||
shape="circle"
|
||||
type="primary"
|
||||
@click="login"
|
||||
>
|
||||
<text class="text_7">重置密码</text>
|
||||
</u-button>
|
||||
</view>
|
||||
<view class="flex-col group" v-if="state === 2">
|
||||
<text class="text">遇见身边的校友</text>
|
||||
<view class="flex-col group_7">
|
||||
<view class="flex-col">
|
||||
<u-input
|
||||
v-model="passWord"
|
||||
class="view text-wrapper"
|
||||
placeholder="请输入新密码"
|
||||
type="password"
|
||||
/>
|
||||
</view>
|
||||
<view class="flex-col group_6">
|
||||
<u-input
|
||||
v-model="passWordTwo"
|
||||
class="view text-wrapper"
|
||||
placeholder="请确认新密码"
|
||||
type="password"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips">
|
||||
<image src="/static/common/img/infoCircle.png"></image>
|
||||
提示:密码长度应该大于5,必须包含字母、数字、特殊字符,且不能包含中文!
|
||||
</view>
|
||||
<u-button
|
||||
class="flex-col items-center text-wrapper_1"
|
||||
shape="circle"
|
||||
throttle-time="1000"
|
||||
type="primary"
|
||||
@click="login"
|
||||
>
|
||||
<text class="text_7">立即重置</text>
|
||||
</u-button>
|
||||
<u-button
|
||||
class="flex-col items-center text-wrapper_1"
|
||||
shape="circle"
|
||||
style=" margin-top: 10px"
|
||||
type="primary"
|
||||
@click="state = 1"
|
||||
>
|
||||
<text class="text_7">返回</text>
|
||||
</u-button>
|
||||
</view>
|
||||
<u-top-tips ref="uTips" :navbar-height="0"></u-top-tips>
|
||||
<u-toast ref="uToast"/>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import md5 from "js-md5";
|
||||
import {aesEncrypt} from "@/utils/encrypt.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
phone: "",
|
||||
passWord: "",
|
||||
code: "",
|
||||
passWordTwo: "",
|
||||
agreement: false,
|
||||
disabled: false,
|
||||
send: "发送验证码",
|
||||
state: 1,
|
||||
};
|
||||
},
|
||||
onLoad(e) {
|
||||
},
|
||||
methods: {
|
||||
// 提示
|
||||
tips(title, type, time) {
|
||||
this.$refs.uToast.show({
|
||||
title: title ? title : "",
|
||||
type: type ? type : "success",
|
||||
duration: time ? time + "" : "1500",
|
||||
});
|
||||
},
|
||||
// 发送验证码
|
||||
sendCode() {
|
||||
var reg = new RegExp("^[1][3,4,5,6,7,8,9][0-9]{9}$", "g"); //手机号
|
||||
if (this.phone === "" || !reg.test(this.phone)) {
|
||||
// this.$tips("请输入正确的手机号码", "error");
|
||||
this.$refs.uToast.show({
|
||||
title: '请输入正确的手机号码',
|
||||
type: 'error',
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
const timestamp = Date.now();
|
||||
const base64Key = btoa('xiaoyout!#@12345');
|
||||
const signStr = this.phone + timestamp + base64Key;
|
||||
const sign = md5(signStr);
|
||||
|
||||
this.$u.apiList
|
||||
.GetAppValidateCode({
|
||||
phone: this.phone,
|
||||
t: timestamp.toString(),
|
||||
sign: sign,
|
||||
type: 2,
|
||||
})
|
||||
.then((res) => {
|
||||
//中间数字加密
|
||||
// let result =this.userName.replace(this.userName.substring(3,7),"****")
|
||||
// this.userName = result
|
||||
this.disabled = true;
|
||||
// this.$tips("发送成功");
|
||||
this.$refs.uToast.show({
|
||||
title: '发送成功',
|
||||
type: 'success',
|
||||
})
|
||||
var second = 60;
|
||||
this.send = second + "秒后重试";
|
||||
var time = setInterval(() => {
|
||||
this.send = second + "秒后重试";
|
||||
second--;
|
||||
if (second <= 0) {
|
||||
this.disabled = false;
|
||||
this.send = "发送验证码";
|
||||
clearInterval(time);
|
||||
}
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
// this.$tips(err.error, "error");
|
||||
this.$refs.uToast.show({
|
||||
title: err.error,
|
||||
type: 'error',
|
||||
})
|
||||
});
|
||||
},
|
||||
login() {
|
||||
if (this.state == 1) {
|
||||
if (this.phone === "") {
|
||||
return this.tips("请输入手机号", "error");
|
||||
}
|
||||
if (this.code === "") {
|
||||
return this.tips("请输入验证码", "error");
|
||||
}
|
||||
this.$u.apiList.ForgotPasswordValidate({
|
||||
phone: this.phone,
|
||||
code: this.code,
|
||||
}).then((res) => {
|
||||
console.info("🚀 ~ file:ForgetPassword method: line:189 -----", res)
|
||||
this.state = 2;
|
||||
}).catch((err) => {
|
||||
this.tips(err.error, "error");
|
||||
});
|
||||
|
||||
return
|
||||
}
|
||||
if (this.state == 2) {
|
||||
if (this.passWord === "") {
|
||||
return this.tips("请输入新密码", "error");
|
||||
}
|
||||
let reg = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[\W_]).{5,}$/;
|
||||
if (!reg.test(this.passWord)) {
|
||||
/* return this.$tips(
|
||||
"密码必须包含字母、数字、特殊字符,且不能包含中文!",
|
||||
"error"
|
||||
); */
|
||||
return this.$refs.uToast.show({
|
||||
title: "密码必须包含字母、数字、特殊字符,且不能包含中文!",
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
if (this.passWordTwo === "") {
|
||||
return this.tips("请确认新密码", "error");
|
||||
}
|
||||
if (this.passWord != this.passWordTwo) {
|
||||
return this.tips("请检查两次密码是否一致", "error");
|
||||
}
|
||||
}
|
||||
const req = {
|
||||
phone: this.phone,
|
||||
code: this.code,
|
||||
newPassWord: aesEncrypt(this.passWord),
|
||||
};
|
||||
console.log(req, "res-");
|
||||
// return
|
||||
this.$u.apiList
|
||||
.ForgotPassword(req)
|
||||
.then((res) => {
|
||||
console.log(res, "res---");
|
||||
uni.showToast({
|
||||
title: "重置成功",
|
||||
duration: 2000,
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({
|
||||
url: "/",
|
||||
});
|
||||
}, 2000);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, "err---");
|
||||
// this.$tips(err.error, "error");
|
||||
this.$refs.uToast.show({
|
||||
title: err.error,
|
||||
type: 'error',
|
||||
})
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-style {
|
||||
color: #3cb5fb !important;
|
||||
padding: 0 !important;
|
||||
height: 70rpx !important;
|
||||
line-height: 60rpx !important;
|
||||
}
|
||||
|
||||
.custom-style::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.page {
|
||||
padding-bottom: 0.015rem;
|
||||
background-color: rgb(255, 255, 255);
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
|
||||
.image {
|
||||
flex-shrink: 0;
|
||||
align-self: flex-start;
|
||||
width: 102%;
|
||||
}
|
||||
|
||||
.group {
|
||||
padding: 1.0rem 0.29rem;
|
||||
|
||||
.text {
|
||||
align-self: left;
|
||||
// color: rgb(46, 155, 255);
|
||||
color: #000;
|
||||
font-size: 0.22rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.17rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.group_7 {
|
||||
margin-top: 0.29rem;
|
||||
|
||||
.text-wrapper {
|
||||
border: solid 2rpx #dcdfe6;
|
||||
border-radius: 100rpx;
|
||||
background: #f6f8fa;
|
||||
}
|
||||
|
||||
.group_6 {
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
.text_1 {
|
||||
margin-left: 0.01rem;
|
||||
align-self: flex-start;
|
||||
color: rgb(51, 51, 51);
|
||||
font-size: 0.15rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
|
||||
.view {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 20rpx;
|
||||
padding: 20rpx 50rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text_6 {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
margin-left: 0.01rem;
|
||||
margin-top: 0.2rem;
|
||||
align-self: flex-start;
|
||||
color: #1F2232;
|
||||
font-size: 0.13rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
|
||||
.text-wrapper_1 {
|
||||
margin: 50rpx 0rpx 40rpx;
|
||||
padding: 50rpx 0 50rpx;
|
||||
// background-image: linear-gradient(90deg, rgb(135, 230, 254) 0%, rgb(91, 192, 254) 52%, rgb(46, 155, 255) 100%);
|
||||
background: #3cb4fb;
|
||||
box-shadow: 0px 6rpx 9rpx rgba(38, 122, 199, 0.34);
|
||||
border-radius: 100rpx;
|
||||
|
||||
.text_7 {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 32rpx;
|
||||
font-family: PingFang;
|
||||
line-height: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.group_1 {
|
||||
margin-top: 0.12rem;
|
||||
|
||||
.text_8 {
|
||||
color: rgb(102, 102, 102);
|
||||
font-size: 24rpx;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
|
||||
.text_9 {
|
||||
margin-left: 0.035rem;
|
||||
color: rgb(25, 140, 255);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
}
|
||||
|
||||
.group_2 {
|
||||
margin-top: 0.36rem;
|
||||
justify-content: center;
|
||||
|
||||
.section_1 {
|
||||
flex-shrink: 0;
|
||||
width: 0.17rem;
|
||||
}
|
||||
|
||||
.group_3 {
|
||||
margin-left: 0.11rem;
|
||||
height: 0.18rem;
|
||||
line-height: 0.18rem;
|
||||
font-size: 0;
|
||||
|
||||
.text_10 {
|
||||
color: rgb(153, 153, 153);
|
||||
font-size: 0.11rem;
|
||||
font-family: PingFang;
|
||||
}
|
||||
|
||||
.text_11 {
|
||||
color: rgb(25, 140, 255);
|
||||
font-size: 0.11rem;
|
||||
font-family: PingFang;
|
||||
}
|
||||
|
||||
.text_12 {
|
||||
color: rgb(102, 102, 102);
|
||||
font-size: 0.11rem;
|
||||
font-family: PingFang;
|
||||
}
|
||||
|
||||
.text_13 {
|
||||
color: rgb(25, 140, 255);
|
||||
font-size: 0.11rem;
|
||||
font-family: PingFang;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 24rpx;
|
||||
color: #EF3920;
|
||||
display: flex;
|
||||
margin-top: 20rpx;
|
||||
|
||||
image {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-right: 10rpx;
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
<template>
|
||||
<view class="authentication-page">
|
||||
<u-navbar title="身份认证"> </u-navbar>
|
||||
|
||||
<view class="title">请填写您的真实信息</view>
|
||||
|
||||
<view class="form-container">
|
||||
<view class="input-item">
|
||||
<text>姓名</text>
|
||||
<input
|
||||
v-model="name"
|
||||
maxlength="20"
|
||||
type="text"
|
||||
placeholder="请输入"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="input-item">
|
||||
<text>身份证号</text>
|
||||
<input
|
||||
v-model="idCard"
|
||||
maxlength="18"
|
||||
type="text"
|
||||
placeholder="请输入"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn-container">
|
||||
<button class="next-btn" @click="handleNext">下一步</button>
|
||||
</view>
|
||||
|
||||
<u-toast ref="uToast" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import test from "@/uview-ui/libs/function/test.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
name: "",
|
||||
idCard: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleNext() {
|
||||
// 调用后端API获取token
|
||||
this.getTokenFromBackend();
|
||||
|
||||
if (!this.name) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请输入姓名",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
if (!this.idCard) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请输入身份证号",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
// 验证身份证号码格式
|
||||
if (!test.idCard(this.idCard)) {
|
||||
return this.$refs.uToast.show({
|
||||
title: "请输入正确的身份证号码",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
// 处理下一步逻辑
|
||||
// console.log("提交信息", this.name, this.idCard);
|
||||
},
|
||||
|
||||
// 获取token
|
||||
getTokenFromBackend() {
|
||||
this.$u.api.getAPIToken().then((res) => {
|
||||
const token = res.verifyToken
|
||||
|
||||
// 跳转到百度人脸核验页面
|
||||
this.redirectToBaiduVerification(token);
|
||||
});
|
||||
},
|
||||
|
||||
redirectToBaiduVerification(token) {
|
||||
// 获取当前域名
|
||||
const currentDomain = window.location.origin;
|
||||
|
||||
// 编码回调URL
|
||||
// const callbackUrl = encodeURIComponent(`${currentDomain}/success.html`);
|
||||
const callbackUrl = "/pages/login/recognitionResult/recognitionResult";
|
||||
|
||||
// 构建跳转URL
|
||||
const verifyUrl = `https://brain.baidu.com/face/print/verify/verify?token=${token}&successUrl=${callbackUrl}&failedUrl=${callbackUrl}`;
|
||||
|
||||
const verifyObj = {
|
||||
url: verifyUrl,
|
||||
name:'身份认证'
|
||||
};
|
||||
|
||||
// 在uni-app中跳转
|
||||
this.$u.route({
|
||||
url: `/pages/webview/index?data=${encodeURIComponent(
|
||||
JSON.stringify(verifyObj)
|
||||
)}`,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.authentication-page {
|
||||
padding: 0 30rpx;
|
||||
|
||||
.title {
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
line-height: 52rpx;
|
||||
text-align: left;
|
||||
margin-top: 30rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
background-color: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: 60rpx;
|
||||
|
||||
.input-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx 0;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
.next-btn {
|
||||
background-color: #45b5ff;
|
||||
color: #ffffff;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
border-radius: 45rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,338 @@
|
|||
<template>
|
||||
<view class="flex-col page">
|
||||
<!-- <image src="/static/common/img/16530269846087107196.png" class="image" /> -->
|
||||
<u-navbar title="确认密码"></u-navbar>
|
||||
<view class="flex-col group">
|
||||
<text class="text">确认密码后登录</text>
|
||||
<view class="flex-col group_7">
|
||||
<view class="flex-col">
|
||||
<view class="flex-row" style="padding: 0">
|
||||
<u-input type="password" v-model="user.passWord" placeholder="请输入密码" class="view text-wrapper"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-col group_6">
|
||||
<u-input type="password" v-model="isPassWord" placeholder="请确认密码" class="view text-wrapper" />
|
||||
</view>
|
||||
<view class="tips">
|
||||
<image src="/static/common/img/infoCircle.png"></image> 提示:密码长度应该大于5,必须包含字母、数字、特殊字符,且不能包含中文!
|
||||
</view>
|
||||
</view>
|
||||
<u-button class="flex-col items-center text-wrapper_1" throttle-time="1000" type="primary" shape="circle"
|
||||
@click="login"><text class="text_7">确定</text></u-button>
|
||||
<!-- 此次接入人脸验证 登录 ==> 确定 -->
|
||||
</view>
|
||||
<u-toast ref="uToast" />
|
||||
<u-top-tips ref="uTips" :navbar-height="0"></u-top-tips>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {aesEncrypt} from '@/utils/encrypt.js'
|
||||
import md5 from "js-md5";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
userName: "",
|
||||
isPassWord: "",
|
||||
agreement: false,
|
||||
user: {
|
||||
phone: '',
|
||||
passWord: '',
|
||||
code:''
|
||||
}
|
||||
};
|
||||
},
|
||||
onLoad(e) {
|
||||
if (e.phone) {
|
||||
this.user.phone = e.phone
|
||||
this.user.code = e.code
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: "../register/register",
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
login() {
|
||||
if (this.user.passWord === "") {
|
||||
return this.$refs.uToast.show({
|
||||
title: '请输入密码',
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
if (this.user.passWord.length < 5) {
|
||||
// return this.$tips("您的密码长度应该大于5", "error");
|
||||
return this.$refs.uToast.show({
|
||||
title: '您的密码长度应该大于5',
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
if (this.isPassWord === "") {
|
||||
return this.$refs.uToast.show({
|
||||
title: '请确认密码',
|
||||
type: 'error',
|
||||
})
|
||||
// return this.$tips("请确认密码", "error");
|
||||
}
|
||||
if (this.isPassWord !== this.user.passWord) {
|
||||
return this.$refs.uToast.show({
|
||||
title: '请确认两次密码是否一致',
|
||||
type: 'error',
|
||||
})
|
||||
// return this.$tips("请确认两次密码是否一致", "error");
|
||||
}
|
||||
uni.showLoading({
|
||||
title: "注册中",
|
||||
});
|
||||
const req = {...this.user}
|
||||
req.passWord = aesEncrypt(this.user.passWord)
|
||||
// 生成13位时间戳
|
||||
const timestamp = Date.now();
|
||||
// 生成签名
|
||||
const base64Key = btoa('xiaoyout!#@12345');
|
||||
const signStr = this.user.phone + timestamp + base64Key;
|
||||
const sign = md5(signStr);
|
||||
req.timeStamp = timestamp.toString();
|
||||
req.sign = sign;
|
||||
console.log(req,'req')
|
||||
// return
|
||||
this.$u.api.RegisterUser(req).then((res) => {
|
||||
const newReq = {...this.user}
|
||||
newReq.passWord = aesEncrypt(this.user.passWord)
|
||||
this.$u.api.LoginApp(newReq).then((ress) => {
|
||||
uni.hideLoading();
|
||||
// 保存登录后得到的用户数据
|
||||
this.$u.vuex('vuex_user', ress.user)
|
||||
this.$u.vuex('vuex_token', ress.token)
|
||||
this.$refs.uToast.show({
|
||||
title: '注册成功',
|
||||
type: 'success',
|
||||
})
|
||||
// uni.navigateTo({
|
||||
// url: "../perfect/perfect",
|
||||
// });
|
||||
setTimeout(()=>{
|
||||
// 这里改为进行人脸识别
|
||||
this.toBaiduApi();
|
||||
return
|
||||
|
||||
uni.navigateTo({
|
||||
url: "/pages/login/roleSelection",
|
||||
});
|
||||
},300)
|
||||
|
||||
}).catch((e) => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
|
||||
}).catch((e) => {
|
||||
uni.hideLoading();
|
||||
// this.$tips( e.error, 'error')
|
||||
this.$refs.uToast.show({
|
||||
title: e.error,
|
||||
type: 'error',
|
||||
})
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// 跳转至人脸验证
|
||||
toBaiduApi(){
|
||||
this.$u.api.getAPIToken().then((res) => {
|
||||
const token = res.result.verify_token;
|
||||
|
||||
// 跳转到百度人脸核验页面
|
||||
this.redirectToBaiduVerification(token);
|
||||
});
|
||||
},
|
||||
redirectToBaiduVerification(token) {
|
||||
// 获取当前域名
|
||||
const currentDomain = window.location.origin;
|
||||
|
||||
// 编码回调URL - 使用相对路径,让uni-app处理路由
|
||||
// 百度人脸核验会在回调URL后附加verify_result和verify_info参数
|
||||
const successUrl = encodeURIComponent(
|
||||
`${currentDomain}/#/pages/login/recognitionResult/recognitionResult?token=${token}`
|
||||
);
|
||||
const failedUrl = encodeURIComponent(
|
||||
`${currentDomain}/#/pages/login/recognitionResult/recognitionFailed?token=${token}`
|
||||
);
|
||||
|
||||
// 构建跳转URL
|
||||
const verifyUrl = `https://brain.baidu.com/face/print/verify/verify?token=${token}&successUrl=${successUrl}&failedUrl=${failedUrl}`;
|
||||
|
||||
console.log("跳转到百度人脸核验页面:", verifyUrl);
|
||||
|
||||
// 直接跳转到百度人脸核验页面
|
||||
window.location.href = verifyUrl;
|
||||
return;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-style {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.custom-style::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.page {
|
||||
padding-bottom: 0.015rem;
|
||||
background-color: rgb(255, 255, 255);
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
|
||||
.image {
|
||||
flex-shrink: 0;
|
||||
align-self: flex-start;
|
||||
width: 102%;
|
||||
}
|
||||
|
||||
.group {
|
||||
padding: 0.15rem 0.29rem;
|
||||
|
||||
.text {
|
||||
font-family: PingFang;
|
||||
font-weight: bold;
|
||||
font-size: 48rpx;
|
||||
color: #000000;
|
||||
margin-top: 200rpx;
|
||||
}
|
||||
|
||||
.group_7 {
|
||||
margin-top: 0.29rem;
|
||||
|
||||
.text-wrapper {
|
||||
border: solid 2rpx #dcdfe6;
|
||||
border-radius: 100rpx;
|
||||
background: #f6f8fa;
|
||||
}
|
||||
|
||||
.group_6 {
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
.text_1 {
|
||||
margin-left: 0.01rem;
|
||||
align-self: flex-start;
|
||||
color: rgb(51, 51, 51);
|
||||
font-size: 0.15rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.14rem;
|
||||
}
|
||||
|
||||
.view {
|
||||
margin-top: 20rpx;
|
||||
padding: 20rpx 50rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text_6 {
|
||||
margin-left: 0.01rem;
|
||||
margin-top: 0.13rem;
|
||||
align-self: flex-start;
|
||||
color: rgb(25, 140, 255);
|
||||
font-size: 0.13rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
|
||||
.text-wrapper_1 {
|
||||
margin: 0.35rem 0rem 0;
|
||||
padding: 20rpx 50rpx;
|
||||
height: 108rpx;
|
||||
/* background-image: linear-gradient(90deg,
|
||||
rgb(135, 230, 254) 0%,
|
||||
rgb(91, 192, 254) 52%,
|
||||
rgb(46, 155, 255) 100%);
|
||||
box-shadow: 0px 0.03rem 0.09rem rgba(38, 122, 199, 0.34); */
|
||||
background: #3cb5fb;
|
||||
border-radius: 0.23rem;
|
||||
|
||||
.text_7 {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 0.16rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.group_1 {
|
||||
margin-top: 0.12rem;
|
||||
|
||||
.text_8 {
|
||||
color: rgb(102, 102, 102);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
|
||||
.text_9 {
|
||||
margin-left: 0.035rem;
|
||||
color: rgb(25, 140, 255);
|
||||
font-size: 0.14rem;
|
||||
font-family: PingFang;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
}
|
||||
|
||||
.group_2 {
|
||||
margin-top: 0.36rem;
|
||||
justify-content: center;
|
||||
|
||||
.section_1 {
|
||||
flex-shrink: 0;
|
||||
width: 0.17rem;
|
||||
}
|
||||
|
||||
.group_3 {
|
||||
margin-left: 0.11rem;
|
||||
height: 0.18rem;
|
||||
line-height: 0.18rem;
|
||||
font-size: 0;
|
||||
|
||||
.text_10 {
|
||||
color: rgb(153, 153, 153);
|
||||
font-size: 0.11rem;
|
||||
font-family: PingFang;
|
||||
}
|
||||
|
||||
.text_11 {
|
||||
color: rgb(25, 140, 255);
|
||||
font-size: 0.11rem;
|
||||
font-family: PingFang;
|
||||
}
|
||||
|
||||
.text_12 {
|
||||
color: rgb(102, 102, 102);
|
||||
font-size: 0.11rem;
|
||||
font-family: PingFang;
|
||||
}
|
||||
|
||||
.text_13 {
|
||||
color: rgb(25, 140, 255);
|
||||
font-size: 0.11rem;
|
||||
font-family: PingFang;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.tips{
|
||||
font-size: 24rpx;
|
||||
color: #EF3920;
|
||||
display: flex;
|
||||
margin-top: 20rpx;
|
||||
image{
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,532 @@
|
|||
<template>
|
||||
<view class="flex-col page">
|
||||
<!-- <image src="/static/common/img/loginBg.png" class="image" /> -->
|
||||
<view class="img-box">
|
||||
|
||||
</view>
|
||||
<view class="login-box">
|
||||
<view class="tab-list">
|
||||
<view v-for="tab in tabList" :key="tab.id" class="tab-item"
|
||||
:class="activeTab === tab.id ? 'tab-selected' : 'not-selected'" @click="onTab(tab.id)">
|
||||
<text class="tab-text">{{tab.label}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-col group">
|
||||
<text class="text"></text>
|
||||
|
||||
<view class="flex-col group_7">
|
||||
<view class="flex-col">
|
||||
<!-- <text class="text_1">手机号</text> -->
|
||||
<!-- @input="changeInput($event)" -->
|
||||
<!-- <u-input type="number" v-model="userName" placeholder="请输入手机号" class="view text-wrapper" /> -->
|
||||
<u-input type="number" v-model="userName" placeholder="请输入手机号" class="view text-wrapper" maxlength="11"/>
|
||||
</view>
|
||||
<view class="error-tips" v-if="errorPhone"><image class="error-img" src="/static/common/img/infoCircle.png"></image> 请输入正确手机号</view>
|
||||
<view style="height: 0;width: 0;border: 0;padding: 0;margin: 0;overflow: hidden;">
|
||||
<u-input placeholder='' />
|
||||
</view>
|
||||
<view class="flex-col group_6">
|
||||
<!-- <text class="text_1">密码</text> -->
|
||||
<u-input type="password" v-model="passWord" placeholder="请输入密码" class="view text-wrapper" />
|
||||
</view>
|
||||
<!-- 密码必须包含字母、数字、特殊字符,且不能包含中文 -->
|
||||
<view class="error-tips" v-if="errorPwd"><image class="error-img" src="/static/common/img/infoCircle.png"></image> {{errormsg}}</view>
|
||||
|
||||
</view>
|
||||
<navigator class="text_6" style="width: 100%; text-align: right;" url="/pages/login/ForgetPassword/ForgetPassword">忘记密码?</navigator>
|
||||
<u-button class="flex-col items-center text-wrapper_1" throttle-time='1000' type="primary" shape="circle"
|
||||
@click="login"><text class="text_7">登录</text></u-button>
|
||||
<view class="justify-center group_1">
|
||||
<text class="text_8">还没有账号?</text>
|
||||
<navigator class="text_9" url="/pages/login/register/register">立即注册</navigator>
|
||||
</view>
|
||||
<!-- <view class="flex-row group_2">
|
||||
<u-checkbox-group class="section_1" :size='34'>
|
||||
<u-checkbox v-model="agreement"> </u-checkbox>
|
||||
</u-checkbox-group>
|
||||
<view class="group_3">
|
||||
<text class="text_10">已阅读并同意</text>
|
||||
<text class="text_11">《用户服务协议》</text>
|
||||
<text class="text_12">&</text>
|
||||
<text class="text_13">《用户隐私保护政策》</text>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<u-top-tips ref="uTips" :navbar-height='0'></u-top-tips>
|
||||
<u-toast ref="uToast" />
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
toBaiduApi
|
||||
} from '@/utils/faceVerify.js'
|
||||
import {
|
||||
aesEncrypt
|
||||
} from '@/utils/encrypt.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
userName: "",
|
||||
passWord: "",
|
||||
agreement: true,
|
||||
tabList: [{
|
||||
id: 1,
|
||||
label: '密码登录'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: '验证码登录'
|
||||
}
|
||||
],
|
||||
activeTab: 1,
|
||||
errorPhone: false,
|
||||
errorPwd: false,
|
||||
errormsg: "",
|
||||
};
|
||||
},
|
||||
onLoad(e) {},
|
||||
onHide(){
|
||||
this.userName= ""
|
||||
this.passWord= ""
|
||||
},
|
||||
onShow() {
|
||||
this.userName= ""
|
||||
this.passWord= ""
|
||||
setTimeout(() => {
|
||||
const lifeData = uni.getStorageSync('lifeData');
|
||||
if (lifeData.vuex_user && lifeData.vuex_token) {
|
||||
this.$u.api.getUser().then(res => {
|
||||
// if(!this.vuex_user.isCard){
|
||||
// uni.navigateTo({
|
||||
// url: '/pages/Face/index/index'
|
||||
// });
|
||||
// return
|
||||
// }
|
||||
uni.switchTab({
|
||||
url: '../../main/index/index'
|
||||
});
|
||||
})
|
||||
}
|
||||
}, 200)
|
||||
},
|
||||
methods: {
|
||||
changeInput(e){
|
||||
setTimeout(() => {
|
||||
this.userName = e.target.value
|
||||
}, 0);
|
||||
},
|
||||
onTab(id) {
|
||||
if(id == 1){
|
||||
this.activeTab = id
|
||||
}else{
|
||||
/* uni.showToast({
|
||||
title: '暂未开放',
|
||||
icon: 'none'
|
||||
}) */
|
||||
this.$refs.uToast.show({
|
||||
title: '暂未开放',
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
login() {
|
||||
// this.$u.vuex("vuex_msgList", '');
|
||||
// this.$u.vuex('vuex_user', '')
|
||||
// this.$u.vuex('vuex_token', '')
|
||||
// uni.clearStorage();
|
||||
if (!/^1[3-9]\d{9}$/.test(this.userName)) {
|
||||
// 校验手机号格式是否正确
|
||||
this.errorPhone = true;
|
||||
// return this.$tips("请输入正确的手机号", "error");
|
||||
return;
|
||||
} else {
|
||||
this.errorPhone = false;
|
||||
}
|
||||
// 校验密码格式先注释掉 因为重置密码的时候密码是1q2w3e
|
||||
// if (!/^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*?&.])[A-Za-z\d@$!%*?&.]{5,}$/.test(this.passWord)) {
|
||||
/* if (this.passWord.length < 6) {
|
||||
// 校验密码是否包含字母、数字、特殊字符,且长度至少为6
|
||||
this.errorPwd = true;
|
||||
// return this.$tips("密码必须包含字母、数字、特殊字符,且不能包含中文", "error");
|
||||
return;
|
||||
} else {
|
||||
this.errorPwd = false;
|
||||
} */
|
||||
/* if (!this.agreement) {
|
||||
return this.$tips("请同意用户服务协议及用户隐私保护政策", "error");
|
||||
} */
|
||||
if (this.passWord.length===0) {
|
||||
this.errorPwd = true;
|
||||
this.errormsg = "请输入密码";
|
||||
console.log("请输入密码");
|
||||
return
|
||||
}else if (this.passWord.length>0&&this.passWord.length < 6) {
|
||||
this.errorPwd = true;
|
||||
this.errormsg = "密码长度不能少于6位";
|
||||
console.log("密码长度不能少于6位");
|
||||
return
|
||||
}else{
|
||||
this.errorPwd = false;
|
||||
this.errormsg = "";
|
||||
}
|
||||
uni.showLoading({
|
||||
title: "登录中",
|
||||
});
|
||||
//
|
||||
let data = {
|
||||
phone: this.userName,
|
||||
password: aesEncrypt(this.passWord),
|
||||
}
|
||||
this.$u.api.LoginApp(data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (!res.succeed && !res.token) {
|
||||
/* uni.showToast({
|
||||
title: res.error,
|
||||
duration: 2000,
|
||||
icon: 'none'
|
||||
}); */
|
||||
// this.$tips(res.error, "error");
|
||||
this.$refs.uToast.show({
|
||||
title: err.error,
|
||||
type: "error",
|
||||
});
|
||||
return
|
||||
}
|
||||
// this.$tips("登录成功", "success")
|
||||
this.$refs.uToast.show({
|
||||
title: "登录成功",
|
||||
type: "success",
|
||||
});
|
||||
/* uni.showToast({
|
||||
title: "登录成功",
|
||||
duration: 2000,
|
||||
}); */
|
||||
// 保存登录后得到的用户数据
|
||||
this.$u.vuex('vuex_user', res.user)
|
||||
this.$u.vuex('vuex_token', res.token)
|
||||
this.$u.vuex('vuex_glyType', res.glyType)
|
||||
// if(!res.user.isCard){
|
||||
// uni.navigateTo({
|
||||
// url: '/pages/Face/index/index'
|
||||
// });
|
||||
// return
|
||||
// }
|
||||
if (res.user.isFill) {
|
||||
uni.switchTab({
|
||||
url: '/pages/home/home/home'
|
||||
});
|
||||
} else {
|
||||
// uni.navigateTo({
|
||||
// // url: "../perfect/perfect",
|
||||
// url: "../roleSelection",
|
||||
// });
|
||||
|
||||
// 没认证先前往人脸识别
|
||||
toBaiduApi(this);
|
||||
|
||||
return
|
||||
// 这里先注释
|
||||
uni.navigateTo({
|
||||
url: "/pages/login/roleSelection?source=login",
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
// this.$tips(err.error, "error");
|
||||
this.$refs.uToast.show({
|
||||
title: err.error,
|
||||
type: "error",
|
||||
});
|
||||
/* uni.showToast({
|
||||
title: err.error,
|
||||
icon: 'none'
|
||||
}) */
|
||||
})
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page {
|
||||
padding-bottom: 30rpx;
|
||||
background-color: rgb(255, 255, 255);
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
background: url(/static/common/img/loginBg.png);
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: top;
|
||||
|
||||
.img-box {
|
||||
height: 420rpx;
|
||||
}
|
||||
|
||||
.image {
|
||||
flex-shrink: 0;
|
||||
align-self: flex-start;
|
||||
width: 102%;
|
||||
}
|
||||
|
||||
.group {
|
||||
background: #fff;
|
||||
padding: 20rpx 25rpx;
|
||||
width: calc(100% - 50rpx);
|
||||
margin: 0 auto;
|
||||
border-radius: 30rpx;
|
||||
|
||||
.text {
|
||||
align-self: center;
|
||||
color: rgb(46, 155, 255);
|
||||
font-size: 32rpx;
|
||||
font-family: PingFang;
|
||||
line-height: 32rpx;
|
||||
}
|
||||
|
||||
.group_7 {
|
||||
margin-top: 40rpx;
|
||||
|
||||
.text-wrapper {
|
||||
border: solid 2rpx #dcdfe6;
|
||||
border-radius: 100rpx;
|
||||
background: #f6f8fa;
|
||||
|
||||
}
|
||||
|
||||
.group_6 {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.text_1 {
|
||||
margin-left: 10rpx;
|
||||
align-self: flex-start;
|
||||
color: rgb(51, 51, 51);
|
||||
font-size: 32rpx;
|
||||
font-family: PingFang;
|
||||
line-height: 30rpx;
|
||||
}
|
||||
|
||||
.view {
|
||||
margin-top: 20rpx;
|
||||
padding: 20rpx 50rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text_6 {
|
||||
margin-left: 5rpx;
|
||||
margin-top: 50rpx;
|
||||
align-self: flex-start;
|
||||
// color: rgb(25, 140, 255);
|
||||
color:#1F2232;
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang;
|
||||
line-height: 28rpx;
|
||||
}
|
||||
|
||||
.text-wrapper_1 {
|
||||
margin: 50rpx 0rpx 40rpx;
|
||||
padding: 50rpx 0 50rpx;
|
||||
// background-image: linear-gradient(90deg, rgb(135, 230, 254) 0%, rgb(91, 192, 254) 52%, rgb(46, 155, 255) 100%);
|
||||
background: #3cb4fb;
|
||||
box-shadow: 0px 6rpx 9rpx rgba(38, 122, 199, 0.34);
|
||||
border-radius: 100rpx;
|
||||
|
||||
.text_7 {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 32rpx;
|
||||
font-family: PingFang;
|
||||
line-height: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.group_1 {
|
||||
margin-top: 24rpx;
|
||||
|
||||
.text_8 {
|
||||
color: #8697AC;
|
||||
font-size: 30rpx;
|
||||
font-family: PingFang;
|
||||
line-height: 26rpx;
|
||||
}
|
||||
|
||||
.text_9 {
|
||||
margin-left: 0.035rem;
|
||||
color: #2E9CFE;
|
||||
font-size: 30rpx;
|
||||
font-family: PingFang;
|
||||
line-height: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.group_2 {
|
||||
margin-top: 40rpx;
|
||||
justify-content: center;
|
||||
|
||||
.section_1 {
|
||||
flex-shrink: 0;
|
||||
width: 34rpx;
|
||||
}
|
||||
|
||||
.group_3 {
|
||||
margin-left: 24rpx;
|
||||
height: 24rpx;
|
||||
font-size: 0;
|
||||
|
||||
.text_10 {
|
||||
color: rgb(153, 153, 153);
|
||||
font-size: 24rpx;
|
||||
font-family: PingFang;
|
||||
}
|
||||
|
||||
.text_11 {
|
||||
color: rgb(25, 140, 255);
|
||||
font-size: 24rpx;
|
||||
font-family: PingFang;
|
||||
}
|
||||
|
||||
.text_12 {
|
||||
color: rgb(102, 102, 102);
|
||||
font-size: 24rpx;
|
||||
font-family: PingFang;
|
||||
}
|
||||
|
||||
.text_13 {
|
||||
color: rgb(25, 140, 255);
|
||||
font-size: 24rpx;
|
||||
font-family: PingFang;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.login-box{
|
||||
background: #fff;
|
||||
width: calc(100% - 50rpx);
|
||||
margin: 0 auto;
|
||||
border-radius: 30rpx;
|
||||
// height: calc(100% - 350rpx);
|
||||
overflow: hidden;
|
||||
padding-bottom:100rpx;
|
||||
|
||||
}
|
||||
|
||||
$tab-height: 52px;
|
||||
$active-color: #fff;
|
||||
$default-color: #90ecf1;
|
||||
$primary-color: #666;
|
||||
|
||||
.tab-list {
|
||||
display: flex;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
border-radius: 30rpx 30rpx 0 0;
|
||||
background-color: $default-color;
|
||||
overflow: hidden; // 重点
|
||||
|
||||
.tab-item {
|
||||
flex: 1;
|
||||
height: $tab-height;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
// opacity: 0.65; // 暂时删除,不选中样式需要重新编写
|
||||
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.tab-selected {
|
||||
color:#3cb5fb;
|
||||
opacity: 1;
|
||||
background: #ffffff;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
box-shadow: 48rpx 80rpx 0 $active-color, -34rpx 90rpx 0 0 $active-color; // 重点
|
||||
.tab-text::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 160rpx;
|
||||
bottom: 10rpx;
|
||||
width: 32rpx;
|
||||
height: 8rpx;
|
||||
background: #3CB5FB;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-selected::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -12rpx;
|
||||
bottom: 0;
|
||||
width: 24rpx;
|
||||
height: $tab-height;
|
||||
border-top-left-radius: 48rpx;
|
||||
background-color: $active-color;
|
||||
transform: skewX(-15deg); // 重点
|
||||
}
|
||||
|
||||
.tab-selected::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -12rpx;
|
||||
bottom: 0;
|
||||
width: 24rpx;
|
||||
height: $tab-height;
|
||||
border-top-right-radius: 24rpx;
|
||||
background-color: $active-color;
|
||||
transform: skewX(15deg); // 重点
|
||||
}
|
||||
.not-selected {
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.not-selected::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 12rpx;
|
||||
bottom: 0;
|
||||
width: 24rpx;
|
||||
height: $tab-height;
|
||||
background: $default-color;
|
||||
border-bottom-left-radius: 24rpx;
|
||||
transform: skewX(15deg); // 重点
|
||||
}
|
||||
|
||||
.not-selected::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 12rpx;
|
||||
bottom: 0;
|
||||
width: 24rpx;
|
||||
height: $tab-height;
|
||||
background: $default-color;
|
||||
border-bottom-right-radius: 24rpx;
|
||||
transform: skewX(-15deg); // 重点
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
.error-tips{
|
||||
font-size: 24rpx;
|
||||
color: #EF3920;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
margin-top: 10rpx;
|
||||
// padding-left: 30rpx;
|
||||
.error-img{
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-right: 5rpx;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue