8 changed files with 69 additions and 1263 deletions
@ -0,0 +1,47 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
// api地址
|
|||
const api = { |
|||
todoCounts: 'order/todoCounts', |
|||
list: 'order/list', |
|||
detail: 'order/detail', |
|||
express: 'order/express', |
|||
cancel: 'order/cancel', |
|||
receipt: 'order/receipt', |
|||
pay: 'order/pay' |
|||
} |
|||
|
|||
// 当前用户待处理的订单数量
|
|||
export function todoCounts(param, option) { |
|||
return request.get(api.todoCounts, param, option) |
|||
} |
|||
|
|||
// 我的订单列表
|
|||
export function list(param, option) { |
|||
return request.get(api.list, param, option) |
|||
} |
|||
|
|||
// 订单详情
|
|||
export function detail(orderId, param) { |
|||
return request.get(api.detail, { orderId, ...param }) |
|||
} |
|||
|
|||
// 获取物流信息
|
|||
export function express(orderId, param) { |
|||
return request.get(api.express, { orderId, ...param }) |
|||
} |
|||
|
|||
// 取消订单
|
|||
export function cancel(orderId, data) { |
|||
return request.post(api.cancel, { orderId, ...data }) |
|||
} |
|||
|
|||
// 确认收货
|
|||
export function receipt(orderId, data) { |
|||
return request.post(api.receipt, { orderId, ...data }) |
|||
} |
|||
|
|||
// 立即支付
|
|||
export function pay(orderId, payType, param) { |
|||
return request.get(api.pay, { orderId, payType, ...param }) |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
// api地址
|
|||
const api = { |
|||
image: 'upload/image' |
|||
} |
|||
|
|||
// 图片上传
|
|||
export const image = files => { |
|||
// 文件上传大小, 2M
|
|||
const maxSize = 1024 * 1024 * 2 |
|||
// 执行上传
|
|||
return new Promise((resolve, reject) => { |
|||
request.urlFileUpload({ files, maxSize }) |
|||
.then(result => resolve(result.map(item => item.data.fileInfo.file_id), result)) |
|||
.catch(reject) |
|||
}) |
|||
} |
|||
@ -1,187 +0,0 @@ |
|||
<template> |
|||
<view class="container"> |
|||
<!-- 标题 --> |
|||
<view class="page-title">收货地址</view> |
|||
<!-- 表单组件 --> |
|||
<view class="form-wrapper"> |
|||
<u-form :model="form" ref="uForm" label-width="140rpx"> |
|||
<u-form-item label="姓名" prop="name"> |
|||
<u-input v-model="form.name" placeholder="请输入收货人姓名" /> |
|||
</u-form-item> |
|||
<u-form-item label="电话" prop="phone"> |
|||
<u-input v-model="form.phone" placeholder="请输入收货人手机号" /> |
|||
</u-form-item> |
|||
<u-form-item label="地区" prop="region"> |
|||
<select-region ref="sRegion" v-model="form.region" /> |
|||
</u-form-item> |
|||
<u-form-item label="详细地址" prop="detail" :border-bottom="false"> |
|||
<u-input v-model="form.detail" placeholder="街道门牌、楼层等信息" /> |
|||
</u-form-item> |
|||
</u-form> |
|||
</view> |
|||
<!-- 操作按钮 --> |
|||
<view class="footer"> |
|||
<view class="btn-wrapper"> |
|||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">保存</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import SelectRegion from '@/components/select-region/select-region' |
|||
import { isMobile } from '@/utils/verify' |
|||
import * as AddressApi from '@/api/address' |
|||
|
|||
// 表单字段元素 |
|||
const form = { |
|||
name: '', |
|||
phone: '', |
|||
region: [], |
|||
detail: '' |
|||
} |
|||
|
|||
// 表单验证规则 |
|||
const rules = { |
|||
name: [{ |
|||
required: true, |
|||
message: '请输入姓名', |
|||
trigger: ['blur', 'change'] |
|||
}], |
|||
phone: [{ |
|||
required: true, |
|||
message: '请输入手机号', |
|||
trigger: ['blur', 'change'] |
|||
}, { |
|||
// 自定义验证函数 |
|||
validator: (rule, value, callback) => { |
|||
// 返回true表示校验通过,返回false表示不通过 |
|||
return isMobile(value) |
|||
}, |
|||
message: '手机号码不正确', |
|||
// 触发器可以同时用blur和change |
|||
trigger: ['blur'], |
|||
}], |
|||
region: [{ |
|||
required: true, |
|||
message: '请选择省市区', |
|||
trigger: ['blur', 'change'], |
|||
type: 'array' |
|||
}], |
|||
detail: [{ |
|||
required: true, |
|||
message: '请输入详细地址', |
|||
trigger: ['blur', 'change'] |
|||
}], |
|||
} |
|||
|
|||
export default { |
|||
components: { |
|||
SelectRegion |
|||
}, |
|||
data() { |
|||
return { |
|||
form, |
|||
rules, |
|||
// 按钮禁用 |
|||
disabled: false |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面加载 |
|||
*/ |
|||
onLoad(options) {}, |
|||
|
|||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕 |
|||
onReady() { |
|||
this.$refs.uForm.setRules(this.rules) |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
// 表单提交 |
|||
handleSubmit() { |
|||
const app = this |
|||
if (app.disabled) { |
|||
return false |
|||
} |
|||
app.$refs.uForm.validate(valid => { |
|||
if (valid) { |
|||
app.disabled = true |
|||
AddressApi.add(app.form) |
|||
.then(result => { |
|||
app.$toast(result.message) |
|||
uni.navigateBack() |
|||
}) |
|||
.finally(() => app.disabled = false) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
page { |
|||
background: #f7f8fa; |
|||
} |
|||
</style> |
|||
<style lang="scss" scoped> |
|||
.page-title { |
|||
width: 94%; |
|||
margin: 0 auto; |
|||
padding-top: 40rpx; |
|||
font-size: 28rpx; |
|||
color: rgba(69, 90, 100, 0.6); |
|||
} |
|||
|
|||
.form-wrapper { |
|||
margin: 20rpx auto 20rpx auto; |
|||
padding: 0 40rpx; |
|||
width: 94%; |
|||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05); |
|||
border-radius: 16rpx; |
|||
background: #fff; |
|||
} |
|||
|
|||
// 底部操作栏 |
|||
.footer { |
|||
margin-top: 80rpx; |
|||
|
|||
.btn-wrapper { |
|||
height: 100%; |
|||
// display: flex; |
|||
// align-items: center; |
|||
padding: 0 20rpx; |
|||
} |
|||
|
|||
.btn-item { |
|||
flex: 1; |
|||
font-size: 28rpx; |
|||
height: 86rpx; |
|||
color: #fff; |
|||
border-radius: 50rpx; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
.btn-item-wechat { |
|||
background: #0ba90b; |
|||
margin-bottom: 26rpx; |
|||
} |
|||
|
|||
.btn-item-main { |
|||
background: linear-gradient(to right, #f9211c, #ff6335); |
|||
color: #fff; |
|||
|
|||
// 禁用按钮 |
|||
&.disabled { |
|||
opacity: 0.6; |
|||
} |
|||
} |
|||
|
|||
} |
|||
</style> |
|||
@ -1,309 +0,0 @@ |
|||
<template> |
|||
<view class="container"> |
|||
<view class="addres-list"> |
|||
<view class="address-item" v-for="(item, index) in list" :key="index"> |
|||
<view class="contacts"> |
|||
<text class="name">{{ item.name }}</text> |
|||
<text class="phone">{{ item.phone }}</text> |
|||
</view> |
|||
<view class="address"> |
|||
<text class="region" v-for="(region, idx) in item.region" :key="idx">{{ region }}</text> |
|||
<text class="detail">{{ item.detail }}</text> |
|||
</view> |
|||
<view class="line"></view> |
|||
<view class="item-option"> |
|||
<view class="_left"> |
|||
<label class="item-radio" @click.stop="handleSetDefault(item.address_id)"> |
|||
<radio class="radio" color="#fa2209" :checked="item.address_id == defaultId"></radio> |
|||
<text class="text">{{ item.address_id == defaultId ? '默认' : '选择' }}</text> |
|||
</label> |
|||
</view> |
|||
<view class="_right"> |
|||
<view class="events"> |
|||
<view class="event-item" @click="handleUpdate(item.address_id)"> |
|||
<text class="iconfont icon-edit"></text> |
|||
<text class="title">编辑</text> |
|||
</view> |
|||
<view class="event-item" @click="handleRemove(item.address_id)"> |
|||
<text class="iconfont icon-delete"></text> |
|||
<text class="title">删除</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<empty v-if="!list.length" :isLoading="isLoading" tips="亲,暂无收货地址" /> |
|||
<!-- 底部操作按钮 --> |
|||
<view class="footer-fixed"> |
|||
<view class="btn-wrapper"> |
|||
<view class="btn-item btn-item-main" @click="handleCreate()">添加新地址</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import * as AddressApi from '@/api/address' |
|||
import Empty from '@/components/empty' |
|||
|
|||
export default { |
|||
components: { |
|||
Empty |
|||
}, |
|||
data() { |
|||
return { |
|||
//当前页面参数 |
|||
options: {}, |
|||
// 正在加载 |
|||
isLoading: true, |
|||
// 收货地址列表 |
|||
list: [], |
|||
// 默认收货地址 |
|||
defaultId: null |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面加载 |
|||
*/ |
|||
onLoad(options) { |
|||
// 当前页面参数 |
|||
this.options = options |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面显示 |
|||
*/ |
|||
onShow() { |
|||
// 获取页面数据 |
|||
this.getPageData() |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
// 获取页面数据 |
|||
getPageData() { |
|||
const app = this |
|||
app.isLoading = true |
|||
Promise.all([app.getDefaultId(), app.getAddressList()]) |
|||
.then(() => { |
|||
// 列表排序把默认收货地址放到最前 |
|||
app.onReorder() |
|||
}) |
|||
.finally(() => app.isLoading = false) |
|||
}, |
|||
|
|||
// 获取收货地址列表 |
|||
getAddressList() { |
|||
const app = this |
|||
return new Promise((resolve, reject) => { |
|||
AddressApi.list() |
|||
.then(result => { |
|||
app.list = result.data.list |
|||
resolve(result) |
|||
}) |
|||
.catch(reject) |
|||
}) |
|||
}, |
|||
|
|||
// 获取默认的收货地址 |
|||
getDefaultId() { |
|||
return new Promise((resolve, reject) => { |
|||
const app = this |
|||
AddressApi.defaultId() |
|||
.then(result => { |
|||
app.defaultId = result.data.defaultId |
|||
resolve(result) |
|||
}) |
|||
.catch(reject) |
|||
}) |
|||
}, |
|||
|
|||
// 列表排序把默认收货地址放到最前 |
|||
onReorder() { |
|||
const app = this |
|||
app.list.sort(item => { |
|||
return item.address_id == app.defaultId ? -1 : 1 |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 添加新地址 |
|||
*/ |
|||
handleCreate() { |
|||
this.$navTo('pages/address/create') |
|||
}, |
|||
|
|||
/** |
|||
* 编辑地址 |
|||
* @param {int} addressId 收货地址ID |
|||
*/ |
|||
handleUpdate(addressId) { |
|||
this.$navTo('pages/address/update', { addressId }) |
|||
}, |
|||
|
|||
/** |
|||
* 删除收货地址 |
|||
* @param {int} addressId 收货地址ID |
|||
*/ |
|||
handleRemove(addressId) { |
|||
const app = this |
|||
uni.showModal({ |
|||
title: "提示", |
|||
content: "您确定要删除当前收货地址吗?", |
|||
success({ confirm }) { |
|||
confirm && app.onRemove(addressId) |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 确认删除收货地址 |
|||
* @param {int} addressId 收货地址ID |
|||
*/ |
|||
onRemove(addressId) { |
|||
const app = this |
|||
AddressApi.remove(addressId) |
|||
.then(result => { |
|||
app.getPageData() |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 设置为默认地址 |
|||
* @param {Object} addressId |
|||
*/ |
|||
handleSetDefault(addressId) { |
|||
const app = this |
|||
AddressApi.setDefault(addressId) |
|||
.then(result => { |
|||
app.defaultId = addressId |
|||
app.options.from === 'checkout' && uni.navigateBack() |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.addres-list { |
|||
padding-top: 20rpx; |
|||
// 设置ios刘海屏底部横线安全区域 |
|||
padding-bottom: calc(constant(safe-area-inset-bottom) + 140rpx); |
|||
padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx); |
|||
} |
|||
|
|||
// 项目内容 |
|||
.address-item { |
|||
margin: 20rpx auto 20rpx auto; |
|||
padding: 30rpx 40rpx; |
|||
width: 94%; |
|||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05); |
|||
border-radius: 16rpx; |
|||
background: #fff; |
|||
} |
|||
|
|||
.contacts { |
|||
font-size: 30rpx; |
|||
margin-bottom: 16rpx; |
|||
|
|||
.name { |
|||
margin-right: 16rpx; |
|||
} |
|||
} |
|||
|
|||
.address { |
|||
font-size: 28rpx; |
|||
|
|||
.region { |
|||
margin-right: 10rpx; |
|||
} |
|||
} |
|||
|
|||
.line { |
|||
margin: 20rpx 0; |
|||
border-bottom: 1rpx solid #f3f3f3; |
|||
} |
|||
|
|||
.item-option { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
height: 48rpx; |
|||
|
|||
// 单选框 |
|||
.item-radio { |
|||
font-size: 28rpx; |
|||
|
|||
.radio { |
|||
vertical-align: middle; |
|||
transform: scale(0.76) |
|||
} |
|||
|
|||
.text { |
|||
vertical-align: middle; |
|||
} |
|||
} |
|||
|
|||
// 操作 |
|||
.events { |
|||
display: flex; |
|||
align-items: center; |
|||
line-height: 48rpx; |
|||
|
|||
.event-item { |
|||
font-size: 28rpx; |
|||
margin-right: 26rpx; |
|||
color: #4c4c4c; |
|||
|
|||
&:last-child { |
|||
margin-right: 0; |
|||
} |
|||
|
|||
.title { |
|||
margin-left: 8rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
// 底部操作栏 |
|||
.footer-fixed { |
|||
position: fixed; |
|||
bottom: var(--window-bottom); |
|||
left: 0; |
|||
right: 0; |
|||
min-height: 120rpx; |
|||
z-index: 11; |
|||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24); |
|||
background: #fff; |
|||
|
|||
// 设置ios刘海屏底部横线安全区域 |
|||
padding-bottom: constant(safe-area-inset-bottom); |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
|
|||
.btn-wrapper { |
|||
height: 120rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 0 40rpx; |
|||
} |
|||
|
|||
.btn-item { |
|||
flex: 1; |
|||
font-size: 28rpx; |
|||
height: 80rpx; |
|||
line-height: 80rpx; |
|||
text-align: center; |
|||
color: #fff; |
|||
border-radius: 50rpx; |
|||
} |
|||
|
|||
.btn-item-main { |
|||
background: linear-gradient(to right, #f9211c, #ff6335); |
|||
} |
|||
|
|||
} |
|||
</style> |
|||
@ -1,225 +0,0 @@ |
|||
<template> |
|||
<view class="container"> |
|||
<!-- 标题 --> |
|||
<view class="page-title">收货地址</view> |
|||
<!-- 表单组件 --> |
|||
<view class="form-wrapper"> |
|||
<u-form :model="form" ref="uForm" label-width="140rpx"> |
|||
<u-form-item label="姓名" prop="name"> |
|||
<u-input v-model="form.name" placeholder="请输入收货人姓名" /> |
|||
</u-form-item> |
|||
<u-form-item label="电话" prop="phone"> |
|||
<u-input v-model="form.phone" placeholder="请输入收货人手机号" /> |
|||
</u-form-item> |
|||
<u-form-item label="地区" prop="region"> |
|||
<select-region ref="sRegion" v-model="form.region" /> |
|||
</u-form-item> |
|||
<u-form-item label="详细地址" prop="detail" :border-bottom="false"> |
|||
<u-input v-model="form.detail" placeholder="街道门牌、楼层等信息" /> |
|||
</u-form-item> |
|||
</u-form> |
|||
</view> |
|||
<!-- 操作按钮 --> |
|||
<view class="footer"> |
|||
<view class="btn-wrapper"> |
|||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">保存</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import SelectRegion from '@/components/select-region/select-region' |
|||
import { isMobile } from '@/utils/verify' |
|||
import * as AddressApi from '@/api/address' |
|||
|
|||
// 表单验证规则 |
|||
const rules = { |
|||
name: [{ |
|||
required: true, |
|||
message: '请输入姓名', |
|||
trigger: ['blur', 'change'] |
|||
}], |
|||
phone: [{ |
|||
required: true, |
|||
message: '请输入手机号', |
|||
trigger: ['blur', 'change'] |
|||
}, { |
|||
// 自定义验证函数 |
|||
validator: (rule, value, callback) => { |
|||
// 返回true表示校验通过,返回false表示不通过 |
|||
return isMobile(value) |
|||
}, |
|||
message: '手机号码不正确', |
|||
// 触发器可以同时用blur和change |
|||
trigger: ['blur'], |
|||
}], |
|||
region: [{ |
|||
required: true, |
|||
message: '请选择省市区', |
|||
trigger: ['blur', 'change'], |
|||
type: 'array' |
|||
}], |
|||
detail: [{ |
|||
required: true, |
|||
message: '请输入详细地址', |
|||
trigger: ['blur', 'change'] |
|||
}], |
|||
} |
|||
|
|||
export default { |
|||
components: { |
|||
SelectRegion |
|||
}, |
|||
data() { |
|||
return { |
|||
form: { |
|||
name: '', |
|||
phone: '', |
|||
region: [], |
|||
detail: '' |
|||
}, |
|||
rules, |
|||
// 加载中 |
|||
isLoading: true, |
|||
// 按钮禁用 |
|||
disabled: false, |
|||
// 当前收货地址ID |
|||
addressId: null |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面加载 |
|||
*/ |
|||
onLoad({ addressId }) { |
|||
// 当前收货地址ID |
|||
this.addressId = addressId |
|||
// 获取当前记录详情 |
|||
this.getDetail() |
|||
}, |
|||
|
|||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕 |
|||
onReady() { |
|||
this.$refs.uForm.setRules(this.rules) |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
// 获取当前记录详情 |
|||
getDetail() { |
|||
const app = this |
|||
AddressApi.detail(app.addressId) |
|||
.then(result => { |
|||
const detail = result.data.detail |
|||
app.createFormData(detail) |
|||
}) |
|||
}, |
|||
|
|||
// 生成默认的表单数据 |
|||
createFormData(detail) { |
|||
const { form } = this |
|||
form.name = detail.name |
|||
form.phone = detail.phone |
|||
form.detail = detail.detail |
|||
form.region = this.createRegion(detail) |
|||
}, |
|||
|
|||
createRegion(detail) { |
|||
return [{ |
|||
label: detail.region.province, |
|||
value: detail.province_id |
|||
}, { |
|||
label: detail.region.city, |
|||
value: detail.city_id |
|||
}, { |
|||
label: detail.region.region, |
|||
value: detail.region_id |
|||
}] |
|||
}, |
|||
|
|||
// 表单提交 |
|||
handleSubmit() { |
|||
const app = this |
|||
if (app.disabled) { |
|||
return false |
|||
} |
|||
app.$refs.uForm.validate(valid => { |
|||
if (valid) { |
|||
app.disabled = true |
|||
AddressApi.edit(app.addressId, app.form) |
|||
.then(result => { |
|||
app.$toast(result.message) |
|||
uni.navigateBack() |
|||
}) |
|||
.finally(() => app.disabled = false) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
page { |
|||
background: #f7f8fa; |
|||
} |
|||
</style> |
|||
<style lang="scss" scoped> |
|||
.page-title { |
|||
width: 94%; |
|||
margin: 0 auto; |
|||
padding-top: 40rpx; |
|||
font-size: 28rpx; |
|||
color: rgba(69, 90, 100, 0.6); |
|||
} |
|||
|
|||
.form-wrapper { |
|||
margin: 20rpx auto 20rpx auto; |
|||
padding: 0 40rpx; |
|||
width: 94%; |
|||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05); |
|||
border-radius: 16rpx; |
|||
background: #fff; |
|||
} |
|||
|
|||
// 底部操作栏 |
|||
.footer { |
|||
margin-top: 80rpx; |
|||
|
|||
.btn-wrapper { |
|||
height: 100%; |
|||
// display: flex; |
|||
// align-items: center; |
|||
padding: 0 20rpx; |
|||
} |
|||
|
|||
.btn-item { |
|||
flex: 1; |
|||
font-size: 28rpx; |
|||
height: 86rpx; |
|||
color: #fff; |
|||
border-radius: 50rpx; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
.btn-item-wechat { |
|||
background: #0ba90b; |
|||
margin-bottom: 26rpx; |
|||
} |
|||
|
|||
.btn-item-main { |
|||
background: linear-gradient(to right, #f9211c, #ff6335); |
|||
color: #fff; |
|||
|
|||
// 禁用按钮 |
|||
&.disabled { |
|||
opacity: 0.6; |
|||
} |
|||
} |
|||
|
|||
} |
|||
</style> |
|||
@ -1,107 +0,0 @@ |
|||
<template> |
|||
<view v-if="!isLoading" class="container b-f p-b"> |
|||
<view class="article-title"> |
|||
<text class="f-32">{{ detail.title }}</text> |
|||
</view> |
|||
<view class="article-little dis-flex flex-x-between m-top10"> |
|||
<view class="article-little__left"> |
|||
<text class="article-views f-24 col-8">{{ detail.show_views }}次浏览</text> |
|||
</view> |
|||
<view class="article-little__right"> |
|||
<text class="article-views f-24 col-8">{{ detail.view_time }}</text> |
|||
</view> |
|||
</view> |
|||
<view class="article-content m-top20"> |
|||
<mp-html :content="detail.content" /> |
|||
</view> |
|||
<!-- 快捷导航 --> |
|||
<shortcut /> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import Shortcut from '@/components/shortcut' |
|||
import * as ArticleApi from '@/api/article' |
|||
|
|||
export default { |
|||
components: { |
|||
Shortcut |
|||
}, |
|||
data() { |
|||
return { |
|||
// 当前文章ID |
|||
articleId: null, |
|||
// 加载中 |
|||
isLoading: true, |
|||
// 当前文章详情 |
|||
detail: null |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面加载 |
|||
*/ |
|||
onLoad(options) { |
|||
// 记录文章ID |
|||
this.articleId = options.articleId |
|||
// 获取文章详情 |
|||
this.getArticleDetail() |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
// 获取文章详情 |
|||
getArticleDetail() { |
|||
const app = this |
|||
app.isLoading = true |
|||
ArticleApi.detail(app.articleId) |
|||
.then(result => { |
|||
app.detail = result.data.detail |
|||
}) |
|||
.finally(() => app.isLoading = false) |
|||
} |
|||
|
|||
}, |
|||
|
|||
/** |
|||
* 分享当前页面 |
|||
*/ |
|||
onShareAppMessage() { |
|||
const app = this |
|||
// 构建页面参数 |
|||
const params = app.$getShareUrlParams({ articleId: app.articleId }); |
|||
return { |
|||
title: app.detail.title, |
|||
path: "/pages/article/detail?" + params |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 分享到朋友圈 |
|||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta) |
|||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html |
|||
*/ |
|||
onShareTimeline() { |
|||
const app = this |
|||
// 构建页面参数 |
|||
const params = app.$getShareUrlParams({ articleId: app.articleId }); |
|||
return { |
|||
title: app.detail.title, |
|||
path: "/pages/article/detail?" + params |
|||
} |
|||
} |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.container { |
|||
min-height: 100vh; |
|||
padding: 20rpx; |
|||
background: #fff; |
|||
} |
|||
|
|||
.article-content { |
|||
font-size: 28rpx; |
|||
} |
|||
</style> |
|||
@ -1,251 +0,0 @@ |
|||
<template> |
|||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption" |
|||
@up="upCallback"> |
|||
|
|||
<!-- tab栏 --> |
|||
<u-tabs :list="tabList" :is-scroll="true" :current="curTab" active-color="#fd4a5f" :duration="0.2" |
|||
@change="onChangeTab" /> |
|||
|
|||
<!-- 文章列表 --> |
|||
<view class="article-list"> |
|||
<view class="article-item" :class="[`show-type__${item.show_type}`]" v-for="(item, index) in articleList.data" |
|||
:key="index" @click="onTargetDetail(item.article_id)"> |
|||
<!-- 小图模式 --> |
|||
<block v-if="item.show_type == 10"> |
|||
<view class="article-item__left flex-box"> |
|||
<view class="article-item__title"> |
|||
<text class="twoline-hide">{{ item.title }}</text> |
|||
</view> |
|||
<view class="article-item__footer m-top10"> |
|||
<text class="article-views f-24 col-8">{{ item.show_views }}次浏览</text> |
|||
</view> |
|||
</view> |
|||
<view class="article-item__image"> |
|||
<image class="image" mode="widthFix" :src="item.image_url"></image> |
|||
</view> |
|||
</block> |
|||
<!-- 大图模式 --> |
|||
<block v-if="item.show_type == 20"> |
|||
<view class="article-item__title"> |
|||
<text class="twoline-hide">{{ item.title }}</text> |
|||
</view> |
|||
<view class="article-item__image m-top20"> |
|||
<image class="image" mode="widthFix" :src="item.image_url"></image> |
|||
</view> |
|||
<view class="article-item__footer m-top10"> |
|||
<text class="article-views f-24 col-8">{{ item.show_views }}次浏览</text> |
|||
</view> |
|||
</block> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</template> |
|||
|
|||
<script> |
|||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue' |
|||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins' |
|||
import * as ArticleApi from '@/api/article' |
|||
import * as CategoryApi from '@/api/article/category' |
|||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app' |
|||
|
|||
const pageSize = 15 |
|||
|
|||
export default { |
|||
components: { |
|||
MescrollBody |
|||
}, |
|||
mixins: [MescrollMixin], |
|||
data() { |
|||
return { |
|||
// 选项卡列表 |
|||
tabList: [], |
|||
// 当前选项 |
|||
curTab: 0, |
|||
// 文章列表 |
|||
articleList: getEmptyPaginateObj(), |
|||
// 上拉加载配置 |
|||
upOption: { |
|||
// 首次自动执行 |
|||
auto: true, |
|||
// 每页数据的数量; 默认10 |
|||
page: { size: pageSize }, |
|||
// 数量要大于3条才显示无更多数据 |
|||
noMoreSize: 3, |
|||
} |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面加载 |
|||
*/ |
|||
onLoad(options) { |
|||
const app = this |
|||
// 获取文章分类数据 |
|||
app.getCategoryList(options.categoryId) |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
/** |
|||
* 上拉加载的回调 (页面初始化时也会执行一次) |
|||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 |
|||
* @param {Object} page |
|||
*/ |
|||
upCallback(page) { |
|||
const app = this |
|||
// 设置列表数据 |
|||
app.getArticleList(page.num) |
|||
.then(list => { |
|||
const curPageLen = list.data.length |
|||
const totalSize = list.data.total |
|||
app.mescroll.endBySize(curPageLen, totalSize) |
|||
}) |
|||
.catch(() => app.mescroll.endErr()) |
|||
}, |
|||
|
|||
// 获取文章分类数据 |
|||
getCategoryList(categoryId) { |
|||
CategoryApi.list().then(result => { |
|||
this.setTabList(result.data.list, categoryId) |
|||
}) |
|||
}, |
|||
|
|||
// 设置选项卡数据 |
|||
setTabList(categoryList, categoryId) { |
|||
const app = this |
|||
app.tabList = [{ value: 0, name: '全部' }] |
|||
categoryList.forEach(item => { |
|||
app.tabList.push({ value: item.category_id, name: item.name }) |
|||
}) |
|||
if (categoryId > 0) { |
|||
const findIndex = app.tabList.findIndex(item => item.value == categoryId) |
|||
app.curTab = findIndex > -1 ? findIndex : 0 |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 获取文章列表 |
|||
* @param {Number} pageNo 页码 |
|||
*/ |
|||
getArticleList(pageNo = 1) { |
|||
const app = this |
|||
return new Promise((resolve, reject) => { |
|||
ArticleApi.list({ categoryId: app.getTabValue(), page: pageNo }, { load: false }) |
|||
.then(result => { |
|||
// 合并新数据 |
|||
const newList = result.data.list |
|||
app.articleList.data = getMoreListData(newList, app.articleList, pageNo) |
|||
resolve(newList) |
|||
}) |
|||
.catch(reject) |
|||
}) |
|||
}, |
|||
|
|||
// 切换标签项 |
|||
onChangeTab(index) { |
|||
// 设置当前选中的标签 |
|||
this.curTab = index |
|||
// 刷新订单列表 |
|||
this.onRefreshList() |
|||
}, |
|||
|
|||
// 获取当前标签项的值 |
|||
getTabValue() { |
|||
const app = this |
|||
return app.tabList.length ? app.tabList[app.curTab].value : 0 |
|||
}, |
|||
|
|||
// 刷新列表数据 |
|||
onRefreshList() { |
|||
this.articleList = getEmptyPaginateObj() |
|||
setTimeout(() => this.mescroll.resetUpScroll(), 120) |
|||
}, |
|||
|
|||
// 跳转文章详情页 |
|||
onTargetDetail(articleId) { |
|||
this.$navTo('pages/article/detail', { articleId }) |
|||
} |
|||
|
|||
}, |
|||
|
|||
/** |
|||
* 分享当前页面 |
|||
*/ |
|||
onShareAppMessage() { |
|||
return { |
|||
title: '文章首页', |
|||
path: "/pages/article/index?" + this.$getShareUrlParams() |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 分享到朋友圈 |
|||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta) |
|||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html |
|||
*/ |
|||
onShareTimeline() { |
|||
return { |
|||
title: '文章首页', |
|||
path: "/pages/article/index?" + this.$getShareUrlParams() |
|||
} |
|||
} |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.container { |
|||
min-height: 100vh; |
|||
} |
|||
|
|||
// 文章列表 |
|||
.article-list { |
|||
padding-top: 20rpx; |
|||
line-height: 1; |
|||
background: #f7f7f7; |
|||
} |
|||
|
|||
|
|||
.article-item { |
|||
margin-bottom: 20rpx; |
|||
padding: 30rpx; |
|||
background: #fff; |
|||
|
|||
&:last-child { |
|||
margin-bottom: 0; |
|||
} |
|||
|
|||
.article-item__title { |
|||
max-height: 74rpx; |
|||
font-size: 28rpx; |
|||
line-height: 38rpx; |
|||
color: #333; |
|||
} |
|||
|
|||
.article-item__image .image { |
|||
display: block; |
|||
} |
|||
} |
|||
|
|||
// 小图模式 |
|||
.show-type__10 { |
|||
display: flex; |
|||
|
|||
.article-item__left { |
|||
padding-right: 20rpx; |
|||
} |
|||
|
|||
.article-item__title { |
|||
// min-height: 72rpx; |
|||
} |
|||
|
|||
.article-item__image .image { |
|||
width: 240rpx; |
|||
} |
|||
} |
|||
|
|||
// 大图模式 |
|||
.show-type__20 .article-item__image .image { |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue