#5 feat: 样式调整;

Merged
Fox merged 1 commits from fox into master 2 months ago
  1. +21
    -0
      api/model/index.js
  2. +6
    -2
      pages.json
  3. +55
    -6
      pages/index/case.vue
  4. +13
    -8
      pages/index/center.vue
  5. +125
    -53
      pages/index/index.vue
  6. +15
    -10
      pages/index/serve.vue
  7. +39
    -31
      pages_order/case/index.vue
  8. +206
    -0
      pages_order/case/poster.vue
  9. +4
    -18
      pages_order/serve/index.vue
  10. +191
    -83
      pages_order/thesis/index.vue
  11. +450
    -0
      pages_order/thesis/indexTwo.vue
  12. +10
    -70
      pages_order/thesis/poster.vue
  13. +79
    -9
      pages_order/thesis/search.vue

+ 21
- 0
api/model/index.js View File

@ -29,6 +29,27 @@ const api = {
url: '/index/queryThesisById',
method: 'GET',
},
/**
* 获取论文分类列表二
*/
queryCategoryThesisTwoList: {
url: '/config/queryCategoryThesisTwoList',
method: 'GET',
},
/**
* 获取论文文章列表二
*/
queryThesisTwoList: {
url: '/index/queryThesisTwoList',
method: 'GET',
},
/**
* 获取论文文章详情二
*/
queryThesisTwoById: {
url: '/index/queryThesisTwoById',
method: 'GET',
},
/**
* 生成二维码
*/


+ 6
- 2
pages.json View File

@ -36,12 +36,16 @@
"path": "thesis/search"
}, {
"path": "thesis/index"
}, {
"path": "thesis/indexTwo"
}, {
"path": "thesis/poster"
}, {
"path": "case/index"
}, {
"path": "serve/index"
"path": "case/poster"
}, {
"path": "poster/index"
"path": "serve/index"
}
]
}],


+ 55
- 6
pages/index/case.vue View File

@ -4,6 +4,16 @@
<view class="main">
<view class="header">
<view class="title">
{{ configList.config_name }}
</view>
<view class="desc">
<view class="desc-line"></view>
{{ configList.config_name_en }}
</view>
</view>
<!-- 搜索栏 -->
<view class="search">
<uv-search v-model="keyword" placeholder="输入关键词搜索" bgColor="#FBFBFB" @custom="search" @search="search">
@ -15,7 +25,7 @@
<!-- 轮播图 -->
<view class="swiper">
<uv-swiper :list="bannerList" keyName="image" indicator indicatorMode="dot" indicatorActiveColor="#4883F9" indicatorInactiveColor="#FFFFFF" height="239rpx"></uv-swiper>
<uv-swiper :list="bannerList" keyName="image" indicator indicatorMode="dot" indicatorActiveColor="#4883F9" indicatorInactiveColor="#FFFFFF" :height="swiperHeight"></uv-swiper>
</view>
<view class="flex filter">
@ -77,9 +87,14 @@
categoryPeriodId: '',
},
mixinsListApi: 'queryAriticleList',
swiperHeight: '239rpx',
}
},
onLoad() {
const windowWidth = uni.getSystemInfoSync().windowWidth
this.swiperHeight = `${(windowWidth - 18) * 239 / 714}px`
this.fetchBanner()
this.fetchOptions()
this.getData()
@ -133,7 +148,8 @@
<style scoped lang="scss">
.bg {
width: 100%;
height: 438rpx;
// height: 438rpx;
height: 488rpx;
background-image: linear-gradient(#4883F9, #4883F9, #4883F9, #FCFDFF);
}
@ -142,7 +158,36 @@
top: 0;
left: 0;
width: 100%;
padding: 192rpx 0 182rpx 0;
// padding: 192rpx 0 182rpx 0;
padding: 100rpx 0 182rpx 0;
}
.header {
margin-left: 44rpx;
.title {
position: relative;
letter-spacing: 6rpx;
font-size: 46rpx;
font-weight: 700;
color: #FFFFFF;
}
.desc {
position: relative;
font-size: 30rpx;
// font-weight: 700;
color: #FFFFFF;
margin: 4rpx 0 22rpx 0;
display: inline-block;
&-line {
margin-bottom: 6rpx;
width: 100%;
height: 11rpx;
background: linear-gradient(to right, #ffffff, #4883f9);
}
}
}
.search {
@ -193,11 +238,15 @@
}
.list {
padding: 34rpx 37rpx;
padding: 34rpx 0;
&-item {
width: 100%;
height: 284rpx;
$width: calc(100vw - 37rpx * 2);
margin: 0 37rpx;
width: $width;
// height: 284rpx;
height: calc(#{$width} * 284 / 677);
border-radius: 15rpx;
overflow: hidden;


+ 13
- 8
pages/index/center.vue View File

@ -19,11 +19,11 @@
<view class="list">
<view class="list-item" @click="jumpToDetail('other_service')">
<image class="list-item-bg" src="@/static/image/bg-other-serve.png" mode="widthFix"></image>
<view class="list-item-fg">
<image class="list-item-bg" :src="configList.config_image_service" mode="scaleToFill"></image>
<!-- <view class="list-item-fg">
<view class="title">其他服务</view>
<view class="desc">Other services</view>
</view>
</view> -->
</view>
</view>
@ -115,7 +115,7 @@
}
.swiper {
margin: 0 18rpx;
margin: 0 18rpx 15rpx 18rpx;
border-radius: 25rpx;
overflow: hidden;
@ -130,18 +130,23 @@
}
.list {
padding: 0 12rpx;
margin: 0 18rpx;
&-item {
position: relative;
font-size: 0;
border-radius: 25rpx;
overflow: hidden;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
& + & {
margin-top: 19rpx;
}
&-bg {
width: 100%;
height: auto;
$w: calc(100vw - 18rpx*2);
width: $w;
height: calc(#{$w} * 179 / 714);
}
&-fg {


+ 125
- 53
pages/index/index.vue View File

@ -4,6 +4,16 @@
<view class="main">
<view class="header">
<view class="title">
{{ configList.config_name }}
</view>
<view class="desc">
<view class="desc-line"></view>
{{ configList.config_name_en }}
</view>
</view>
<!-- 搜索栏 -->
<view class="section search">
<uv-search v-model="keyword" placeholder="输入关键词搜索" bgColor="#FBFBFB" @custom="search" @search="search">
@ -15,33 +25,40 @@
<!-- 轮播图 -->
<view class="section swiper">
<uv-swiper :list="bannerList" keyName="image" indicator indicatorMode="dot" indicatorActiveColor="#4883F9" indicatorInactiveColor="#FFFFFF" height="239rpx"></uv-swiper>
<uv-swiper :list="bannerList" keyName="image" indicator indicatorMode="dot" indicatorActiveColor="#4883F9" indicatorInactiveColor="#FFFFFF" :height="swiperHeight"></uv-swiper>
</view>
<view class="section card" v-for="(group, gIdx) in list" :key="group.id">
<view class="section card" v-for="group in list" :key="group.id">
<view class="card-header">
<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">
<view class="flex info">
<image class="info-icon" :src="item.image" mode="widthFix"></image>
<view class="info-label">{{ item.title }}</view>
</view>
<button class="btn" @click="jumpToCategory(group.id, item.id, item.title)">查看</button>
<view class="card-item card-row" v-for="item in group.children" :key="item.id">
<view class="flex info">
<image class="info-icon" :src="item.image" mode="widthFix"></image>
<view class="info-label">{{ item.title }}</view>
</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(group.id, item.id, item.title)">
<image class="info-icon" :src="item.image" mode="widthFix"></image>
<view class="info-label">{{ item.title }}</view>
</view>
<button class="btn" @click="jumpToCategory(group.id, item.id, item.title, 'queryThesisList')">查看</button>
</view>
</view>
</view>
<view class="section card" v-for="group in list2" :key="group.id">
<view class="card-header">
<view class="card-header-title">{{ group.title }}</view>
<view class="card-header-tag">JGYT</view>
</view>
<view class="card-content">
<view class="card-box">
<view class="card-item info" v-for="item in group.children" :key="item.id" @click="jumpToCategory(group.id, item.id, item.title, 'queryThesisTwoList')">
<image class="info-icon" :src="item.image" mode="widthFix"></image>
<view class="info-label">{{ item.title }}</view>
</view>
</template>
</view>
</view>
</view>
@ -64,53 +81,78 @@
keyword: '',
bannerList: [],
list: [],
list2: [],
swiperHeight: '239rpx',
}
},
onLoad() {
const windowWidth = uni.getSystemInfoSync().windowWidth
this.swiperHeight = `${(windowWidth - 18) * 239 / 714}px`
this.fetchBanner()
this.getData()
},
methods: {
async getData() {
try {
let records = (await this.$fetch('queryCategoryThesisList', { pageNo: 1, pageSize: 1000 }))?.records
let groups = []
records.forEach(record => {
if (record.hasChild == 1) {
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
}
transformData(records) {
let groups = []
records.forEach(record => {
if (record.hasChild == 1) {
const { id, title, createTime } = record
const index = groups.findIndex(group => group.id === id)
if (index === -1) {
groups.push({ id, title, createTime, children: [] })
} else {
const { pid, id, title, image, createTime } = record
const index = groups.findIndex(group => group.id === pid)
const item = { id, title, image, createTime }
if (index === -1) {
groups.push({ id: pid, children: [item] })
} else {
groups[index].children.push(item)
}
groups[index].title = title
groups[index].createTime = createTime
}
})
} else {
const { pid, id, title, image, createTime } = record
const index = groups.findIndex(group => group.id === pid)
const item = { id, title, image, 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.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())
groups.sort((a, b) => new Date(a.createTime).getTime() - new Date(b.createTime).getTime())
return groups
},
async fetchCategoryThesisList() {
try {
let records = (await this.$fetch('queryCategoryThesisList', { pageNo: 1, pageSize: 1000 }))?.records
this.list = this.transformData(records)
} catch (err) {
this.list = groups
}
},
async fetchCategoryThesisTwoList() {
try {
let records = (await this.$fetch('queryCategoryThesisTwoList', { pageNo: 1, pageSize: 1000 }))?.records
this.list2 = this.transformData(records)
} catch (err) {
}
},
getData() {
this.fetchCategoryThesisList()
this.fetchCategoryThesisTwoList()
},
search() {
uni.navigateTo({
@ -126,9 +168,9 @@
}
},
jumpToCategory(categoryOne, categoryTwo, title) {
jumpToCategory(categoryOne, categoryTwo, title, api) {
uni.navigateTo({
url: `/pages_order/thesis/search?categoryOne=${categoryOne}&categoryTwo=${categoryTwo}&title=${title}`
url: `/pages_order/thesis/search?categoryOne=${categoryOne}&categoryTwo=${categoryTwo}&title=${title}&api=${api}`
})
},
},
@ -138,7 +180,8 @@
<style scoped lang="scss">
.bg {
width: 100%;
height: 438rpx;
// height: 438rpx;
height: 488rpx;
background-image: linear-gradient(#4883F9, #4883F9, #4883F9, #FCFDFF);
}
@ -147,7 +190,36 @@
top: 0;
left: 0;
width: 100%;
padding: 192rpx 0 182rpx 0;
// padding: 192rpx 0 182rpx 0;
padding: 100rpx 0 182rpx 0;
}
.header {
margin-left: 44rpx;
.title {
position: relative;
letter-spacing: 6rpx;
font-size: 46rpx;
font-weight: 700;
color: #FFFFFF;
}
.desc {
position: relative;
font-size: 30rpx;
// font-weight: 700;
color: #FFFFFF;
margin: 4rpx 0 22rpx 0;
display: inline-block;
&-line {
margin-bottom: 6rpx;
width: 100%;
height: 11rpx;
background: linear-gradient(to right, #ffffff, #4883f9);
}
}
}
.section {


+ 15
- 10
pages/index/serve.vue View File

@ -19,18 +19,18 @@
<view class="list">
<view class="list-item" @click="jumpToDetail('academic_advising')">
<image class="list-item-bg" src="@/static/image/bg-academic-advising.png" mode="widthFix"></image>
<view class="list-item-fg">
<image class="list-item-bg" :src="configList.config_image_advising" mode="scaleToFill"></image>
<!-- <view class="list-item-fg">
<view class="title">学术辅导</view>
<view class="desc">Academic Advising</view>
</view>
</view> -->
</view>
<view class="list-item" @click="jumpToDetail('thesis_submission')">
<image class="list-item-bg" src="@/static/image/bg-paper-submission.png" mode="widthFix"></image>
<view class="list-item-fg">
<image class="list-item-bg" :src="configList.config_image_submission" mode="scaleToFill"></image>
<!-- <view class="list-item-fg">
<view class="title">论文投递</view>
<view class="desc">Paper submission</view>
</view>
</view> -->
</view>
</view>
@ -137,18 +137,23 @@
}
.list {
padding: 0 12rpx;
margin: 0 18rpx;
&-item {
position: relative;
font-size: 0;
border-radius: 25rpx;
overflow: hidden;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
& + & {
margin-top: 19rpx;
margin-top: 32rpx;
}
&-bg {
width: 100%;
height: auto;
$w: calc(100vw - 18rpx*2);
width: $w;
height: calc(#{$w} * 179 / 714);
}
&-fg {


+ 39
- 31
pages_order/case/index.vue View File

@ -1,19 +1,18 @@
<template>
<view class="page__view">
<view :class="['page__view', hasPoster ? 'with-bottom' : '']">
<!-- 导航栏 -->
<navbar :title="details.title" leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" />
<!-- 轮播图 -->
<view class="swiper">
<uv-swiper :list="bannerList" keyName="image" :autoplay="bannerList.length > 1" :indicator="bannerList.length > 1" indicatorMode="dot" indicatorActiveColor="#4883F9" indicatorInactiveColor="#FFFFFF" height="424rpx"></uv-swiper>
<view class="cover-image" :style="{ height: coverImageHeight }">
<image class="img" :src="details.paperImage" mode="aspectFill" ></image>
</view>
<!-- 学生情况 -->
<view class="section">
<view class="section" v-if="details.studentCondition">
<view class="section-header">
<arrow></arrow>
<view>学生情况</view>
<view>{{ details.titleOne }}</view>
</view>
<view class="section-content">
<uv-parse :content="details.studentCondition"></uv-parse>
@ -21,10 +20,10 @@
</view>
<!-- 服务项目 -->
<view class="section">
<view class="section" v-if="details.serviceItem">
<view class="section-header">
<arrow></arrow>
<view>服务项目</view>
<view>{{ details.titleTwo }}</view>
</view>
<view class="section-content">
<uv-parse :content="details.serviceItem"></uv-parse>
@ -32,10 +31,10 @@
</view>
<!-- 服务过程 -->
<view class="section">
<view class="section" v-if="details.serviceProcess">
<view class="section-header">
<arrow></arrow>
<view>服务过程</view>
<view>{{ details.titleThree }}</view>
</view>
<view class="section-content">
<uv-parse :content="details.serviceProcess"></uv-parse>
@ -43,10 +42,10 @@
</view>
<!-- 服务结果 -->
<view class="section">
<view class="section" v-if="details.serviceResult">
<view class="section-header">
<arrow></arrow>
<view>服务结果</view>
<view>{{ details.titleFour }}</view>
</view>
<view class="section-content">
<uv-parse :content="details.serviceResult"></uv-parse>
@ -54,17 +53,17 @@
</view>
<!-- 服务感受 -->
<view class="section">
<view class="section" v-if="details.serviceFeeling">
<view class="section-header">
<arrow></arrow>
<view>服务感受</view>
<view>{{ details.titleFive }}</view>
</view>
<view class="section-content">
<uv-parse :content="details.serviceFeeling"></uv-parse>
</view>
</view>
<view class="flex bottom">
<view class="flex bottom" v-if="hasPoster">
<view class="flex btns">
<button class="btn" @click="jumpToPoster">保存海报</button>
<button class="btn btn-share" open-type="share">分享文章</button>
@ -84,9 +83,14 @@
data() {
return {
details: {},
coverImageHeight: '568rpx',
}
},
onLoad({ articleId }) {
const windowWidth = uni.getSystemInfoSync().windowWidth
this.coverImageHeight = `${(windowWidth - 18) * 568 / 677}px`
this.getData(articleId)
},
onShareAppMessage(res) {
@ -97,19 +101,20 @@
}
},
computed: {
bannerList() {
const { image } = this.details || {}
return (image || '').split(',').map(url => ({ image: url }))
},
posterData() {
const { id, title, paperDesc, paperImage } = this.details || {}
const { id, title, image, paperDesc, paperImage } = this.details || {}
return {
paperDesc: paperDesc || title,
paperImage: paperImage || this.bannerList?.[0]?.image || '',
paperImage: paperImage || image || '',
path: `pages_order/case/index?articleId=${id}`
}
},
hasPoster() {
const { paperImage } = this.details || {}
return !!paperImage
},
},
methods: {
async getData(articleId) {
@ -125,7 +130,7 @@
uni.setStorageSync('posterData', this.posterData)
uni.navigateTo({
url: `/pages_order/poster/index`
url: `/pages_order/case/poster`
})
},
},
@ -137,21 +142,24 @@
.page__view {
box-sizing: border-box;
background: #FFFFFF;
padding-bottom: calc(36rpx + 110rpx + env(safe-area-inset-bottom));
padding-bottom: 36rpx;
&.with-bottom {
padding-bottom: calc(36rpx + 110rpx + env(safe-area-inset-bottom));
}
}
.swiper {
.cover-image {
position: relative;
width: calc(100% - 18rpx*2);
background: #FFFFFF;
margin: 20rpx 18rpx 47rpx 18rpx;
border-radius: 25rpx;
overflow: hidden;
/deep/ .uv-swiper-indicator__wrapper__dot {
width: 15rpx;
height: 15rpx;
}
/deep/ .uv-swiper-indicator__wrapper__dot--active {
width: 15rpx;
.img {
width: 100%;
height: 100%;
}
}


+ 206
- 0
pages_order/case/poster.vue View File

@ -0,0 +1,206 @@
<template>
<view class="page__view">
<!-- 导航栏 -->
<navbar leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" />
<view style="width: 750rpx; height: 1184rpx; overflow: hidden;">
<canvas id="myCanvas" canvas-id="firstCanvas1" type="2d" style="width: 100%; height: 100%;"></canvas>
</view>
<view class="flex bottom">
<view class="flex">
<button class="btn" @click="saveImg">保存到手机</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
wxCodeImage: '',
baseUrl: 'https://image.hhlm1688.com/',
canvas: {},
posterData: {},
}
},
async onLoad() {
uni.showLoading({
title: '加载中...'
});
this.posterData = uni.getStorageSync('posterData')
await this.fetchQrCode(this.posterData.path)
uni.hideLoading();
console.log('this.configList.config_paper', this.configList.config_paper)
this.draw()
},
methods: {
async fetchQrCode(path) {
try {
this.wxCodeImage = (await this.$fetch('getInviteCode', { path }))?.url
} catch (err) {
}
},
draw() {
uni.showLoading({
title: "拼命绘画中..."
})
wx.createSelectorQuery()
.select('#myCanvas') // canvasid
.fields({
node: true,
size: true
})
.exec(async (res) => {
const canvas = res[0].node
//
const ctx = canvas.getContext('2d')
// Canvas
const width = res[0].width
const height = res[0].height
//
const dpr = wx.getWindowInfo().pixelRatio
//dpr
// dpr 2 4
// 3 6
console.log("--dpr", dpr)
canvas.width = width * dpr
canvas.height = height * dpr
let Ratio = canvas.width / 750
this.canvas = canvas
ctx.scale(dpr, dpr)
ctx.clearRect(0, 0, width, height)
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = '#999999';
const fontSize = 28 * Ratio / dpr
ctx.font = `${fontSize}px PingFangSC-regular`;
//
const paperImage = canvas.createImage()
paperImage.src = this.posterData.paperImage
paperImage.onload = () => {
console.log('paperImage onload')
const w = 750 * Ratio / dpr
const h = 890 * Ratio / dpr
ctx.drawImage(paperImage, 0, 0, w, h)
//
const configImage = canvas.createImage()
configImage.src = this.configList.config_paper
configImage.onload = () => {
console.log('configImage onload')
const y = 890 * Ratio / dpr
const w = 750 * Ratio / dpr
const h = 294 * Ratio / dpr
ctx.drawImage(configImage, 0, y, w, h)
//
const coderImage = canvas.createImage()
coderImage.src = this.wxCodeImage
coderImage.onload = () => {
console.log('coderImage onload')
// const x = 539 * Ratio / dpr
const x = 560 * Ratio / dpr
const y = 987 * Ratio / dpr
const size = 162 * Ratio / dpr
ctx.drawImage(coderImage, x, y, size, size)
uni.hideLoading()
}
}
}
})
},
saveImg() {
this.$authorize('scope.writePhotosAlbum').then((res) => {
this.imgApi()
})
},
imgApi() {
uni.showLoading({
title: '保存中...'
});
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: this.canvas.width,
height: this.canvas.height,
canvas: this.canvas,
success: (res) => {
let tempFilePath = res.tempFilePath;
this.saveImgToPhone(tempFilePath)
},
fail: (err) => {
console.log('--canvasToTempFilePath--fail', err)
uni.hideLoading();
}
}, this);
},
saveImgToPhone(image) {
/* 获取图片的信息 */
uni.getImageInfo({
src: image,
success: function(image) {
/* 保存图片到手机相册 */
uni.saveImageToPhotosAlbum({
filePath: image.path,
success: function() {
uni.showModal({
title: '保存成功',
content: '图片已成功保存到相册',
showCancel: false
});
},
complete(res) {
console.log(res);
uni.hideLoading();
}
});
}
});
}
},
}
</script>
<style scoped lang="scss">
.page__view {
background: $uni-bg-color-grey;
}
.bottom {
position: fixed;
left: 0;
bottom: 0;
width: 100vw;
height: 154rpx;
padding-bottom: env(safe-area-inset-bottom);
background: #FFFFFF;
.btn {
padding: 20rpx 77rpx;
font-size: 28rpx;
color: #FFFFFF;
background: #4883F9;
border-radius: 14rpx;
}
}
</style>

+ 4
- 18
pages_order/serve/index.vue View File

@ -4,10 +4,7 @@
<!-- 导航栏 -->
<navbar :title="details.paramDesc" leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" />
<view class="main">
<view class="title">{{ details.title }}</view>
<uv-parse :content="details.details"></uv-parse>
</view>
<image class="img" :src="details.details" mode="widthFix"></image>
</view>
</template>
@ -36,20 +33,9 @@
<style scoped lang="scss">
.page__view {
background: #FFFFFF;
}
.main {
padding: 44rpx 40rpx;
font-size: 30rpx;
color: #000000;
.title {
margin-bottom: 50rpx;
font-size: 36rpx;
font-weight: 700;
}
.img {
width: 100vw;
height: auto;
}
</style>

+ 191
- 83
pages_order/thesis/index.vue View File

@ -1,77 +1,84 @@
<template>
<view class="page__view">
<view :class="['page__view', hasPoster ? 'with-bottom' : '']">
<!-- 导航栏 -->
<navbar :title="details.title" leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" />
<!-- 轮播图 -->
<view class="swiper">
<uv-swiper :list="bannerList" keyName="image" :autoplay="bannerList.length > 1" :indicator="bannerList.length > 1" indicatorMode="dot" indicatorActiveColor="#4883F9" indicatorInactiveColor="#FFFFFF" height="424rpx"></uv-swiper>
<view class="cover-image" :style="{ height: coverImageHeight }">
<image class="img" :src="details.image" mode="aspectFill" ></image>
<view class="shadow"></view>
</view>
<view class="page-title">
<view v-if="details.process || (details.educationProcessList && details.educationProcessList.length)">{{ details.processTitle || '发表全流程辅导' }}</view>
<view v-else>{{ details.title }}</view>
<view class="page-title-line"></view>
</view>
<!-- 发表全流程辅导 -->
<view class="section">
<view class="section-header">发表全流程辅导</view>
<view class="section-content paragraph process">
<view class="paragraph">
<uv-parse :content="details.process"></uv-parse>
</view>
<view class="process" v-if="details.process || (details.educationProcessList && details.educationProcessList.length)">
<view class="process-custom" v-if="details.process">
<uv-parse :content="details.process"></uv-parse>
</view>
<view class="process-item" v-for="item in details.educationProcessList" :key="item.id">
<view class="process-item-title">{{ item.title }}</view>
<view class="process-item-content">{{ item.content }}</view>
</view>
</view>
<!-- 可发表方向 -->
<view class="section">
<view class="section" v-if="details.educationTargetList && details.educationTargetList.length">
<view class="section-header">
<view class="section-header-line"></view>
<view>可发表方向</view>
<view>{{ details.targetTitle || '可发表方向' }}</view>
</view>
<view class="section-content direction">
<view class="table">
<view class="table-row" v-for="row in details.educationTargetList" :key="row.id">
<view class="table-cell">{{ row.title }}</view>
<view class="table-cell">{{ row.description }}</view>
<uv-read-more show-height="300rpx" :toggle="true" textIndent="0" closeText="展开" :shadowStyle="{ backgroundImage: 'linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)', paddingTop: '100rpx', marginTop: '-100rpx' }">
<view class="table">
<view class="table-row" v-for="row in details.educationTargetList" :key="row.id">
<view class="table-cell">{{ row.title }}</view>
<view class="table-cell">{{ row.description }}</view>
</view>
</view>
</view>
</uv-read-more>
</view>
</view>
<!-- 师资介绍 -->
<view class="section">
<view class="section" v-if="details.educationTeacherList && details.educationTeacherList.length">
<view class="section-header">
<view class="section-header-line"></view>
<view>师资介绍</view>
<view>{{ details.teacherTitle || '师资介绍' }}</view>
</view>
<view class="section-content teachers">
<view class="card" v-for="item in details.educationTeacherList" :key="item.id">
<view class="info">
<view class="pic">
<image class="img" :src="item.image" mode="aspectFill" ></image>
</view>
<view class="title">
<view class="name">{{ item.title }}</view>
<view class="label">
<view class="label" v-if="item.career">
<view class="label-text">{{ item.career }}</view>
<view class="label-line"></view>
<view class="label-text display">{{ item.career }}</view>
</view>
</view>
<view class="tag">
<image class="tag-icon" src="@/static/image/icon-degree.png" mode="widthFix"></image>
<vie>{{ item.qualification }}</vie>
<view>{{ item.qualification }}</view>
</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 class="desc desc-top">专业经历</view>
<view class="desc desc-bottom">{{ item.experience }}</view>
</view>
</view>
</view>
</view>
<!-- 课程安排 -->
<view class="section">
<view class="section" v-if="details.educationCourseList && details.educationCourseList.length">
<view class="section-header">
<view class="section-header-line"></view>
<view>课程安排</view>
<view>{{ details.courseTitle || '课程安排' }}</view>
</view>
<view class="section-content">
<view class="table">
@ -84,10 +91,10 @@
</view>
<!-- 适用人群 -->
<view class="section">
<view class="section" v-if="details.suit">
<view class="section-header">
<view class="section-header-line"></view>
<view>适用人群</view>
<view>{{ details.suitTitle || '适用人群' }}</view>
</view>
<view class="section-content target-audience">
<view class="paragraph">
@ -97,10 +104,10 @@
</view>
<!-- 期刊推荐 -->
<view class="section">
<view class="section" v-if="details.educationPeriodicalList && details.educationPeriodicalList.length">
<view class="section-header">
<view class="section-header-line"></view>
<view>期刊推荐</view>
<view>{{ details.periodicalTitle || '期刊推荐' }}</view>
</view>
<view class="section-content journal">
<view class="box" v-for="item in details.educationPeriodicalList" :key="item.id">
@ -123,10 +130,10 @@
</view>
<!-- 附加材料 -->
<view class="section">
<view class="section" v-if="details.educationDocumentList && details.educationDocumentList.length">
<view class="section-header">
<view class="section-header-line"></view>
<view>附加材料</view>
<view>{{ details.documentTitle || '附加材料' }}</view>
</view>
<view class="section-content attachment">
<view class="flex file" v-for="item in details.educationDocumentList" :key="item.id">
@ -139,7 +146,7 @@
</template>
<view class="file-detail">
<view class="title">{{ item.title }}</view>
<view class="desc">{{ `${getFileType(item.document)} ${item.size || '-'}MB` }}</view>
<!-- <view class="desc">{{ `${getFileType(item.document)} ${item.size || '-'}MB` }}</view> -->
</view>
</view>
<button class="btn" @click="downloadFile(item.document)">下载</button>
@ -147,7 +154,7 @@
</view>
</view>
<view class="flex bottom">
<view class="flex bottom" v-if="hasPoster">
<view class="flex btns">
<button class="btn" @click="jumpToPoster">保存海报</button>
<button class="btn btn-share" open-type="share">分享文章</button>
@ -161,10 +168,15 @@
data() {
return {
details: {},
coverImageHeight: '848rpx',
}
},
onLoad({ thesisId }) {
const windowWidth = uni.getSystemInfoSync().windowWidth
this.coverImageHeight = `${(windowWidth) * 848 / 714}px`
this.getData(thesisId)
// this.getData('1949729528544800770')
},
onShareAppMessage(res) {
return {
@ -174,19 +186,20 @@
}
},
computed: {
bannerList() {
const { image } = this.details || {}
return (image || '').split(',').map(url => ({ image: url }))
},
posterData() {
const { id, title, paperDesc, paperImage } = this.details || {}
const { id, title, image, paperDesc, paperImage } = this.details || {}
return {
paperDesc: paperDesc || title,
paperImage: paperImage || this.bannerList?.[0]?.image || '',
paperImage: paperImage || image || '',
path: `pages_order/thesis/index?thesisId=${id}`
}
},
hasPoster() {
const { paperImage } = this.details || {}
return !!paperImage
}
},
methods: {
async getData(thesisId) {
@ -221,6 +234,7 @@
}
},
fail: (err) => {
console.log('downloadFile fail', err)
uni.showToast({ title: '网络异常', icon: 'none' });
}
});
@ -229,7 +243,7 @@
uni.setStorageSync('posterData', this.posterData)
uni.navigateTo({
url: `/pages_order/poster/index`
url: `/pages_order/thesis/poster`
})
},
},
@ -240,32 +254,93 @@
.page__view {
background: #FFFFFF;
padding-bottom: calc(62rpx + 110rpx + env(safe-area-inset-bottom));
padding-bottom: 62rpx;
&.with-bottom {
padding-bottom: calc(62rpx + 110rpx + env(safe-area-inset-bottom));
}
}
.swiper {
margin: 20rpx 18rpx 32rpx 18rpx;
border-radius: 25rpx;
overflow: hidden;
.cover-image {
position: relative;
width: 100%;
background: #FFFFFF;
/deep/ .uv-swiper-indicator__wrapper__dot {
width: 15rpx;
height: 15rpx;
.img {
width: 100%;
height: 100%;
}
.shadow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
// background: linear-gradient(transparent, #FFFFFF);
background: linear-gradient(transparent, #FFFFFF 90%, #FFFFFF);
}
}
.page-title {
position: absolute;
padding: 0 36rpx;
transform: translateY(-100%);
font-size: 60rpx;
font-weight: 700;
color: #4783F9;
&-line {
margin: 12rpx 0 24rpx 0;
width: 120rpx;
height: 8rpx;
background: #4783F9;
}
}
.process {
position: relative;
width: 100%;
padding: 0 36rpx;
box-sizing: border-box;
&-custom {
padding: 6rpx 18rpx;
background: #E6EEFD;
border-top-right-radius: 32rpx;
border-bottom-right-radius: 32rpx;
}
&-item {
margin-top: 24rpx;
padding: 10rpx 18rpx;
background: #E6EEFD;
border-radius: 25rpx;
&-title {
font-size: 30rpx;
font-weight: 600;
color: #3378EA;
}
&-content {
font-size: 28rpx;
white-space: pre-wrap;
color: #000000;
}
/deep/ .uv-swiper-indicator__wrapper__dot--active {
width: 15rpx;
}
}
.section {
margin-top: 40rpx;
width: 100%;
padding: 0 18rpx;
box-sizing: border-box;
& + & {
margin-top: 40rpx;
}
// & + & {
// margin-top: 40rpx;
// }
&-header {
display: flex;
@ -324,6 +399,7 @@
font-family: PingFang SC;
font-weight: 400;
font-size: 28rpx;
white-space: pre-wrap;
color: #080808;
&:first-child {
@ -333,11 +409,13 @@
}
&.process {
margin-top: 24rpx;
.difficulty {
justify-content: flex-start;
&.direction {
/deep/ .uv-read-more__toggle {
justify-content: flex-end;
}
/deep/ .uv-read-more__toggle__text .uv-text__value {
color: $uni-color !important;
font-size: 22rpx !important;
}
}
@ -353,7 +431,7 @@
.info {
flex: 1;
padding: 19rpx 0 28rpx 17rpx;
padding: 19rpx 17rpx 28rpx 17rpx;
.title {
display: flex;
@ -369,22 +447,32 @@
.label {
margin-left: 12rpx;
position: relative;
height: 30rpx;
// height: 30rpx;
&-line {
margin: 24rpx 0 0 25rpx;
width: 195rpx;
position: absolute;
left: 0;
bottom: 0;
transform: translate(30rpx, -2rpx);
// margin: 24rpx 0 0 25rpx;
// width: 195rpx;
width: calc(100% - 20rpx);
height: 4rpx;
background-image: linear-gradient(#4883F9, #FFFFFF);
border-radius: 2rpx;
}
&-text {
position: absolute;
top: 0;
left: 0;
font-size: 22rpx;
font-weight: 400;
opacity: 0;
&.display {
opacity: 1;
position: absolute;
left: 0;
top: 0;
}
}
}
}
@ -407,21 +495,35 @@
}
.desc {
padding: 12rpx 15rpx;
// padding: 12rpx 15rpx;
font-size: 28rpx;
font-weight: 500;
white-space: pre-wrap;
color: #000000;
background: #f8f8f8;
border-radius: 16rpx;
// border-radius: 16rpx;
&-top {
padding: 12rpx 15rpx 0 15rpx;
border-top-left-radius: 16rpx;
border-top-right-radius: 16rpx;
}
&-bottom {
padding: 0 15rpx 12rpx 15rpx;
border-bottom-left-radius: 16rpx;
border-bottom-right-radius: 16rpx;
}
}
}
.pic {
margin: 48rpx 9rpx 48rpx 0;
// margin: 48rpx 9rpx 48rpx 0;
margin: 44rpx 0 0 14rpx;
width: 253rpx;
height: 345rpx;
border-radius: 127rpx;
overflow: hidden;
float: right;
.img {
width: 100%;
@ -433,11 +535,13 @@
flex-direction: row-reverse;
.info {
padding: 19rpx 17rpx 28rpx 0;
padding: 19rpx 17rpx 28rpx 17rpx;
}
.pic {
margin: 48rpx 0 48rpx 9rpx;
// margin: 48rpx 0 48rpx 9rpx;
margin: 44rpx 14rpx 0 0;
float: left;
}
}
}
@ -475,7 +579,7 @@
}
.info {
height: 181rpx;
// height: 181rpx;
padding: 0 14rpx 0 266rpx;
.name {
@ -487,14 +591,16 @@
.desc {
margin-top: 24rpx;
font-size: 28rpx;
// font-size: 28rpx;
font-size: 24rpx;
white-space: pre-wrap;
font-weight: 700;
color: #707070;
overflow: hidden;
text-overflow: ellipsis;
display:-webkit-box; //
-webkit-box-orient:vertical; //--
-webkit-line-clamp:3; //
// overflow: hidden;
// text-overflow: ellipsis;
// display:-webkit-box; //
// -webkit-box-orient:vertical; //--
// -webkit-line-clamp:3; //
}
}
@ -504,6 +610,7 @@
margin-top: 18rpx;
padding: 14rpx;
font-size: 28rpx;
white-space: pre-wrap;
color: #000000;
background: #ebebeb;
border-radius: 30rpx 0rpx 30rpx 0rpx;
@ -545,7 +652,8 @@
&-info {
display: flex;
align-items: flex-end;
// align-items: flex-end;
align-items: center;
}
&-icon {


+ 450
- 0
pages_order/thesis/indexTwo.vue View File

@ -0,0 +1,450 @@
<template>
<view :class="['page__view', hasPoster ? 'with-bottom' : '']">
<!-- 导航栏 -->
<navbar :title="details.title" leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" />
<view class="cover-image" :style="{ height: coverImageHeight }">
<image class="img" :src="details.image" mode="aspectFill" ></image>
<view class="shadow"></view>
</view>
<view class="page-title">
<view>{{ details.title }}</view>
<view class="page-title-line"></view>
</view>
<view class="section" v-if="details.cotentModuleOne">
<view class="section-header">
<view>{{ details.titleModuleOne }}</view>
</view>
<view class="section-content">
<view class="paragraph">
<uv-parse :content="details.cotentModuleOne"></uv-parse>
</view>
</view>
</view>
<view class="section" v-if="details.cotentModuleTwo">
<view class="section-header">
<view>{{ details.titleModuleTwo }}</view>
</view>
<view class="section-content">
<view class="paragraph">
<uv-parse :content="details.cotentModuleTwo"></uv-parse>
</view>
</view>
</view>
<view class="section" v-if="details.cotentModuleThree">
<view class="section-header">
<view>{{ details.titleModuleThree }}</view>
</view>
<view class="section-content">
<view class="paragraph">
<uv-parse :content="details.cotentModuleThree"></uv-parse>
</view>
</view>
</view>
<view class="section" v-if="details.educationExcelOneList && details.educationExcelOneList.length">
<view class="section-header">
<view>{{ details.titleExcelOne }}</view>
</view>
<view class="section-content">
<uv-read-more show-height="300rpx" :toggle="true" textIndent="0" closeText="展开" :shadowStyle="{ backgroundImage: 'linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)', paddingTop: '100rpx', marginTop: '-100rpx' }">
<view class="table">
<view class="table-row" v-for="row in details.educationExcelOneList" :key="row.id">
<view class="table-cell">{{ row.columnOne }}</view>
<view class="table-cell">{{ row.columnTwo }}</view>
</view>
</view>
</uv-read-more>
</view>
</view>
<view class="section" v-if="details.cotentModuleFour">
<view class="section-header">
<view>{{ details.titleModuleFour }}</view>
</view>
<view class="section-content">
<view class="paragraph">
<uv-parse :content="details.cotentModuleFour"></uv-parse>
</view>
</view>
</view>
<view class="section" v-if="details.cotentModuleFive">
<view class="section-header">
<view>{{ details.titleModuleFive }}</view>
</view>
<view class="section-content">
<view class="paragraph">
<uv-parse :content="details.cotentModuleFive"></uv-parse>
</view>
</view>
</view>
<view class="section" v-if="details.educationExcelTwoList && details.educationExcelTwoList.length">
<view class="section-header">
<view>{{ details.titleExcelTwo }}</view>
</view>
<view class="section-content">
<uv-read-more show-height="300rpx" :toggle="true" textIndent="0" closeText="展开" :shadowStyle="{ backgroundImage: 'linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)', paddingTop: '100rpx', marginTop: '-100rpx' }">
<view class="table">
<view class="table-row" v-for="row in details.educationExcelTwoList" :key="row.id">
<view class="table-cell">{{ row.columnOne }}</view>
<view class="table-cell">{{ row.columnTwo }}</view>
</view>
</view>
</uv-read-more>
</view>
</view>
<view class="section" v-if="details.cotentModuleSix">
<view class="section-header">
<view>{{ details.titleModuleSix }}</view>
</view>
<view class="section-content">
<view class="paragraph">
<uv-parse :content="details.cotentModuleSix"></uv-parse>
</view>
</view>
</view>
<view class="section" v-if="details.cotentModuleSeven">
<view class="section-header">
<view>{{ details.titleModuleSeven }}</view>
</view>
<view class="section-content">
<view class="paragraph">
<uv-parse :content="details.cotentModuleSeven"></uv-parse>
</view>
</view>
</view>
<!-- 附加材料 -->
<view class="section" v-if="details.educationDocumentTwoList && details.educationDocumentTwoList.length">
<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 details.educationDocumentTwoList" :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.title }}</view>
<!-- <view class="desc">{{ `${getFileType(item.document)} ${item.size || '-'}MB` }}</view> -->
</view>
</view>
<button class="btn" @click="downloadFile(item.document)">下载</button>
</view>
</view>
</view>
<view class="flex bottom" v-if="hasPoster">
<view class="flex btns">
<button class="btn" @click="jumpToPoster">保存海报</button>
<button class="btn btn-share" open-type="share">分享文章</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
details: {},
coverImageHeight: '848rpx',
}
},
onLoad({ thesisId }) {
const windowWidth = uni.getSystemInfoSync().windowWidth
this.coverImageHeight = `${(windowWidth) * 848 / 714}px`
this.getData(thesisId)
},
onShareAppMessage(res) {
return {
title: this.posterData.paperDesc,
imageUrl: this.posterData.paperImage,
path: this.posterData.path,
}
},
computed: {
posterData() {
const { id, title, image, paperDesc, paperImage } = this.details || {}
return {
paperDesc: paperDesc || title,
paperImage: paperImage || image || '',
path: `pages_order/thesis/index?thesisId=${id}`
}
},
hasPoster() {
const { paperImage } = this.details || {}
return !!paperImage
}
},
methods: {
async getData(thesisId) {
try {
this.details = await this.$fetch('queryThesisTwoById', { thesisId })
} catch (err) {
}
},
getFileType(fileName) {
const pdfReg = /(.pdf)$/g
// const officeReg = /(doc|docx|ppt|pptx|xls|xlsx)$/g
return pdfReg.test(fileName) ? 'pdf' : ''
},
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) => {
console.log('downloadFile fail', err)
uni.showToast({ title: '网络异常', icon: 'none' });
}
});
},
jumpToPoster() {
uni.setStorageSync('posterData', this.posterData)
uni.navigateTo({
url: `/pages_order/thesis/poster`
})
},
},
}
</script>
<style scoped lang="scss">
.page__view {
background: #FFFFFF;
padding-bottom: 62rpx;
&.with-bottom {
padding-bottom: calc(62rpx + 110rpx + env(safe-area-inset-bottom));
}
}
.cover-image {
position: relative;
width: 100%;
background: #FFFFFF;
.img {
width: 100%;
height: 100%;
}
.shadow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
// background: linear-gradient(transparent, #FFFFFF);
background: linear-gradient(transparent, #FFFFFF 90%, #FFFFFF);
}
}
.page-title {
position: absolute;
padding: 0 36rpx;
transform: translateY(-100%);
font-size: 60rpx;
font-weight: 700;
color: #4783F9;
&-line {
margin: 12rpx 0 24rpx 0;
width: 120rpx;
height: 8rpx;
background: #4783F9;
}
}
.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;
white-space: pre-wrap;
color: #080808;
&:first-child {
border-right: 1rpx solid #E5E5E5;
}
}
}
/deep/ .uv-read-more__toggle {
justify-content: flex-end;
}
/deep/ .uv-read-more__toggle__text .uv-text__value {
color: $uni-color !important;
font-size: 22rpx !important;
}
&.attachment {
.file {
justify-content: space-between;
padding: 32rpx 15rpx 32rpx 26rpx;
background: #f8f8f8;
border-radius: 15rpx;
&-info {
display: flex;
// align-items: flex-end;
align-items: center;
}
&-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;
}
}
}
}
.bottom {
position: fixed;
left: 0;
bottom: 0;
width: 100vw;
height: 110rpx;
padding-bottom: env(safe-area-inset-bottom);
background: #FFFFFF;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.16);
.btns {
column-gap: 34rpx;
}
.btn {
padding: 20rpx 90rpx;
font-size: 28rpx;
color: #FFFFFF;
background: #4883F9;
border-radius: 42rpx;
&-share {
background: #FFD019;
}
}
}
</style>

pages_order/poster/index.vue → pages_order/thesis/poster.vue View File

@ -4,7 +4,8 @@
<!-- 导航栏 -->
<navbar leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" />
<view style="width: 750rpx; height: 1184rpx; overflow: hidden;">
<!-- height: 1184rpx; -->
<view style="width: 750rpx; height: 890rpx; overflow: hidden;">
<canvas id="myCanvas" canvas-id="firstCanvas1" type="2d" style="width: 100%; height: 100%;"></canvas>
</view>
@ -45,57 +46,6 @@
}
},
drawTextWithManualLineBreaks(ctx, text, x, y, maxWidth, lineHeight) {
let rows = 0
let size = 0
let lines = text.split('\n'); //
for (let lIdx = 0; lIdx < lines.length; lIdx++) {
let line = lines[lIdx]
let row = ''
for (let wIdx = 0; wIdx < line.length; wIdx++) {
let word = line[wIdx]
let metrics = ctx.measureText(row + word);
if (metrics.width > maxWidth) {
rows++
size += row.length
console.log('--rows', rows, '--size', size)
if (rows === 4 && size < text.length) {
row = row.slice(0, -2) + '......'
}
ctx.fillText(row, x, y);
row = ''
y += lineHeight
if (rows === 4) {
break
}
} else {
row += word
}
}
if (rows === 4) {
break
}
if (row) {
rows++
size += row.length
console.log('--rows', rows, '--size', size)
if (rows === 4 && size < text.length) {
row = row.slice(0, -2) + '......'
}
ctx.fillText(row, x, y);
y += lineHeight
if (rows === 4) {
break
}
}
}
},
draw() {
uni.showLoading({
@ -134,33 +84,23 @@
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = '#999999';
const fontSize = 28 * Ratio / dpr
ctx.font = `${fontSize}px PingFangSC-regular`;
const descX = 37 * Ratio / dpr
const descY = 751 * Ratio / dpr
const maxWidth = 677 * Ratio / dpr
const lineHeight = 45 * Ratio / dpr
const text = this.posterData.paperDesc
this.drawTextWithManualLineBreaks(ctx, text, descX, descY, maxWidth, lineHeight)
//
const paperImage = canvas.createImage()
paperImage.src = this.posterData.paperImage
paperImage.onload = () => {
const x = 37 * Ratio / dpr
const y = 21 * Ratio / dpr
const w = 677 * Ratio / dpr
const h = 687 * Ratio / dpr
ctx.drawImage(paperImage, x, y, w, h)
const w = 750 * Ratio / dpr
// const h = 1184 * Ratio / dpr
const h = 890 * Ratio / dpr
ctx.drawImage(paperImage, 0, 0, w, h)
//
const coderImage = canvas.createImage()
coderImage.src = this.wxCodeImage
coderImage.onload = () => {
const x = 539 * Ratio / dpr
const y = 987 * Ratio / dpr
// const x = 539 * Ratio / dpr
const x = 560 * Ratio / dpr
// const y = 987 * Ratio / dpr
const y = 693 * Ratio / dpr
const size = 162 * Ratio / dpr
ctx.drawImage(coderImage, x, y, size, size)

+ 79
- 9
pages_order/thesis/search.vue View File

@ -20,11 +20,19 @@
<template v-if="total">
<view class="flex card" v-for="item in list" :key="item.id" @click="jumpToDetail(item.id)">
<view class="left">
<view class="title">{{ item.title }}</view>
<view class="content">{{ item.shortTitle }}</view>
<view class="title-box">
<view class="title">{{ item.title }}</view>
</view>
<view class="content-box" v-if="item.shortTitle">
<view class="content">
{{ item.shortTitle || '' }}
</view>
<view class="dot bottom-left"></view>
<view class="dot top-right"></view>
</view>
</view>
<view class="right">
<image class="img" :src="item.image" mode="aspectFill"></image>
<image class="img" :src="item.paperImage" mode="aspectFill"></image>
</view>
</view>
</template>
@ -55,7 +63,7 @@
mixinsListApi: 'queryThesisList',
}
},
onLoad({ search, categoryOne, categoryTwo, title }) {
onLoad({ search, categoryOne, categoryTwo, title, api }) {
if (search) {
this.keyword = search
this.queryParams.title = search
@ -67,6 +75,9 @@
if (title) {
this.title = title
}
if (api) {
this.mixinsListApi = api
}
this.getData()
},
@ -78,8 +89,10 @@
this.getData()
},
jumpToDetail(thesisId) {
let path = this.mixinsListApi == 'queryThesisList' ? '/pages_order/thesis/index' : '/pages_order/thesis/indexTwo'
uni.navigateTo({
url: `/pages_order/thesis/index?thesisId=${thesisId}`
url: `${path}?thesisId=${thesisId}`
})
},
},
@ -136,24 +149,81 @@
.left {
flex: 1;
padding: 13rpx 32rpx 35rpx 20rpx;
position: relative;
// padding: 13rpx 32rpx 35rpx 20rpx;
padding: 13rpx 70rpx 35rpx 20rpx;
box-sizing: border-box;
.title {
font-size: 32rpx;
font-weight: 700;
color: #000000;
color: $uni-color;
padding: 4rpx 16rpx;
background: #FFFFFF;
border-radius: 12rpx;
&-box {
position: absolute;
top: 0;
z-index: 1;
display: inline-block;
padding: 4rpx;
background: linear-gradient(to right, $uni-color, #FFFFFF);
border-radius: 14rpx;
transform: translateY(50%);
}
}
.content {
font-size: 28rpx;
font-size: 24rpx;
font-weight: 400;
color: #0F2248;
color: #000000;
white-space: pre-wrap;
overflow: hidden;
text-overflow: ellipsis;
display:-webkit-box; //
-webkit-box-orient:vertical; //--
-webkit-line-clamp:7; //
&-box {
margin-top: 40rpx;
position: relative;
padding: 40rpx 16rpx;
border: 4rpx solid $uni-color;
border-radius: 20rpx;
&:after {
content: ' ';
position: absolute;
bottom: 0;
right: 0;
width: 20rpx;
height: 40rpx;
background: #FFFFFF;
transform: translate(4rpx, 4rpx);
}
.dot {
position: absolute;
z-index: 2;
width: 8rpx;
height: 8rpx;
background: $uni-color;
border-radius: 50%;
&.bottom-left {
bottom: 0;
right: 16rpx;
transform: translateY(6rpx);
}
&.top-right {
bottom: 36rpx;
right: 0;
transform: translateX(6rpx);
}
}
}
}
}


Loading…
Cancel
Save