Browse Source

feat: page-index;

pull/1/head
Fox-33 1 day ago
parent
commit
26890e93f2
26 changed files with 937 additions and 1580 deletions
  1. +1
    -1
      App.vue
  2. +2
    -2
      api/api.js
  3. +20
    -201
      api/model/index.js
  4. +0
    -115
      api/model/info.js
  5. +0
    -35
      api/model/login.js
  6. +0
    -20
      api/model/vip.js
  7. +1
    -0
      common.scss
  8. +4
    -3
      config.js
  9. +3
    -10
      pages.json
  10. +54
    -59
      pages/index/index.vue
  11. +0
    -514
      pages_order/auth/loginAndRegisterAndForgetPassword.vue
  12. +0
    -155
      pages_order/auth/wxLogin.vue
  13. +0
    -133
      pages_order/auth/wxUserInfo.vue
  14. +0
    -254
      pages_order/search/index.vue
  15. +660
    -0
      pages_order/thesis/index.vue
  16. +191
    -0
      pages_order/thesis/search.vue
  17. BIN
      static/image/icon-degree.png
  18. BIN
      static/image/icon-empty.png
  19. BIN
      static/image/icon-pdf.png
  20. BIN
      static/image/icon-word.png
  21. BIN
      static/image/temp-11.png
  22. BIN
      static/image/temp-12.png
  23. BIN
      static/image/temp-13.png
  24. BIN
      static/image/temp-14.png
  25. +1
    -60
      store/store.js
  26. +0
    -18
      utils/utils.js

+ 1
- 1
App.vue View File

@ -3,7 +3,7 @@
onLaunch: function() {
},
onShow: function() {
// this.$store.commit('initConfig')
this.$store.commit('initConfig')
},
onHide: function() {
}


+ 2
- 2
api/api.js View File

@ -5,7 +5,7 @@ import utils from '../utils/utils.js'
let limit = {}
let debounce = {}
const models = ['login', 'index', 'vip', 'info']
const models = ['index']
const config = {
// 示例
@ -14,7 +14,7 @@ const config = {
// limit : 1000
// },
getConfig : {url : '/config_common/getConfig', method : 'GET', limit : 500},
getConfig : {url : '/config/queryConfigList', method : 'GET', limit : 500},
}


+ 20
- 201
api/model/index.js View File

@ -1,215 +1,34 @@
// 首页相关接口
const api = {
// 获取首页轮播图
getRiceBanner: {
url: '/index_common/getRiceBanner',
/**
* 获取banner图列表
*/
queryBannerList: {
url: '/index/queryBannerList',
method: 'GET',
},
// 获取首页常规产品【废弃】
// getRiceCommonProductList: {
// url: '/index_common/getRiceCommonProductList',
// method: 'GET',
// },
// 获取首页跳转图标
getRiceIconList: {
url: '/index_common/getRiceIconList',
/**
* 获取论文分类列表
*/
queryCategoryThesisList: {
url: '/config/queryCategoryThesisList',
method: 'GET',
},
// 获取首页新闻详情
getRiceNewsDetail: {
url: '/index_common/getCommonNewsDetail',
/**
* 获取论文文章列表
*/
queryThesisList: {
url: '/index/queryThesisList',
method: 'GET',
},
// 获取首页新闻列表
getRiceNewsList: {
url: '/index_common/getRiceNewsList',
/**
* 获取论文文章详情
*/
queryThesisById: {
url: '/index/queryThesisById',
method: 'GET',
},
// 获取首页公告列表
getRiceNoticeList: {
url: '/index_common/getRiceNoticeList',
method: 'GET',
},
// 获取首页商品详情
getRiceProductDetail: {
url: '/index_common/getRiceProductDetail',
method: 'GET',
},
// 获取首页体验产品
getRiceProductList: {
url: '/index_common/getRiceProductList',
method: 'GET',
},
// 查询分类接口
getCategoryList: {
url: '/index_common/getCategoryList',
method: 'GET',
},
// 新查询分类以及商品数据接口
getCategoryPidList: {
url: '/index_common/getCategoryPidList',
method: 'GET',
debounce : 250,
},
// 查询一级分类接口
getPidList: {
url: '/index_common/getCategoryPidList',
method: 'GET',
},
// 获取分类分页商品列表接口
getClassShopPageList: {
url: '/index_common/getClassShopPageList',
method: 'GET',
},
// 加入购物车
addCart: {
url: '/index_common/addCart',
method: 'GET',
auth: true,
showLoading: true,
limit : 500,
},
// 删除购物车信息
deleteCart: {
url: '/index_common/deleteCart',
method: 'DELETE',
auth: true,
showLoading: true,
},
// 修改购物车信息数量
updateCartNum: {
url: '/index_common/updateCartNum',
method: 'POST',
auth: true,
debounce: 300,
},
// 创建订单
createOrder: {
url: '/index_common/createOrder',
method: 'GET',
auth: true,
limit: 1000,
showLoading: true,
},
// 创建订单-再次支付
createOrderTwo: {
url: '/index_common/createOrderTwo',
method: 'GET',
auth: true,
limit: 1000,
showLoading: true,
},
// 多商品创建订单
createSumOrder: {
url: '/index_common/createSumOrder',
method: 'POST',
auth: true,
limit: 1000,
showLoading: true,
},
// 多商品订单再次支付
createSumOrderAgain: {
url: '/index_common/createSumOrderAgain',
method: 'POST',
auth: true,
limit: 1000,
showLoading: true,
},
// 确认收货
confirmOrder: {
url: '/index_common/confirmOrder',
method: 'GET',
auth: true,
limit: 1000,
showLoading: true,
},
// 取消订单
cancelOrder: {
url: '/index_common/cancelOrder',
method: 'GET',
auth: true,
limit: 1000,
showLoading: true,
},
// 获取首页广告列表
getRiceProductList: {
url: '/index_common/getRiceAdList',
method: 'GET',
},
// 获取首页广告列表
getRiceAdDetail: {
url: '/index_common/getRiceAdDetail',
method: 'GET',
},
//获取优惠券信息
getRiceCouponList: {
url: '/info_common/getRiceCouponList',
method: 'GET',
},
//增加或者修改合伙人申请信息
addOrUpdateCommonUser: {
url: '/index_common/addOrUpdateCommonUser',
method: 'POST',
},
//根据用户查询渠合伙人申请信息表单
getCommonUser: {
url: '/index_common/getCommonUser',
method: 'GET'
},
//提交反馈信息
addFeedback: {
url: '/info_common/addFeedback',
method: 'POST'
},
// 获取我的直接推荐间接推荐用户列表带分页
getHanHaiMemberUser: {
url: '/info_common/getHanHaiMemberUser',
method: 'GET'
},
// 获取祝福背景图
getRiceBlessing: {
url: '/index_common/getRiceBlessing',
method: 'GET'
},
// 随机获取祝福语
getRiceBlessingWords: {
url: '/index_common/getRiceBlessingWords',
method: 'GET'
},
// 根据订单标识修改订单祝福语背景
updateOrderBlessing: {
url: '/index_common/updateOrderBlessing',
method: 'POST',
auth : true,
limit : 1000,
},
// 1.收礼流程 =》点击收礼
getGiveShop: {
url: '/index_common/getGiveShop',
method: 'GET',
auth : true,
limit : 1000,
},
// 2.点击抽奖 =》抽奖
getGiveShopLottery: {
url: '/index_common/getGiveShopLottery',
method: 'GET',
auth : true,
limit : 1000,
},
// 获取我的礼品订单
getMyGiftOrder: {
url: '/index_common/getMyGiftOrder',
method: 'GET',
auth : true,
},
// 获取我的礼品订单详情
getMyGiftOrderDetail: {
url: '/index_common/getMyGiftOrderDetail',
method: 'GET',
auth : true,
},
}
export default api

+ 0
- 115
api/model/info.js View File

@ -1,115 +0,0 @@
// 个人相关接口
const api = {
// 充值
recharge: {
url: '/info_common/withdraw',
method: 'GET',
auth: true,
limit: 1000,
showLoading: true,
},
// 提现
withdraw: {
url: '/info_common/withdraw',
method: 'GET',
auth: true,
limit: 1000,
showLoading: true,
},
// 获取地址列表带分页
getAddressPageList: {
url: '/info_common/getAddressPageList',
method: 'GET',
auth: true,
},
// 增加或修改地址信息
addOrUpdateAddress: {
url: '/info_common/addOrUpdateAddress',
method: 'POST',
limit: 500,
auth: true,
showLoading: true,
},
// 删除地址
deleteAddress: {
url: '/info_common/deleteAddress',
method: 'GET',
limit: 500,
auth: true,
showLoading: true,
},
// 修改默认地址
updateDefaultAddress: {
url: '/info_common/updateDefaultAddress',
method: 'GET',
auth: true,
limit: 1000,
},
// 获取粉丝列表带分页
getFansPageList: {
url: '/info_common/getFansPageList',
method: 'GET',
auth: true,
},
// 获取相关介绍
getInfoIntroduce: {
url: '/info_common/getInfoIntroduce',
method: 'GET',
auth: true,
},
// 获取个人邀请码
getInviteCode: {
url: '/info_common/getInviteCode',
method: 'GET',
auth: true,
},
// 获取订单列表带分页
getOrderPageList: {
url: '/info_common/getOrderPageList',
method: 'GET',
auth: true,
},
// 获取订单详情
getOrderDetail: {
url: '/info_common/getOrderDetail',
method: 'GET',
auth: true,
},
// 获取流水记录带分页
getWaterPageList: {
url: '/info_common/getWaterPageList',
method: 'GET',
auth: true,
},
// 获取相关介绍
getInfoIntroduce: {
url: '/info_common/getInfoIntroduce',
method: 'GET',
},
// 获取相关介绍详情
getInfoIntroduceDetail: {
url: '/info_common/getRiceNewsDetail',
method: 'GET',
},
// 查询个人信息相关
getRiceInfo: {
url: '/info_common/getRiceInfo',
method: 'GET',
limit: 500,
},
// 获取购物车信息列表带分页
getCartPageList: {
url: '/info_common/getCartPageList',
method: 'GET',
},
// 领取新人优惠券
getRiceCoupon: {
url: '/info_common/getRiceCoupon',
method: 'GET',
limit: 500,
auth: true,
},
}
export default api

+ 0
- 35
api/model/login.js View File

@ -1,35 +0,0 @@
// 登录相关接口
const api = {
// 微信登录接口
wxLogin: {
url: '/login_common/appletLogin',
method: 'GET',
limit : 500,
showLoading : true,
},
// 获取绑定手机号码
bindPhone: {
url: '/login_common/bindPhone',
method: 'GET',
auth: true,
},
// 修改个人信息接口
updateInfo: {
url: '/info_common/updateInfo',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
},
// 获取个人信息
getInfo: {
url: '/info_common/getInfo',
method: 'GET',
auth: true,
},
}
export default api

+ 0
- 20
api/model/vip.js View File

@ -1,20 +0,0 @@
// vip相关接口
const api = {
// 获取会员权益列表
getRiceVipList: {
url: '/index_common/getVipInfoList',
method: 'GET',
},
// 申请成为会员
applyRiceVip: {
url: '/rice_vip/applyRiceVip',
method: 'POST',
limit : 500,
auth : true,
showLoading : true,
},
}
export default api

+ 1
- 0
common.scss View File

@ -45,6 +45,7 @@
background-color: $uni-bg-color;
position: relative;
font-family: PingFang SC;
font-weight: 400;
line-height: 1.4;
}


+ 4
- 3
config.js View File

@ -1,22 +1,23 @@
import Vue from 'vue'
import api from '@/api/api.js'
import fetch from '@/api/fetch.js'
import utils from './utils/utils.js'
import uvUI from '@/uni_modules/uv-ui-tools'
Vue.use(uvUI);
// 当前环境
const type = 'dev'
const type = 'prod'
// 环境配置
const config = {
dev : {
baseUrl : 'http://www.gcosc.fun:82',
baseUrl: 'http://augcl.natapp1.cc/education-admin/education',
},
prod : {
baseUrl : 'http://xxx.xxx.xxx/xxx',
baseUrl: 'https://www.jgyt.chat/education-admin/education',
}
}


+ 3
- 10
pages.json View File

@ -33,16 +33,9 @@
"subPackages": [{
"root": "pages_order",
"pages": [{
"path": "auth/wxLogin"
},
{
"path": "auth/wxUserInfo"
},
{
"path": "auth/loginAndRegisterAndForgetPassword"
},
{
"path": "search/index"
"path": "thesis/search"
},{
"path": "thesis/index"
}
]
}],


+ 54
- 59
pages/index/index.vue View File

@ -20,25 +20,27 @@
<view class="section card" v-for="(group, gIdx) in list" :key="group.id">
<view class="card-header">
<view class="card-header-title">{{ group.label }}</view>
<view class="card-header-title">{{ group.title }}</view>
<view class="card-header-tag">JGYT</view>
</view>
<view class="card-content">
<template v-if="gIdx === 0">
<view class="card-item card-row" v-for="item in group.children" :key="item.id" @click="jumpToCategory(item)">
<view class="card-item card-row" v-for="item in group.children" :key="item.id">
<view class="flex info">
<!-- todo -->
<image class="info-icon" :src="item.icon" mode="widthFix"></image>
<view class="info-label">{{ item.label }}</view>
<view class="info-label">{{ item.title }}</view>
</view>
<button class="btn">查看</button>
<button class="btn" @click="jumpToCategory(group.id, item.id, item.title)">查看</button>
</view>
</template>
<template v-else>
<view class="card-box">
<view class="card-item info" v-for="item in group.children" :key="item.id" @click="jumpToCategory(item)">
<view class="card-item info" v-for="item in group.children" :key="item.id" @click="jumpToCategory(group.id, item.id, item.title)">
<!-- todo -->
<image class="info-icon" :src="item.icon" mode="widthFix"></image>
<view class="info-label">{{ item.label }}</view>
<view class="info-label">{{ item.title }}</view>
</view>
</view>
</template>
@ -71,73 +73,66 @@
this.getData()
},
methods: {
getData() {
// todo
this.list = [
{
id: '001',
label: '导航检索',
children: [
{ id: '0011', label: 'AHCI', icon: '/static/image/temp-4.png', },
{ id: '0012', label: 'EI会议', icon: '/static/image/temp-9.png', },
{ id: '0013', label: 'EI源刊', icon: '/static/image/temp-10.png', },
{ id: '0014', label: 'ESCI', icon: '/static/image/temp-5.png', },
{ id: '0015', label: 'SCI', icon: '/static/image/temp-6.png', },
{ id: '0016', label: 'Scoupus', icon: '/static/image/temp-7.png', },
{ id: '0017', label: 'SSCI', icon: '/static/image/temp-8.png', },
],
},
{
id: '002',
label: '精选内容',
children: [
{ id: '0021', label: 'AHCI', icon: '/static/image/temp-4.png', },
{ id: '0022', label: 'EI会议', icon: '/static/image/temp-9.png', },
{ id: '0023', label: 'AHCI', icon: '/static/image/temp-4.png', },
{ id: '0024', label: 'EI会议', icon: '/static/image/temp-9.png', },
],
},
{
id: '003',
label: '精选内容',
children: [
{ id: '0031', label: 'AHCI', icon: '/static/image/temp-4.png', },
{ id: '0032', label: 'EI会议', icon: '/static/image/temp-9.png', },
{ id: '0033', label: 'AHCI', icon: '/static/image/temp-4.png', },
{ id: '0034', label: 'EI会议', icon: '/static/image/temp-9.png', },
],
},
]
async getData() {
try {
let records = (await this.$fetch('queryCategoryThesisList', { pageNo: 1, pageSize: 1000 }))?.records
let groups = []
records.forEach(record => {
if (record.hasChild == 1) {
// todo: icon
const { id, title, createTime } = record
const index = groups.findIndex(group => group.id === id)
if (index === -1) {
groups.push({ id, title, createTime, children: [] })
} else {
groups[index].title = title
groups[index].createTime = createTime
}
} else {
// todo: icon
const { pid, id, title, createTime } = record
const index = groups.findIndex(group => group.id === pid)
const item = { id, title, createTime }
if (index === -1) {
groups.push({ id: pid, children: [item] })
} else {
groups[index].children.push(item)
}
}
})
groups.forEach(group => {
let { children } = group
children.sort((a, b) => new Date(a.createTime).getTime() - new Date(b.createTime).getTime())
group.children = children
})
groups.sort((a, b) => new Date(a.createTime).getTime() - new Date(b.createTime).getTime())
this.list = groups
} catch (err) {
}
},
search() {
uni.navigateTo({
url: '/pages_order/search/index?search=' + this.keyword
url: '/pages_order/thesis/search?search=' + this.keyword
})
this.keyword = ''
},
//
async fetchBanner() {
try {
// todo
// this.bannerList = (await this.$fetch('queryBannerList'))?.records
this.bannerList = [
{ image: '/static/image/temp-1.png' },
{ image: '/static/image/temp-2.png' },
{ image: '/static/image/temp-3.png' },
{ image: '/static/image/temp-2.png' },
]
this.bannerList = (await this.$fetch('queryBannerList', { type: '0' }))?.records // type0- 1- 2- 3-
} catch (err) {
}
},
jumpToCategory(obj) {
const { id, label } = obj
jumpToCategory(categoryOne, categoryTwo, title) {
uni.navigateTo({
url: `/pages_order/search/index?cid=${id}&title=${label}`
url: `/pages_order/thesis/search?categoryOne=${categoryOne}&categoryTwo=${categoryTwo}&title=${title}`
})
},
},


+ 0
- 514
pages_order/auth/loginAndRegisterAndForgetPassword.vue View File

@ -1,514 +0,0 @@
<template>
<view class="refundsOrExchange">
<navbar :title="titleList[titleIndex]" leftClick
@leftClick="$utils.redirectTo('/pages/index/index')" />
<view class="frame">
<!-- 注册 -->
<view class='forgetPassword' v-if='titleIndex == 0'>
<!-- 标题 -->
<view class="title">{{titleList[titleIndex]}}</view>
<!-- 表单 -->
<view class="form1">
<view class="userName">
<uv-input v-model="form1.username" placeholder="请输入手机号" border="surround" shape='circle'
clearable :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
<view class="code">
<view class="left">
<uv-input v-model="form1.captcha" placeholder="请输入验证码" border="surround" shape='circle'
clearable :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
<view class="right">
<view>
<uv-toast ref="toast"></uv-toast>
<uv-code :seconds="seconds" @end="end" @start="start" ref="code"
@change="codeChange"></uv-code>
<uv-button @tap="getCode" iconSize='10rpx' color='#1f1c39'
shape='circle'>{{tips}}</uv-button>
</view>
</view>
</view>
<view class="password1">
<uv-input v-model="form1.password" placeholder="设置您的新密码(6到50个字符)" password clearable
border="surround" shape='circle' :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
<view class="password2">
<uv-input v-model="form1.newPassword" placeholder="重新确认密码" password clearable border="surround"
shape='circle' :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
</view>
<view>
<uv-checkbox-group v-model="checkboxValue" shape="circle">
<view class="content">
<view style="display: flex;">
<uv-checkbox size="30rpx" :name="1"></uv-checkbox>
请你阅读并同意我们的<span style="color: #fd5100"
@click="$refs.popup.open('getPrivacyPolicy')">隐私条款</span><span
style="color: #fd5100"
@click="$refs.popup.open('getUserAgreement')">服务协议</span>
</view>
</view>
</uv-checkbox-group>
</view>
</view>
<!-- 登录 -->
<view class="loginRegister" v-if='titleIndex==1'>
<!-- 标题 -->
<view class="title">{{titleList[titleIndex]}}</view>
<!-- 头像 -->
<view class="userIamge">
<view>
<img src="/static/image/center/11.svg" alt="" style="width: 100%;height: 100%;">
</view>
</view>
<!-- 用户名&密码&隐私条款 -->
<view class="form">
<view>
<uv-input v-model="form.username" placeholder="请输入账号" border="surround" shape='circle' clearable
:customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
<view>
<uv-input v-model="form.password" password placeholder="请输入密码" border="surround" shape='circle'
clearable :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
<view>
<uv-checkbox-group v-model="checkboxValue" shape="circle">
<view class="content">
<view style="display: flex;">
<uv-checkbox size="30rpx" :name="1"></uv-checkbox>
请你阅读并同意我们的<span style="color: #fd5100"
@click="$refs.popup.open('yszc')">隐私条款</span><span
style="color: #fd5100"
@click="$refs.popup.open('fwxy')">服务协议</span>
</view>
</view>
</uv-checkbox-group>
</view>
</view>
</view>
<!-- 忘记密码 -->
<view class='forgetPassword' v-if='titleIndex == 2'>
<!-- 标题 -->
<view class="title">{{titleList[titleIndex]}}</view>
<!-- 表单 -->
<view class="form1">
<view class="userName">
<uv-input v-model="form1.username" placeholder="请输入手机号" border="surround" shape='circle'
clearable :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
<view class="code">
<view class="left">
<uv-input v-model="form1.captcha" placeholder="请输入验证码" border="surround" shape='circle'
clearable :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
<view class="right">
<view>
<uv-toast ref="toast"></uv-toast>
<uv-code :seconds="seconds" @end="end" @start="start" ref="code"
@change="codeChange"></uv-code>
<uv-button @tap="getCode" iconSize='10rpx' color='#1f1c39'
shape='circle'>{{tips}}</uv-button>
</view>
</view>
</view>
<view class="password1">
<uv-input v-model="form1.password" placeholder="设置您的新密码(6到50个字符)" password clearable
border="surround" shape='circle' :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
<view class="password2">
<uv-input v-model="form1.newPassword" placeholder="重新确认密码" password clearable border="surround"
shape='circle' :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input>
</view>
</view>
</view>
<!-- 按钮 -->
<view class="btn" @click="submit">
<button class='a'>{{titleList[titleIndex]}}</button>
</view>
<!-- tab -->
<view class="bottomTab">
<span :class="titleIndex==0 ? 'tabbarItemActive' : 'tabbarItemNoActive'"
@click='changePage(0)'>注册账号</span>
<span style="color: #9c9fa4">|</span>
<span :class="titleIndex==1 ? 'tabbarItemActive' : 'tabbarItemNoActive'"
@click='changePage(1)'>账号登录</span>
<span style="color: #9c9fa4">|</span>
<span :class="titleIndex==2 ? 'tabbarItemActive' : 'tabbarItemNoActive'"
@click='changePage(2)'>忘记密码</span>
</view>
</view>
<configPopup ref="popup"></configPopup>
</view>
</template>
<script>
import configPopup from '@/components/config/configPopup.vue';
export default {
components: {
configPopup
},
onLoad(option) {
this.titleIndex = option.index || 1
},
data() {
return {
titleIndex: 0,
titleList: ['注册', '登录', '重置密码'],
checkboxValue: [],
form: {
username: '',//19330214982
password: '',//1234567
loginModel: 0,
captcha: '',
},
form1: {
username: '',
captcha: '',
password: '',
newPassword: '',
},
tips: '获取验证码',
seconds: 60,
}
},
methods: {
submit() {
if (!this.checkboxValue.length && this.titleIndex != 2) {
return uni.showToast({
title: '请先同意隐私协议',
icon: 'none'
})
}
if (this.titleIndex == 0) {
//
this.register()
} else if (this.titleIndex == 1) {
//
this.login()
} else {
//
this.updatePassword()
}
},
//
login(){
if (this.$utils.verificationAll(this.form, {
username: '请输入账号',
password: '请输入密码',
})) {
return
}
if (!this.$utils.verificationPhone(this.form.username)) {
return uni.showToast({
title: '请输入合法的手机号',
icon: 'none'
})
}
//
this.$store.commit('login', this.form)
},
//
register(){
if (this.$utils.verificationAll(this.form1, {
username: '请输入账号',
captcha : '请输入验证码',
password: '请输入密码',
newPassword: '请确认密码',
})) {
return
}
if (!this.$utils.verificationPhone(this.form1.username)) {
return uni.showToast({
title: '请输入合法的手机号',
icon: 'none'
})
}
if (this.form1.password != this.form1.newPassword) {
return uni.showToast({
title: '密码与确认密码不一致',
icon: 'none'
})
}
this.$api('registerUser', this.form1, res => {
this.form1 = {}
if (res.code == 200) {
this.titleIndex = 1
uni.showToast({
title: '注册成功,请登录!',
icon: 'none'
})
}
})
},
updatePassword(){
if (this.$utils.verificationAll(this.form1, {
username: '请输入账号',
captcha : '请输入验证码',
password: '请输入新密码',
newPassword: '请确认密码',
})) {
return
}
if (!this.$utils.verificationPhone(this.form1.username)) {
return uni.showToast({
title: '请输入合法的手机号',
icon: 'none'
})
}
if (this.form1.password != this.form1.newPassword) {
return uni.showToast({
title: '密码与确认密码不一致',
icon: 'none'
})
}
this.$api('newPassword', this.form1, res => {
this.form1 = {}
if (res.code == 200) {
this.titleIndex = 1
uni.showToast({
title: '修改成功,请登录!',
icon: 'none'
})
}
})
},
//
changePage(index) {
this.titleIndex = index
},
confirm() {
},
codeChange(text) {
this.tips = text;
},
getCode() {
if (this.$refs.code.canGetCode) {
if (!this.$utils.verificationPhone(this.form1.username)) {
return uni.showToast({
title: '请输入合法的手机号',
icon: 'none'
})
}
uni.showLoading({
title: '正在获取验证码'
})
this.$api('sendSms', {
username: this.form1.username,
}, res => {
if (res.code == 200) {
uni.hideLoading();
// this.start()
uni.$uv.toast('验证码已发送');
//
this.$refs.code.start();
}
})
} else {
uni.$uv.toast('请勿重复发送');
}
},
end() {
// uni.$uv.toast('');
},
start() {
// uni.$uv.toast('');
}
}
}
</script>
<style lang="scss" scoped>
* {
box-sizing: border-box;
}
.content{
font-size: 22rpx;
margin: 0 auto;
}
.refundsOrExchange {
background-color: #FFF;
height: 100vh;
.frame {
background-color: #FFF;
.loginRegister {
display: flex;
flex-direction: column;
gap: 40rpx;
padding-bottom: 50rpx;
.title {
display: flex;
justify-content: center;
align-items: flex-end;
height: 10vh;
color: #000;
font-size: 40rpx;
font-weight: 700;
}
.userIamge {
display: flex;
justify-content: center;
height: 10vh;
>view:nth-of-type(1) {
width: 25%;
height: 100%;
border-radius: 50%;
overflow: hidden;
}
}
.form {
height: 12vh;
>view:nth-of-type(1) {
padding: 20rpx 100rpx;
}
>view:nth-of-type(2) {
padding: 0 100rpx;
}
>view:nth-of-type(3) {
display: flex;
padding: 30rpx 100rpx 0 100rpx;
font-size: 22rpx;
}
}
}
.btn {
// height: 5vh;
display: flex;
justify-content: center;
margin: 90rpx 0 0 0;
.a {
display: flex;
justify-content: center;
align-items: center;
width: 70%;
height: 80rpx;
color: #FFF;
background-color: $uni-color;
box-shadow: 0 0 4rpx 4rpx rgba($uni-color, 0.2);
border-radius: 100rpx;
font-size: 30rpx;
}
}
.bottomTab {
display: flex;
justify-content: space-between;
height: 10vh;
padding: 0 80rpx;
margin-top: 30rpx;
.tabbarItemActive {
color: $uni-color;
}
.tabbarItemNoActive {
color: #9c9fa4;
}
}
.forgetPassword {
padding: 100rpx 40rpx 0 40rpx;
.title {
display: flex;
justify-content: center;
align-items: flex-end;
height: 10vh;
color: #000;
font-size: 40rpx;
font-weight: 700;
}
.form1 {
display: flex;
flex-direction: column;
gap: 30rpx;
margin-top: 20rpx;
padding: 20rpx 80rpx;
.userName {
// padding: 20rpx 100 rpx;
}
.code {
display: flex;
width: 100%;
.left {
width: 55%;
}
.right {
width: 45%;
height: 100%;
>view:nth-of-type(1) {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
}
}
}
.password1 {}
.password2 {}
}
}
}
}
</style>

+ 0
- 155
pages_order/auth/wxLogin.vue View File

@ -1,155 +0,0 @@
<template>
<view class="login">
<view class="logo">
<!-- <image src="/static/image/login/logo.png" mode=""></image> -->
</view>
<view class="title">
欢迎使用酒店桌布租赁平台
</view>
<view class="btn mt"
@click="wxLogin">
<view class="icon">
<image src="../static/auth/wx.png" mode=""></image>
</view>
<view class="">
微信授权登录
</view>
</view>
<!-- <view class="btn b2">
使用短信验证登录
</view> -->
<view class="btn b2"
@click="qux">
取消登录
</view>
<view class="config">
<uv-checkbox-group
v-model="checkboxValue"
shape="circle">
<view class="content">
<view
style="display: flex;">
<uv-checkbox
size="40rpx"
icon-size="30rpx"
activeColor="#FD5100"
:name="1"
></uv-checkbox>
阅读并同意我们的<text @click="$refs.popup.open('getPrivacyPolicy')">服务协议与隐私条款</text>
</view>
<view class="">
以及<text @click="$refs.popup.open('getUserAgreement')">个人信息保护指引</text>
</view>
</view>
</uv-checkbox-group>
</view>
<configPopup ref="popup"></configPopup>
</view>
</template>
<script>
export default {
name : 'Login',
data() {
return {
checkboxValue : []
}
},
methods: {
wxLogin(){
if(!this.checkboxValue.length){
return uni.showToast({
title: '请先同意隐私协议',
icon:'none'
})
}
this.$store.commit('login')
},
qux(){
uni.reLaunch({
url: '/pages/index/index'
})
},
}
}
</script>
<style scoped lang="scss">
.login{
display: flex;
justify-content: center;
align-items: center;
height: 80vh;
flex-direction: column;
position: relative;
.logo{
height: 140rpx;
width: 140rpx;
background-color: #ddd;
border-radius: 30rpx;
image{
height: 140rpx;
width: 140rpx;
border-radius: 30rpx;
}
margin-bottom: 20rpx;
}
.title{
position: relative;
font-weight: 900;
font-size: 45rpx;
&::after{
content: '';
position: absolute;
left: 0;
top: 100%;
display: block;
height: 8rpx;
width: 210rpx;
background: linear-gradient(to right,$uni-color, #fff);
}
}
.btn{
width: 80%;
height: 100rpx;
background-color: $uni-color;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
margin: 20rpx 0;
border-radius: 20rpx;
.icon{
margin-right: 10rpx;
image{
width: 40rpx;
height: 35rpx;
}
}
}
.b2{
background-color: rgba($uni-color, 0.2);
color: $uni-color;
}
.mt{
margin-top: 200rpx;
}
.config{
position: absolute;
bottom: 0;
font-size: 24rpx;
text-align: center;
line-height: 40rpx;
text{
color: $uni-color;
}
}
}
</style>

+ 0
- 133
pages_order/auth/wxUserInfo.vue View File

@ -1,133 +0,0 @@
<template>
<view class="login">
<view class="title">
酒店桌布租赁平台
</view>
<view class="title">
申请获取你的头像昵称
</view>
<button class="chooseAvatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<view class="line">
<view class="">
头像
</view>
<view class="">
<image :src="userInfo.headImage" v-if="userInfo.headImage" style="width: 60rpx;height: 60rpx;"
mode=""></image>
<image src="../static/auth/headImage.png" v-else style="width: 50rpx;height: 50rpx;" mode=""></image>
</view>
</view>
</button>
<view class="line">
<view class="">
昵称
</view>
<view class="">
<input type="nickname" placeholder="请输入昵称" style="text-align: right;" id="nickName"
v-model="userInfo.nickName" />
</view>
</view>
<view class="btn" @click="submit">
确认
</view>
</view>
</template>
<script>
export default {
data() {
return {
userInfo: {
headImage: '',
nickName: '',
}
};
},
onShow() {},
computed: {},
methods: {
onChooseAvatar(res) {
let self = this
self.$Oss.ossUpload(res.target.avatarUrl)
.then(url => {
self.userInfo.headImage = url
})
},
submit() {
let self = this
uni.createSelectorQuery().in(this)
.select("#nickName")
.fields({
properties: ["value"],
})
.exec((res) => {
const nickName = res?.[0]?.value
self.userInfo.nickName = nickName
if (self.$utils.verificationAll(self.userInfo, {
headImage: '请选择头像',
nickName: '请填写昵称',
})) {
return
}
self.$api('updateInfo', self.userInfo, res => {
if (res.code == 200) {
uni.switchTab({
url:'/pages/index/index'
})
}
})
})
},
}
}
</script>
<style lang="scss" scoped>
.login {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 80vh;
.title {
line-height: 45rpx;
font-weight: 900;
}
.line {
display: flex;
justify-content: space-between;
align-items: center;
width: 80%;
border-bottom: 1px solid #00000023;
padding: 30rpx 0;
margin: 0 auto;
}
.chooseAvatar {
width: 100%;
padding: 0;
margin: 0;
margin-top: 10vh;
border: none;
}
.btn {
// background: $uni-linear-gradient-btn-color;
background: $uni-color;
color: #fff;
width: 80%;
padding: 20rpx 0;
text-align: center;
border-radius: 15rpx;
margin-top: 10vh;
}
}
</style>

+ 0
- 254
pages_order/search/index.vue View File

@ -1,254 +0,0 @@
<template>
<view class="page__view">
<!-- 导航栏 -->
<navbar :title="title" leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" />
<view class="top">
<!-- 搜索栏 -->
<view class="search">
<uv-search v-model="keyword" placeholder="输入关键词搜索" bgColor="#FBFBFB" @custom="search" @search="search">
<template #prefix>
<image class="search-icon" src="@/static/image/icon-search.png" mode="widthFix"></image>
</template>
</uv-search>
</view>
</view>
<view class="main">
<view class="flex card" v-for="item in list" :key="item.id">
<view class="left">
<view class="title">{{ item.title }}</view>
<view class="content">{{ item.content }}</view>
</view>
<view class="right">
<image class="img" :src="item.image" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
</template>
<script>
import mixinsList from '@/mixins/list.js'
export default {
mixins: [mixinsList],
data() {
return {
title: '搜索',
keyword: '',
queryParams: {
pageNo: 1,
pageSize: 10,
title: null,
cid: null,
},
// todo
mixinsListApi: '',
}
},
onLoad({ search, cid, title }) {
if (search) {
this.keyword = search
this.queryParams.title = search
}
if (cid) {
this.queryParams.cid = cid
}
if (title) {
this.title = title
}
this.getData()
},
methods: {
search() {
this.queryParams.pageNo = 1
this.queryParams.pageSize = 10
this.queryParams.title = this.keyword
this.getData()
},
// todo: delete
getData() {
this.list = [
{
id: '001',
title: '建筑学',
content: `
<h>建筑学</h>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
`,
image: '/static/image/temp-1.png',
},
{
id: '002',
title: '建筑学',
content: `
<h>建筑学</h>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
<p>文字说明</p>
`,
image: '/static/image/temp-2.png',
},
]
this.getDataThen(this.list)
},
getDataThen(list) {
const reg = /\<[^>]*\>/g
this.list = list.map(item => {
const content = item.content.replace(reg, '')
return { ...item, content }
})
},
},
}
</script>
<style scoped lang="scss">
.page__view {
background: $uni-bg-color-grey;
}
.top {
padding: 49rpx 0 17rpx 0;
box-sizing: border-box;
background: $uni-color;
}
.search {
margin: 0 19rpx;
width: calc(100% - 20rpx * 2);
background-color: #FFFFFF;
border-radius: 37rpx;
padding: 13rpx 0 13rpx 18rpx;
box-sizing: border-box;
display: flex;
align-items: center;
/deep/ .uv-search__action {
color: $uni-color;
padding: 10rpx 18rpx;
}
&-icon {
width: 26rpx;
height: auto;
}
}
.main {
padding: 17rpx;
box-sizing: border-box;
}
.card {
background: #ffffff;
border-radius: 20rpx;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
& + & {
margin-top: 27rpx;
}
.left {
flex: 1;
padding: 13rpx 32rpx 35rpx 20rpx;
box-sizing: border-box;
.title {
font-size: 32rpx;
font-weight: 700;
color: #000000;
}
.content {
font-size: 28rpx;
font-weight: 400;
color: #0F2248;
overflow: hidden;
text-overflow: ellipsis;
display:-webkit-box; //
-webkit-box-orient:vertical; //--
-webkit-line-clamp:7; //
}
}
.right {
padding: 23rpx 17rpx 23rpx 0;
box-sizing: border-box;
.img {
width: 225rpx;
height: 325rpx;
}
}
}
</style>

+ 660
- 0
pages_order/thesis/index.vue View File

@ -0,0 +1,660 @@
<template>
<view class="page__view">
<!-- 导航栏 -->
<navbar :title="title" leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" />
<!-- 轮播图 -->
<view class="swiper">
<uv-swiper :list="bannerList" keyName="image" :autoplay="bannerList.length" :indicator="bannerList.length" indicatorMode="dot" indicatorActiveColor="#4883F9" indicatorInactiveColor="#FFFFFF" height="424rpx"></uv-swiper>
</view>
<!-- 发表全流程辅导 -->
<view class="section">
<view class="section-header">发表全流程辅导</view>
<view class="section-content paragraph process">
<view class="paragraph">
<view class="flex difficulty">
<view>难度</view>
<uv-rate :value="process.difficulty" size="28rpx" activeColor="#4883F9" :allowHalf="true" :minCount="0.5" readonly></uv-rate>
</view>
<view>{{ process.content }}</view>
</view>
</view>
</view>
<!-- 可发表方向 -->
<view class="section">
<view class="section-header">
<view class="section-header-line"></view>
<view>可发表方向</view>
</view>
<view class="section-content direction">
<view class="table">
<view class="table-row" v-for="row in direction" :key="row.id">
<view class="table-cell">{{ row.title }}</view>
<view class="table-cell">{{ row.desc }}</view>
</view>
</view>
</view>
</view>
<!-- 师资介绍 -->
<view class="section">
<view class="section-header">
<view class="section-header-line"></view>
<view>师资介绍</view>
</view>
<view class="section-content teachers">
<view class="card" v-for="item in teachers" :key="item.id">
<view class="info">
<view class="title">
<view class="name">{{ item.name }}</view>
<view class="label">
<view class="label-text">{{ item.label }}</view>
<view class="label-line"></view>
</view>
</view>
<view class="tag">
<image class="tag-icon" src="@/static/image/icon-degree.png" mode="widthFix"></image>
<vie>{{ item.degree }}</vie>
</view>
<view class="desc">
<view>专业经历</view>
<view>{{ item.experience }}</view>
</view>
</view>
<view class="pic">
<image class="img" :src="item.image" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
<!-- 课程安排 -->
<view class="section">
<view class="section-header">
<view class="section-header-line"></view>
<view>课程安排</view>
</view>
<view class="section-content">
<view class="table">
<view class="table-row" v-for="row in course" :key="row.id">
<view class="table-cell">
<view>{{ row.title }}</view>
<view>{{ `(共${row.length}课时)` }}</view>
</view>
<view class="table-cell">{{ row.desc }}</view>
</view>
</view>
</view>
</view>
<!-- 适用人群 -->
<view class="section">
<view class="section-header">
<view class="section-header-line"></view>
<view>适用人群</view>
</view>
<view class="section-content target-audience">
<view class="paragraph">
{{ targetAudience }}
</view>
</view>
</view>
<!-- 期刊推荐 -->
<view class="section">
<view class="section-header">
<view class="section-header-line"></view>
<view>期刊推荐</view>
</view>
<view class="section-content journal">
<view class="box" v-for="item in journal" :key="item.id">
<view class="card">
<view class="top">
<view class="pic">
<image class="img" :src="item.image" mode="aspectFill"></image>
</view>
<view class="info">
<view class="name">{{ item.name }}</view>
<view class="desc">{{ item.desc }}</view>
</view>
</view>
<view class="main">
{{ item.intro }}
</view>
</view>
</view>
</view>
</view>
<!-- 附加材料 -->
<view class="section">
<view class="section-header">
<view class="section-header-line"></view>
<view>附加材料</view>
</view>
<view class="section-content attachment">
<view class="flex file" v-for="item in attachment" :key="item.id">
<view class="file-info">
<template v-if="item.type == 'pdf'">
<image class="file-icon" src="@/static/image/icon-pdf.png" mode="widthFix"></image>
</template>
<template v-else>
<image class="file-icon" src="@/static/image/icon-word.png" mode="widthFix"></image>
</template>
<view class="file-detail">
<view class="title">{{ item.name }}</view>
<view class="desc">{{ `${item.type} ${item.size}MB` }}</view>
</view>
</view>
<button class="btn" @click="downloadFile(item.url)">下载</button>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: '',
bannerList: [],
process: {},
direction: [],
teachers: [],
course: [],
targetAudience: '',
journal: [],
attachment: [],
}
},
onLoad({ id }) {
this.getData(id)
},
methods: {
async getData(thesisId) {
try {
// todo
await this.$fetch('queryThesisById', { thesisId })
} catch (err) {
}
// todo: delete
this.title = '建筑学学科论文'
this.bannerList = [
{ image: '/static/image/temp-1.png' },
{ image: '/static/image/temp-2.png' },
{ image: '/static/image/temp-3.png' },
{ image: '/static/image/temp-2.png' },
]
this.process = {
difficulty: 4,
content: `导周期本次辅导共包含15课时,每课时60分钟通常建议辅导周期为2-3个月,可根据学员进度个性化调整。发表周期6-12个月不等(包含论文撰写、修改、投稿、审稿等环节)期刊不同。周期有所差异,平均审稿期为3-6月。结果产出定制选题报告与研究框架辅导高质量学术论文初稿+多轮修改辅导完整投稿材料包(含CoverLetter、格式排版等)AHCI核心期刊正式发表
`
}
this.direction = [
{
id: '001',
title: '建筑历史方向',
desc: '聚焦不同时期建筑风格,流派演变,哲学美学(如现象学)与建筑关联,经典或当代实(如生态建筑)、标志性建筑项目实践案例。',
},
{
id: '002',
title: '建筑设计实践',
desc: '创新设计流程(含参数化计)、可持续设计(如生态建筑)、标志性建筑项目实践案例。',
},
{
id: '003',
title: '建筑技术与工程',
desc: '创新设计流程(含参数化计)、可持续设计(如生态建筑)、标志性建筑项目实践案例。',
},
]
this.teachers = [
{
id: '001',
name: 'Elizabeth',
label: '文化与技术融合研究者',
degree: '牛津大学建筑学博士',
image: '/static/image/temp-11.png',
experience: `
Building Environment等权威期刊发表多篇论文;教学特色:擅长以项目制教学打通理论到实践的闭环学生团队多次斩获亚洲建筑新人赛大奖
`
},
{
id: '002',
name: 'Elizabeth',
label: '文化与技术融合研究者',
degree: '牛津大学建筑学博士',
image: '/static/image/temp-12.png',
experience: `
Building Environment等权威期刊发表多篇论文;教学特色:擅长以项目制教学打通理论到实践的闭环学生团队多次斩获亚洲建筑新人赛大奖
`
},
]
this.course = [
{
id: '001',
title: '选题指导',
length: 4,
desc: '探讨当前建筑学热点与研究势,启发学员形成研究兴出与方向在导师引导下,完成选题定位、研究问题设定;',
},
{
id: '002',
title: '论文撰写辅导',
length: 4,
desc: '创新设计流程(含参数化计)、可持续设计(如生态建筑)、标志性建筑项目实践案例。',
},
{
id: '003',
title: '论文修改与润色提升',
length: 4,
desc: '......',
},
]
this.targetAudience = `正在攻读本科、硕土或博士阶段建筑学、城市设计、景观建筑、建筑历史与理论等相关专业的学生
·有志申请海外建筑类高校研究生项目需准备具有深度与原创性的学术写作材料的申请者;
-准备参与各类学术会议论文竟赛设计研究发表等活动的高校建筑学子;
.希望将设计实践与理论研究相结合通过论文提升学术表达与评职称的建筑从业者或高校教师;
对跨学科建筑议题(如空间社会学建筑文化研究数字建构等)有浓厚兴趣并计划在学术方向深入发展的研究者
`
this.journal = [
{
id: '001',
name: 'Journal of Architecture',
desc: '发表难度中等偏难,审稿周期较长,注重研究的创新性。',
intro: '专注于建筑理论与历史研究。该刊理论性强,特别欢迎跨学科、历史与文化视角的论文,期刊适合深度分析与批评性研究。作为AHCI核刊。JCRQ2分区。影响因子1.2。',
image: '/static/image/temp-13.png',
},
{
id: '002',
name: 'Journal of Architecture',
desc: '发表难度中等偏难,审稿周期较长,注重研究的创新性。',
intro: '专注于建筑理论与历史研究。该刊理论性强,特别欢迎跨学科、历史与文化视角的论文,期刊适合深度分析与批评性研究。作为AHCI核刊。JCRQ2分区。影响因子1.2。',
image: '/static/image/temp-14.png',
},
]
this.attachment = [
{
id: '001',
name: '学术平台手册.pdf',
type: 'pdf',
size: 6.37,
url: 'https://www.klook.cn/klvoucher/UENZOG10SE81amgzbURkNXhvRVhFeXFIaDJONnpYb0gyQUNFYURJRzlQVjlydTJUZGFGaVpCM3VmYW1wUnhKSkp0bDBUK2IvekU4Vk14RmhacTJ2d0VqVEVCUHlMZ0JFelNycGxGdTl4VTA9.pdf?from_source=email&from_medium=system_email&from_campaign=TTD_pretrip2_booking_confirmation_base',
},
{
id: '002',
name: '学术平台手册.doc',
type: 'word',
size: 6.37,
url: 'https://qcloud.dpfile.com/pc/myug_luLpDQj6VgAsrUXgol_FrfrTcsVfpzy8-1PMV3uCvjEkdZxjKI_hzpUwDOs.jpg',
},
]
},
downloadFile(url) {
console.log('downloadFile', url)
uni.downloadFile({
url, //
success: (downloadRes) => {
console.log('downloadRes', downloadRes)
if (downloadRes.statusCode === 200) {
uni.openDocument({
showMenu: true,
filePath: downloadRes.tempFilePath,
success: () => console.log('打开成功')
});
} else {
uni.showToast({ title: '下载失败', icon: 'none' });
}
},
fail: (err) => {
uni.showToast({ title: '网络异常', icon: 'none' });
}
});
},
},
}
</script>
<style scoped lang="scss">
.page__view {
padding-bottom: 62rpx;
background: #FFFFFF;
}
.swiper {
margin: 20rpx 18rpx 32rpx 18rpx;
/deep/ .uv-swiper-indicator__wrapper__dot {
width: 15rpx;
height: 15rpx;
}
/deep/ .uv-swiper-indicator__wrapper__dot--active {
width: 15rpx;
}
}
.section {
width: 100%;
padding: 0 18rpx;
box-sizing: border-box;
& + & {
margin-top: 40rpx;
}
&-header {
display: flex;
align-items: center;
justify-content: flex-start;
column-gap: 15rpx;
padding-left: 18rpx;
font-size: 32rpx;
font-weight: 700;
color: #000000;
&-line {
width: 11rpx;
height: 45rpx;
border-radius: 6rpx;
background-image: linear-gradient(#FFFFFF, #4883F9);
}
}
&-content {
margin-top: 37rpx;
.paragraph {
width: 100%;
padding: 22rpx;
box-sizing: border-box;
white-space: pre-line;
font-size: 28rpx;
color: #000000;
background: #F8F8F8;
border-radius: 15rpx;
}
.table {
width: 100%;
border-radius: 15rpx;
overflow: hidden;
&-row {
display: grid;
grid-template-columns: 218rpx auto;
background: #EEEEEE;
&:nth-child(2n) {
background: #DEDEDE;
}
}
&-cell {
display: inline-flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
padding: 17rpx;
box-sizing: border-box;
font-family: PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #080808;
&:first-child {
border-right: 1rpx solid #E5E5E5;
}
}
}
&.process {
margin-top: 24rpx;
.difficulty {
justify-content: flex-start;
}
}
&.teachers {
.card {
display: flex;
align-items: center;
column-gap: 12rpx;
background: #ffffff;
border-radius: 15rpx;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
.info {
flex: 1;
padding: 19rpx 0 28rpx 17rpx;
.title {
display: flex;
align-items: center;
padding-left: 11rpx;
color: #000000;
.name {
font-size: 32rpx;
font-weight: 700;
}
.label {
margin-left: 12rpx;
position: relative;
height: 30rpx;
&-line {
margin: 24rpx 0 0 25rpx;
width: 195rpx;
height: 4rpx;
background-image: linear-gradient(#4883F9, #FFFFFF);
border-radius: 2rpx;
}
&-text {
position: absolute;
top: 0;
left: 0;
font-size: 22rpx;
font-weight: 400;
}
}
}
.tag {
margin: 5rpx 0 18rpx 0;
display: inline-flex;
align-items: center;
padding: 5rpx 43rpx 5rpx 16rpx;
column-gap: 16rpx;
font-size: 28rpx;
color: #FFFFFF;
background: rgba(72,131,249,0.58);
border-radius: 30rpx 0rpx 30rpx 0rpx;
&-icon {
width: 38rpx;
height: auto;
}
}
.desc {
padding: 12rpx 15rpx;
font-size: 28rpx;
font-weight: 500;
color: #000000;
background: #f8f8f8;
border-radius: 16rpx;
}
}
.pic {
padding: 48rpx 9rpx 48rpx 0;
width: 253rpx;
height: 345rpx;
border-radius: 127rpx;
overflow: hidden;
.img {
width: 100%;
height: 100%;
}
}
&:nth-child(2n) {
flex-direction: row-reverse;
.info {
padding: 19rpx 17rpx 28rpx 0;
}
.pic {
padding: 48rpx 0 48rpx 9rpx;
}
}
}
.card + .card {
margin-top: 24rpx;
}
}
&.journal {
.box {
padding-top: 73rpx;
.card {
padding: 29rpx 12rpx 19rpx 12rpx;
background: #f6f6f6;
border-radius: 15rpx;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
.top {
position: relative;
.pic {
position: absolute;
left: 42rpx;
bottom: 0;
width: 213rpx;
height: 285rpx;
.img {
width: 100%;
height: 100%;
}
}
.info {
height: 181rpx;
padding: 0 14rpx 0 266rpx;
}
}
.main {
margin-top: 18rpx;
padding: 14rpx;
font-size: 28rpx;
color: #000000;
background: #ebebeb;
border-radius: 30rpx 0rpx 30rpx 0rpx;
}
}
&:nth-child(2n) {
.card {
.top {
.info {
padding: 0 258rpx 0 14rpx;
}
.pic {
left: unset;
right: 29rpx;
}
}
}
}
}
.box + .box {
margin-top: 28rpx;
}
}
&.attachment {
.file {
justify-content: space-between;
padding: 32rpx 15rpx 32rpx 26rpx;
background: #f8f8f8;
border-radius: 15rpx;
&-info {
display: flex;
align-items: flex-end;
}
&-icon {
width: 64rpx;
height: auto;
}
&-detail {
margin-left: 14rpx;
.title {
font-size: 30rpx;
color: #000000;
}
.desc {
font-size: 28rpx;
color: #999999;
}
}
.btn {
padding: 7rpx 30rpx;
font-size: 28rpx;
color: #FFFFFF;
background: #4883f9;
border-radius: 27rpx;
}
}
.file + .file {
margin-top: 21rpx;
}
}
}
}
</style>

+ 191
- 0
pages_order/thesis/search.vue View File

@ -0,0 +1,191 @@
<template>
<view class="page__view">
<!-- 导航栏 -->
<navbar :title="title" leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" />
<view class="top">
<!-- 搜索栏 -->
<view class="search">
<uv-search v-model="keyword" placeholder="输入关键词搜索" bgColor="#FBFBFB" @custom="search" @search="search">
<template #prefix>
<image class="search-icon" src="@/static/image/icon-search.png" mode="widthFix"></image>
</template>
</uv-search>
</view>
</view>
<view class="main">
<template v-if="total">
<view class="flex card" v-for="item in list" :key="item.id" @click="jumpToDetail(item.thesisId)">
<view class="left">
<view class="title">{{ item.title }}</view>
<view class="content">{{ item.description }}</view>
</view>
<view class="right">
<image class="img" :src="item.image" mode="aspectFill"></image>
</view>
</view>
</template>
<template v-else>
<view class="flex empty">
<image class="empty-icon" src="@/static/image/icon-empty.png" mode="widthFix"></image>
</view>
</template>
</view>
</view>
</template>
<script>
import mixinsList from '@/mixins/list.js'
export default {
mixins: [mixinsList],
data() {
return {
title: '搜索',
keyword: '',
queryParams: {
pageNo: 1,
pageSize: 10,
title: null,
cid: null,
},
mixinsListApi: 'queryThesisList',
}
},
onLoad({ search, categoryOne, categoryTwo, title }) {
if (search) {
this.keyword = search
this.queryParams.title = search
}
if (categoryTwo) {
this.queryParams.categoryOne = categoryOne
this.queryParams.categoryTwo = categoryTwo
}
if (title) {
this.title = title
}
this.getData()
},
methods: {
search() {
this.queryParams.pageNo = 1
this.queryParams.pageSize = 10
this.queryParams.title = this.keyword
this.getData()
},
getDataThen(list) {
// todo: check
const reg = /\<[^>]*\>/g
this.list = list.map(item => {
const description = item.description.replace(reg, '')
return { ...item, description }
})
},
jumpToDetail(thesisId) {
uni.navigateTo({
url: `/pages_order/thesis/index?thesisId=${thesisId}`
})
},
},
}
</script>
<style scoped lang="scss">
.page__view {
background: $uni-bg-color-grey;
}
.top {
padding: 49rpx 0 17rpx 0;
box-sizing: border-box;
background: $uni-color;
}
.search {
margin: 0 19rpx;
width: calc(100% - 20rpx * 2);
background-color: #FFFFFF;
border-radius: 37rpx;
padding: 13rpx 0 13rpx 18rpx;
box-sizing: border-box;
display: flex;
align-items: center;
/deep/ .uv-search__action {
color: $uni-color;
padding: 10rpx 18rpx;
}
&-icon {
width: 26rpx;
height: auto;
}
}
.main {
padding: 17rpx;
box-sizing: border-box;
}
.card {
background: #ffffff;
border-radius: 20rpx;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
& + & {
margin-top: 27rpx;
}
.left {
flex: 1;
padding: 13rpx 32rpx 35rpx 20rpx;
box-sizing: border-box;
.title {
font-size: 32rpx;
font-weight: 700;
color: #000000;
}
.content {
font-size: 28rpx;
font-weight: 400;
color: #0F2248;
overflow: hidden;
text-overflow: ellipsis;
display:-webkit-box; //
-webkit-box-orient:vertical; //--
-webkit-line-clamp:7; //
}
}
.right {
padding: 23rpx 17rpx 23rpx 0;
box-sizing: border-box;
.img {
width: 225rpx;
height: 325rpx;
}
}
}
.empty {
margin-top: 165rpx;
width: 100%;
&-icon {
width: 464rpx;
height: auto;
}
}
</style>

BIN
static/image/icon-degree.png View File

Before After
Width: 57  |  Height: 41  |  Size: 1.7 KiB

BIN
static/image/icon-empty.png View File

Before After
Width: 696  |  Height: 726  |  Size: 78 KiB

BIN
static/image/icon-pdf.png View File

Before After
Width: 97  |  Height: 129  |  Size: 2.7 KiB

BIN
static/image/icon-word.png View File

Before After
Width: 97  |  Height: 129  |  Size: 3.9 KiB

BIN
static/image/temp-11.png View File

Before After
Width: 380  |  Height: 518  |  Size: 222 KiB

BIN
static/image/temp-12.png View File

Before After
Width: 380  |  Height: 518  |  Size: 223 KiB

BIN
static/image/temp-13.png View File

Before After
Width: 320  |  Height: 428  |  Size: 160 KiB

BIN
static/image/temp-14.png View File

Before After
Width: 327  |  Height: 437  |  Size: 204 KiB

+ 1
- 60
store/store.js View File

@ -26,7 +26,7 @@ const store = new Vuex.Store({
...state.configList,
}
if (res.code == 200) {
res.result.forEach(n => {
res.result?.records?.forEach(n => {
configList[n.keyName] = n.keyContent;
configList[n.keyName + '_keyValue'] = n.keyValue;
});
@ -44,65 +44,6 @@ const store = new Vuex.Store({
// })
// })
},
// 微信登录
login(state){
uni.showLoading({
title: '登录中...'
})
uni.login({
success(res) {
if(res.errMsg != "login:ok"){
return
}
api('wxLogin', {
code : res.code
}, res => {
uni.hideLoading()
if(res.code != 200){
return
}
state.userInfo = res.result.userInfo
uni.setStorageSync('token', res.result.token)
if(!state.userInfo.nickName || !state.userInfo.headImage){
uni.navigateTo({
url: '/pages_order/auth/wxUserInfo'
})
}else{
uni.navigateBack(-1)
}
})
}
})
},
// 获取用户个人信息
getUserInfo(state){
api('getInfo', res => {
if(res.code == 200){
state.userInfo = res.result
}
})
},
// 退出登录
logout(state){
uni.showModal({
title: '确认退出登录吗',
success(r) {
if(r.confirm){
state.userInfo = {}
state.role = false
uni.removeStorageSync('token')
uni.reLaunch({
url: '/pages/index/index'
})
}
}
})
},
},
actions: {},
})


+ 0
- 18
utils/utils.js View File

@ -209,23 +209,6 @@ export function redirectTo(...args){
uni.redirectTo(params(...args))
}
/**
* 登录跳转函数防止短时间内多次调用
* @returns {Function} 节流处理后的登录跳转函数
*/
export const toLogin = function(){
let time = 0
return () => {
if(new Date().getTime() - time < 1000){
return
}
time = new Date().getTime()
uni.navigateTo({
url: '/pages_order/auth/wxLogin'
})
}
}()
export default {
toArray,
generateUUID,
@ -240,5 +223,4 @@ export default {
redirectTo,
copyText,
stringFormatHtml,
toLogin
}

Loading…
Cancel
Save