This commit is contained in:
2025-06-16 10:09:19 +08:00
commit 7a066b3026
428 changed files with 50385 additions and 0 deletions

22
pages/const/about.vue Normal file
View File

@ -0,0 +1,22 @@
<template>
<view>
关于我们页面
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

22
pages/const/help.vue Normal file
View File

@ -0,0 +1,22 @@
<template>
<view>
帮助页面
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

22
pages/const/license.vue Normal file
View File

@ -0,0 +1,22 @@
<template>
<view>
用户条例
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

89
pages/const/more.vue Normal file
View File

@ -0,0 +1,89 @@
<template>
<view class="flex flex-column">
<view class="center-list" @click="goHelp">
<view class="center-list-item">
<text class="list-text">帮助中心</text>
</view>
</view>
<view class="center-list" @click="goAbout">
<view class="center-list-item">
<text class="list-text">关于我们</text>
</view>
</view>
<view class="center-list">
<view class="center-list-item">
<text class="list-text">通知提醒</text>
</view>
</view>
<view class="center-list" @click="goLicense">
<view class="center-list-item">
<text class="list-text">用户协议</text>
</view>
</view>
<view class="center-list" @click="goPrivacy">
<view class="center-list-item">
<text class="list-text">隐私政策</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
goHelp() {
uni.navigateTo({
url: "/pages/const/help"
})
},
goAbout() {
uni.navigateTo({
url: "/pages/const/about"
})
},
goLicense() {
uni.navigateTo({
url: "/pages/const/license"
})
},
goPrivacy() {
uni.navigateTo({
url: "/pages/const/privacy"
})
},
}
}
</script>
<style scoped>
.center-list {
flex-direction: column;
background-color: #FFFFFF;
margin-top: 20upx;
width: 690upx;
margin-left: 30upx;
margin-right: 30upx;
}
.center-list-item {
height: 90upx;
width: 690upx;
flex-direction: row;
padding: 0upx 20upx;
border-radius: 10upx;
box-shadow: #55555555 1rpx 0rpx 2rpx 0rpx;
}
.list-text {
height: 90upx;
line-height: 90upx;
font-size: 34upx;
color: #555;
flex: 1;
}
</style>

22
pages/const/privacy.vue Normal file
View File

@ -0,0 +1,22 @@
<template>
<view>
隐私政策
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

299
pages/index/index.vue Normal file
View File

@ -0,0 +1,299 @@
<template>
<view class="flex flex-column" style="width: 100vw;">
<view style="height: 300rpx;" v-if="bannerList.length > 0">
<swiper interval="5000" :autoplay="true" :circular="true">
<swiper-item class="flex" v-for="(item, index) in bannerList" :key="index">
<image :src="item.image" mode="aspectFill" style="height: 300rpx;width: 100%;"></image>
</swiper-item>
</swiper>
</view>
<i-loading v-if="loading" />
<view class="icon-container">
<view class="icon-block" @click="gotoUserShare">
<image src="/static/images/icon-photograph.png" alt="随手拍" class="icon-img"></image>
<text class="icon-text">随手拍</text>
</view>
<view class="icon-block" @click="gotoShop">
<image src="/static/images/icon-store.png" alt="" class="icon-img"></image>
<text class="icon-text">积分商城</text>
</view>
<view class="icon-block" @click="gotoTutorial">
<image src="/static/images/icon-guide.png" alt="办事指南" class="icon-img"></image>
<text class="icon-text">办事指南</text>
</view>
<view class="icon-block" @click="gotoThumbsUp">
<image src="/static/images/icon-city.png" alt="" class="icon-img"></image>
<text class="icon-text">点赞城市</text>
</view>
</view>
<view class="flex flex-column flex-1">
<view>
<scroll-view class="flex-1" :scroll-y="true" :refresher-enabled="true"
:refresher-triggered="refresh" @refresherrefresh="refreshData" @scrolltolower="loadData">
<view class="px-2">
<i-news-list :resdata="newsList" />
</view>
<uni-load-more :status="more_status" @clickLoadMore="loadData"></uni-load-more>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
import {
TaAjax
} from '@/common/ajax';
import {
friendlyDate
} from '@/common/util';
export default {
computed: {
more_status() {
if (this.finish) {
return 'no-more';
} else if (this.loading) {
return 'loading';
} else {
return 'more';
}
},
},
data() {
return {
bannerList: [],
tabBars: [{
id: '',
name: '全部'
}],
tabIndex: 0,
newsList: [],
curPage: 1,
loading: false,
refresh: false,
finish: false
}
},
created() {
TaAjax.get('/cms/api.category/index').then((res) => {
const data = res.data;
data.forEach((item) => {
this.tabBars.push(item)
})
}).finally(() => {
this.loading = false;
})
TaAjax.get('/cms/api.banner/index').then((res) => {
const data = res.data;
data.forEach((item) => {
this.bannerList.push(item)
})
})
},
onReady() {
this.refreshData();
},
methods: {
changeTab(index) {
this.tabIndex = index
},
loadData() {
if (this.refresh) {
this.newsList.length = 0;
this.finish = false;
}
if (this.finish) {
return;
}
if (this.loading) {
return;
}
TaAjax.get('/cms/api.article/index', {
cid: this.tabBars[this.tabIndex].id,
page: this.curPage
}).then((result) => {
const data = result.data;
const data_list = data.data.map((news) => {
news.publish_at = friendlyDate(new Date(news.publish_at.replace(/\-/g, '/'))
.getTime())
news.imgs = news.thumb ? [news.thumb] : [];
return news;
});
if (this.refresh) {
this.newsList.length = 0;
}
this.newsList = this.newsList.concat(data_list);
this.finish = data.total <= this.newsList.length;
this.curPage++;
}).catch((e) => {
console.warn(e)
if (this.newsList.length == 0) {
this.finish = true;
}
}).finally(() => {
this.refresh = false;
this.loading = false;
});
},
refreshData() {
this.finish = false;
this.refresh = true;
this.curPage = 1;
this.loadData();
},
swiperChange(e) {
this.tabIndex = e.detail.current
this.refreshData()
},
gotoShop() {
uni.navigateTo({
url: "/pages/points-mall/index",
})
},
gotoTutorial() {
uni.switchTab({
url: "/pages/tutorial/tutorial"
})
},
gotoUserShare() {
uni.navigateTo({
url: "/pages/user-share/user-share"
})
},
gotoThumbsUp() {
uni.navigateTo({
url: "/pages/thumb/thumb"
})
},
}
}
</script>
<style>
page {
width: 100%;
min-height: 100%;
display: flex;
}
.tabs {
flex: 1;
flex-direction: column;
overflow: hidden;
background-color: #ffffff;
/* #ifdef MP-ALIPAY || MP-BAIDU */
height: 100vh;
/* #endif */
}
.tab-bar {
position: sticky;
top: 0;
height: 42px;
flex-direction: row;
white-space: nowrap;
}
/* #ifndef APP-NVUE */
.tab-bar ::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
/* #endif */
.scroll-view-indicator {
position: relative;
height: 2px;
background-color: transparent;
}
.scroll-view-underline {
position: absolute;
top: 0;
bottom: 0;
width: 0;
background-color: #007AFF;
}
.scroll-view-animation {
transition-duration: 0.2s;
transition-property: left;
}
.tab-bar-line {
height: 1px;
background-color: #cccccc;
}
.tab-box {
flex: 1;
}
.uni-tab-item {
/* #ifndef APP-PLUS */
display: inline-block;
/* #endif */
flex-wrap: nowrap;
padding-left: 20px;
padding-right: 20px;
}
.uni-tab-item-title {
color: #555;
font-size: 15px;
height: 40px;
line-height: 40px;
flex-wrap: nowrap;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
}
.uni-tab-item-title-active {
color: #007AFF;
}
.swiper-item {
flex: 1;
flex-direction: column;
}
.page-item {
flex: 1;
flex-direction: row;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.icon-container {
height: 160rpx;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.icon-block {
display: flex;
flex-direction: column;
flex: 1;
justify-content: center;
align-items: center;
gap: 12rpx;
}
.icon-img {
border-radius:16rpx;
height: 100rpx;
width: 100rpx;
}
.icon-text {
font-size: 24rpx;
color: #555;
}
</style>

90
pages/message/message.vue Normal file
View File

@ -0,0 +1,90 @@
<template>
<view class="flex flex-column" style="width:100vw;height: 100vh;">
<i-loading v-if="loading" />
<view class="flex flex-column flex-1">
<scroll-view class="flex-1" :scroll-y="true" :refresher-enabled="true"
:refresher-triggered="refresh" @refresherrefresh="refreshData" @scrolltolower="loadData">
<view class="px-2">
<i-message-list :resdata="messageList" />
</view>
<uni-load-more :status="more_status" @clickLoadMore="loadData"></uni-load-more>
</scroll-view>
</view>
</view>
</template>
<script>
import {
TaAjax
} from '@/common/ajax';
import {
friendlyDate
} from '@/common/util';
export default {
computed: {
more_status() {
if (this.finish) {
return 'no-more';
} else if (this.loading) {
return 'loading';
} else {
return 'more';
}
},
},
data() {
return {
messageList: [],
curPage: 1,
loading: true,
refresh: true,
finish: false
}
},
methods: {
loadData() {
if (this.refresh) {
this.messageList.length = 0;
this.finish = false;
}
if (this.finish) {
return;
}
TaAjax.get('/custom/api.auth.Message/index', {
page: this.curPage
}).then((result) => {
const data = result.data;
const data_list = data.data.map((item) => {
item.create_at = friendlyDate(new Date(item.create_at.replace(/\-/g, '/'))
.getTime())
return item;
});
if (this.refresh) {
this.messageList.length = 0;
}
this.messageList = this.messageList.concat(data_list);
this.finish = data.total <= this.messageList.length;
this.curPage++;
}).catch((e) => {
console.warn(e)
if (this.messageList.length == 0) {
this.finish = true;
}
}).finally(() => {
this.refresh = false;
this.loading = false;
});
},
refreshData() {
this.finish = false;
this.refresh = true;
this.curPage = 1;
this.loadData();
},
}
}
</script>
<style>
</style>

78
pages/news/detail.vue Normal file
View File

@ -0,0 +1,78 @@
<template>
<view class="px-3">
<i-loading v-if="loading" />
<view class="mt-2 font40 line15">{{newsInfo.title}}</view>
<view class="bg-hover-light p-2 mt-2 rounded flex align-center justify-between flex-wrap font24">
<view class="flex align-center">
<uni-icons type="contact" size="16" color="#cccccc"></uni-icons>
<text class="font24 text-muted">{{newsInfo.author}}</text>
</view>
<view class="flex align-center">
<uni-icons type="eye" size="16" color="#cccccc"></uni-icons>
<text class="font24 text-muted">{{newsInfo.view_count}}</text>
</view>
<view class="flex align-center">
<uni-icons type="calendar" size="16" color="#cccccc"></uni-icons>
<text class="font24 text-muted">{{newsInfo.publish_at}}</text>
</view>
</view>
<view class="mt-2">
<u-parse :content="content" @preview="preview" @navigate="navigate"></u-parse>
</view>
</view>
</template>
<script>
import { friendlyDate } from '../../common/util';
import {
TaAjax
} from '@/common/ajax'
export default {
data() {
return {
id: 0,
content: "",
newsInfo: {
title: "",
from: "",
source: "",
publish_at: "",
view_count: 0,
},
loading: true
}
},
onLoad(params) {
this.id = params.id
this.loading = true;
TaAjax.get('/cms/api.article/info', {
id: this.id
}).then((response) => {
const data = response.data;
this.content = data.content;
uni.setNavigationBarTitle({
title: data.title
});
data.publish_at = friendlyDate((new Date(data.publish_at.replace(/\-/g, '/')).getTime()))
this.newsInfo = data;
}).catch((e) => {
console.warn(e)
}).finally(() => {
this.loading = false;
})
},
methods: {
preview(src, e) {
// do something
},
navigate(href, e) {
// do something
},
},
}
</script>
<style>
</style>

161
pages/points-mall/buy.vue Normal file
View File

@ -0,0 +1,161 @@
<template>
<view >
<i-loading v-if="loading || address_loading"></i-loading>
<view class="flex align-center justify-center bg-white p-3" @click="toAddress" v-if="!address_id">
<view class="text-center">
<uni-icons type="plusempty" size="20" color="#999999"></uni-icons>
<view class="text-muted font28 mt-2">请选择收货地址</view>
</view>
</view>
<view class="bg-white p-3 flex align-center" @click="toAddress" v-else>
<uni-icons type="location" size="20" color="#333333"></uni-icons>
<view class="flex-1 mx-2">
<view class="flex align-center font32">
<text>{{address.user_name}}</text>
<text class="ml-3">{{address.user_phone}}</text>
</view>
<view class="mt-1 font30 line15">{{address.region_prov}}{{address.region_city}}{{address.region_area}}{{address.region_addr}}</view>
</view>
<uni-icons type="right" size="16" color="#999999"></uni-icons>
</view>
<view class=" mt-2 bg-white">
<view class="flex align-center justify-between p-3 border-bottom">
<text class="font28 text-muted">订单编号</text>
<view class="">{{order.order_no}}</view>
</view>
</view>
<view class=" mt-2 bg-white">
<view class="flex align-center justify-between p-3 border-bottom">
<text class="font28 text-muted">商品积分</text>
<view class="cny_jf font-weight-bold">{{order.amount_goods}}</view>
</view>
</view>
<view class="mt-2 bg-white p-3" v-if="false">
<view class="font30 mr-2">备注信息</view>
<textarea placeholder="请输入备注信息" class="font30 mt-2 w-100" style="height: 100rpx;"></textarea>
</view>
<view class="cu-tabbar-height"></view>
<view class="fixed-bottom bg-white py-2 border-top">
<view class="flex align-center justify-between px-3">
<view class="flex align-center font32">
<text class="text-muted">消耗</text>
<view class="cny_jf font-weight-bold">{{order.amount_total}}</view>
</view>
<view class="bg-danger text-white px-4 rounded-circle py-2 font30" @click="toPay">立即兑换</view>
</view>
</view>
</view>
</template>
<script>
import { TaAjax } from '../../common/ajax'
export default {
data() {
return {
address_loading: false,
address_id: 0,
address: {},
loading: false,
order_no: "",
order: {},
}
},
onLoad(e) {
this.order_no = e.order_no
if (!this.order_no) {
uni.showToast({
title: '参数错误',
icon: 'none',
complete() {
uni.navigateBack()
}
})
}
this.address_id = e.address_id
if (this.address_id) {
this.loadAddress()
}
this.loadData()
},
methods: {
loadData() {
this.loading = true
TaAjax.get('/points_mall/api.auth.order/get', {
order_no: this.order_no,
}).then(res => {
const data = res.data
this.order = data.list[0]
}).finally(() => {
this.loading = false
})
},
loadAddress() {
this.address_loading = true
TaAjax.get('/points_mall/api.auth.address/info', {
id: this.address_id,
}).then(res => {
this.address = res.data
}).finally(() => {
this.address_loading = false
})
},
toPay(){
if (!this.address_id) {
return uni.showToast({
title: '请选择收货地址',
icon: 'none',
})
}
uni.showLoading({
title: '兑换中',
})
TaAjax.post('/points_mall/api.auth.order/perfect', {
order_no: this.order_no,
address_id: this.address_id,
}).then(res => {
if (res.code == 1) {
TaAjax.post('/points_mall/api.auth.order/payment', {
order_no: this.order_no,
}).then(payRes => {
if (payRes.code == 1) {
uni.hideLoading()
uni.showToast({
title: "兑换成功",
icon: 'success',
})
} else {
uni.hideLoading()
uni.showToast({
title: payRes.info,
icon: 'error',
})
}
})
} else {
uni.hideLoading()
uni.showToast({
title: res.info,
icon: 'error',
})
}
}).catch(err => {
uni.hideLoading()
uni.showToast({
title: "网络异常",
icon: 'none',
})
})
},
toAddress(){
uni.redirectTo({
url:'/pages/user/address?order_no='+this.order_no
})
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,111 @@
<template>
<view>
<i-swiper :resdata="piclist" :width="750" :height="750" :round='false' />
<view class="bg-white p-3">
<view class="flex align-center">
<!-- <text class="d-inline-block bg-danger font20 text-white px-1 line2 rounded mr-1">秒杀</text> -->
<view class="flex-1 text-ellipsis-1 font32">{{goodsInfo.name}}</view>
</view>
<view class=" flex align-end mt-2">
<view class="text-danger">
<text class="cny_jf">{{goodsInfo.price_selling}}</text>
</view>
<view class="font24 text-through cny ml-2 text-muted">{{goodsInfo.price_market}}</view>
</view>
</view>
<view class="mt-2 bg-white p-3">
<view class="font32 font-weight-bold">图文详情</view>
<i-spread width="690rpx" height="2000rpx" :isShrink="true">
<u-parse :content="goodsInfo.content" @preview="preview" @navigate="navigate"></u-parse>
</i-spread>
</view>
<view class="cu-tabbar-height"></view>
<view class="bg-white fixed-bottom">
<view class=" px-2 py-1 border-top flex align-center">
<view class="flex-1 flex align-center ">
<view class="text-center flex-1" @click="toIndex">
<uni-icons type="home" size="20" color="#333333"></uni-icons>
<view class="font24">首页</view>
</view>
</view>
<view class="flex-2 flex align-center ml-2">
<view class="bg-danger text-white text-center py-2 font30 line15 rounded-circle flex-1" @click="toEvaluate">立即兑换</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { TaAjax } from '../../common/ajax';
export default {
data() {
return {
code: 0,
goodsInfo: {},
piclist: [],
}
},
onLoad(e) {
this.code = e.code
if (!this.code) {
uni.showToast({
title: '参数错误',
icon: 'none',
duration: 2000,
complete() {
uni.navigateBack({
delta: 1,
})
}
})
}
},
onShow() {
this.loadData()
},
methods: {
loadData() {
TaAjax.get('/points_mall/api.goods/get', {
code: this.code
}).then((result) => {
const data = result.data;
const data_list = data.list;
this.goodsInfo = data_list[0];
this.piclist = this.goodsInfo.slider
}).catch((e) => {
console.warn(e)
}).finally(() => {
});
},
toIndex(){
uni.switchTab({
url:'/pages/points-mall/index'
})
},
toEvaluate(){
uni.showLoading({
title: '加载中',
})
TaAjax.post('/points_mall/api.auth.order/add_goods', {
code: this.code
}).then((result) => {
const data = result.data;
const order_no = data.order_no;
uni.navigateTo({
url:'/pages/points-mall/buy?order_no='+order_no
})
}).finally(() => {
uni.hideLoading()
});
},
}
}
</script>
<style scoped>
.bg-light-danger {
background-color: #fad8d6;
}
</style>

View File

@ -0,0 +1,82 @@
<template>
<view class="flex flex-column" style="width:100vw;height: 100vh;">
<i-loading v-if="loading" />
<view class="flex flex-column flex-1">
<scroll-view class="flex-1" :scroll-y="true" :refresher-enabled="true"
:refresher-triggered="refresh" @refresherrefresh="refreshData" @scrolltolower="loadData">
<view class="px-2">
<i-list-top :resdata="goodsList"></i-list-top>
</view>
<uni-load-more :status="more_status" @clickLoadMore="loadData"></uni-load-more>
</scroll-view>
</view>
</view>
</template>
<script>
import { TaAjax } from '../../common/ajax';
export default {
computed: {
more_status() {
if (this.finish) {
return 'no-more';
} else if (this.loading) {
return 'loading';
} else {
return 'more';
}
},
},
data() {
return {
goodsList: [],
curPage: 1,
loading: true,
refresh: true,
finish: false
}
},
methods: {
loadData() {
if (this.refresh) {
this.goodsList.length = 0;
this.finish = false;
}
if (this.finish) {
return;
}
this.loading = true;
TaAjax.get('/points_mall/api.goods/get', {
page: this.curPage
}).then((result) => {
const data = result.data;
const data_list = data.list;
if (this.refresh) {
this.goodsList.length = 0;
}
this.goodsList = this.goodsList.concat(data_list);
this.finish = data.total <= this.goodsList.length;
this.curPage++;
}).catch((e) => {
console.warn(e)
if (this.goodsList.length == 0) {
this.finish = true;
}
}).finally(() => {
this.refresh = false;
this.loading = false;
});
},
refreshData() {
this.finish = false;
this.refresh = true;
this.curPage = 1;
this.loadData();
},
}
}
</script>
<style>
</style>

75
pages/thumb/detail.vue Normal file
View File

@ -0,0 +1,75 @@
<template>
<view class="flex flex-column" style="width:100vw;height: 100vh;">
<i-loading v-if="loading"></i-loading>
<view class="bg-white px-3 pb-3 mx-2 rounded-lg mt-2">
<view class="pt-3 font30">
<view class="text-muted">点赞内容</view>
<view class="mt-2">{{info.content}}</view>
</view>
<view class="flex align-center justify-between pt-3 font30">
<view class="text-muted">点赞时间</view>
<view>{{info.create_at}}</view>
</view>
<view class="pt-3 font30" v-if="info.imgs_arr.length > 0">
<view class="text-muted">图片</view>
<view class="mt-2">
<image v-for="(item, index) in info.imgs_arr" :key="index" :src="item" mode="aspectFill" class="rounded-lg" style="width: 100px;height: 100px;margin-right: 10px;" />
</view>
</view>
</view>
</view>
</template>
<script>
import { TaCache } from '../../common/cache';
import { TaAjax } from '@/common/ajax'
export default {
onLoad(options) {
const userInfo = TaCache.get('auth.user');
if (!userInfo) {
this.login = false
} else {
this.login = true
}
this.id = options.id
if (!this.id) {
uni.showToast({
title: '缺少参数',
icon: 'none'
})
return uni.navigateBack()
}
this.loadInfo()
},
data() {
return {
id: 0,
loading: false,
login: false,
info: {},
}
},
methods: {
loadInfo() {
this.loading = true
TaAjax.get((this.login ? '/cms/api.auth.Thumb/info?id=' : '/cms/api.Thumb/info?id=') + this.id).then(res => {
console.log(res)
this.info = res.data
}).catch(err => {
uni.showToast({
title: err.info,
icon: 'error',
})
uni.navigateBack()
}).finally(() => {
this.loading = false
})
}
}
}
</script>
<style>
</style>

102
pages/thumb/list.vue Normal file
View File

@ -0,0 +1,102 @@
<template>
<view class="flex flex-column flex-1" style="height: 100vh;">
<i-loading v-if="loading" />
<view class="flex flex-column flex-1">
<scroll-view class="flex-1" :scroll-y="true" :refresher-enabled="true"
:refresher-triggered="refresh" @refresherrefresh="refreshData" @scrolltolower="loadData">
<view class="px-2">
<i-thumb-list :resdata="shareList" />
</view>
<uni-load-more :status="more_status" @clickLoadMore="loadData"></uni-load-more>
</scroll-view>
</view>
</view>
</template>
<script>
import { TaCache } from '@/common/cache';
import {
TaAjax
} from '@/common/ajax';
import {
friendlyDate
} from '@/common/util';
export default {
computed: {
more_status() {
if (this.finish) {
return 'no-more';
} else if (this.loading) {
return 'loading';
} else {
return 'more';
}
},
},
data() {
return {
shareList: [],
curPage: 1,
loading: true,
refresh: true,
finish: false,
login: false
}
},
onLoad() {
const userInfo = TaCache.get('auth.user');
if (!userInfo) {
this.login = false
} else {
this.login = true
}
},
methods: {
loadData() {
if (this.refresh) {
this.shareList.length = 0;
this.finish = false;
}
if (this.finish) {
return;
}
TaAjax.get(this.login ? '/cms/api.auth.Thumb/index' : '/cms/api.Thumb/index', {
page: this.curPage
}).then((result) => {
const data = result.data;
const data_list = data.data.map((share) => {
share.create_at = friendlyDate(new Date(share.publish_at.replace(/\-/g, '/'))
.getTime());
share.imgs = share.imgs_arr;
return share;
});
if (this.refresh) {
this.shareList.length = 0;
}
this.shareList = this.shareList.concat(data_list);
this.finish = data.total <= this.shareList.length;
this.curPage++;
}).catch((e) => {
console.warn(e)
if (this.shareList.length == 0) {
this.finish = true;
}
}).finally(() => {
this.refresh = false;
this.loading = false;
});
},
refreshData() {
this.finish = false;
this.refresh = true;
this.curPage = 1;
this.loadData();
},
}
}
</script>
<style>
</style>

129
pages/thumb/thumb.vue Normal file
View File

@ -0,0 +1,129 @@
<template>
<view class="flex flex-column" style="width:100vw;height: 100vh; background-color: #F5F6F8;">
<view class="bg-white mt-2 p-2 rounded-lg" style="padding-bottom: 200rpx;">
<view class="flex-1 pt-3" style="color: #666666;">点赞城市内容</view>
<view class="border border-light rounded py-3 flex align-center justify-between" style="height: 200rpx;">
<textarea v-model="form.content" autoHeight class="flex-1 font28" placeholder="点赞城市内容" />
</view>
<view class="flex-1 py-3">相关图片</view>
<view class="flex py-3 mb-6">
<div class="flex flex-wrap w-25 position-relative" v-for="(item,index) in img_array" :key='index'>
<img class="img-add" :src="item" @click="previewImage(index)" alt=""/>
<img class='img-delete position-absolute' src='/static/images/delete.png' @click='deleteImage(index)'>
</div>
<div class="flex flex-wrap w-25" @click="chooseImages()">
<img class='img-add' src="/static/images/addImage.png" alt="">
</div>
</view>
</view>
<view class="fixed-bottom border-top bg-white py-2 px-3">
<view class="bg-danger py-3 font30 text-center text-white shadow rounded-circle" @click="onSubmit">
立即提交
</view>
</view>
</view>
</template>
<script>
import { TaCache } from '@/common/cache';
import {
TaAjax, TaPost, baseUrl
} from '@/common/ajax';
export default {
data() {
return {
form: {
title: "点赞城市",
content: "",
imgs: "",
},
img_array: [],
}
},
created() {
const that = this;
const userInfo = TaCache.get('auth.user');
if (!userInfo) {
uni.navigateTo({
url: "/pages/user/login"
})
}
},
methods: {
chooseImages() {
const that = this;
uni.chooseMedia({
mediaType: ['image', 'video'],
sourceType: ['album', 'camera'],
sizeType: ['original'],
success(res) {
for(let i=0;i<res.tempFiles.length;i++){
const tempFilePath = res.tempFiles[i].tempFilePath
const loadingId = uni.showLoading({
title: '上传中...',
mask: true,
})
uni.uploadFile({
url: baseUrl + '/custom/api.Upload/file',
filePath: tempFilePath,
name: 'file',
success(res) {
const responseStr = res.data;
const response = JSON.parse(res.data);
const data = response.data;
const url = data.url;
that.img_array.push(url);
},
complete() {
uni.hideLoading(loadingId)
},
})
}
},
})
},
previewImage(idx = 0) {
uni.previewImage({
urls: this.img_array,
current: idx,
loop: true,
})
},
deleteImage(idx) {
this.img_array.splice(idx, 1)
},
onSubmit() {
this.form.images = this.img_array.join("|")
TaPost('/cms/api.auth.Thumb/add', this.form).then((result) => {
if (result.code == 0) {
return uni.showToast({
icon: 'error',
title: result.info,
})
}
const id = result.data
uni.switchTab({
url: "/pages/index/index"
})
return uni.showToast({
icon: 'success',
title: result.info,
})
})
},
}
}
</script>
<style scoped>
.img-add {
width: 180rpx;
height: 180rpx;
}
.img-delete {
top: 0;
right: 0;
height: 48rpx;
width: 48rpx;
}
</style>

64
pages/tutorial/detail.vue Normal file
View File

@ -0,0 +1,64 @@
<template>
<view class="flex flex-column" style="width:100vw;height: 100vh;">
<i-loading v-if="loading" />
<view class="mt-2 font40 line15">{{newsInfo.title}}</view>
<scroll-view>
<view class="mt-2">
<u-parse :content="newsInfo.content" @preview="preview" @navigate="navigate"></u-parse>
</view>
</scroll-view>
</view>
</template>
<script>
import { friendlyDate } from '../../common/util';
import {
TaAjax
} from '@/common/ajax'
export default {
data() {
return {
id: 0,
newsInfo: {
title: "",
content: "",
material: "",
method: "",
view_count: 0,
},
loading: true
}
},
onLoad(params) {
this.id = params.id
this.loading = true;
TaAjax.get('/cms/api.tutorial/info', {
id: this.id
}).then((response) => {
if (response.code == 0) {
uni.showToast({
title: response.info
})
return uni.navigateBack()
}
const data = response.data;
uni.setNavigationBarTitle({
title: data.title
});
data.create_at = friendlyDate((new Date(data.create_at.replace(/\-/g, '/')).getTime()))
this.newsInfo = data;
}).catch((e) => {
console.warn(e)
}).finally(() => {
this.loading = false;
})
},
methods: {
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,91 @@
<template>
<view class="flex flex-column" style="width:100vw;height: 100vh;">
<i-loading v-if="loading" />
<view class="flex flex-column flex-1">
<scroll-view class="flex-1" :scroll-y="true" :refresher-enabled="true"
:refresher-triggered="refresh" @refresherrefresh="refreshData" @scrolltolower="loadData">
<view class="px-2">
<i-tutorial-list :resdata="newsList" />
</view>
<uni-load-more :status="more_status" @clickLoadMore="loadData"></uni-load-more>
</scroll-view>
</view>
</view>
</template>
<script>
import {
TaAjax
} from '@/common/ajax';
import {
friendlyDate
} from '@/common/util';
export default {
computed: {
more_status() {
if (this.finish) {
return 'no-more';
} else if (this.loading) {
return 'loading';
} else {
return 'more';
}
},
},
data() {
return {
newsList: [],
curPage: 1,
loading: true,
refresh: true,
finish: false
}
},
methods: {
loadData() {
if (this.refresh) {
this.newsList.length = 0;
this.finish = false;
}
if (this.finish) {
return;
}
TaAjax.get('/cms/api.tutorial/index', {
page: this.curPage
}).then((result) => {
const data = result.data;
const data_list = data.data.map((news) => {
news.publish_at = friendlyDate(new Date(news.create_at.replace(/\-/g, '/'))
.getTime())
news.imgs = [];
return news;
});
if (this.refresh) {
this.newsList.length = 0;
}
this.newsList = this.newsList.concat(data_list);
this.finish = data.total <= this.newsList.length;
this.curPage++;
}).catch((e) => {
console.warn(e)
if (this.newsList.length == 0) {
this.finish = true;
}
}).finally(() => {
this.refresh = false;
this.loading = false;
});
},
refreshData() {
this.finish = false;
this.refresh = true;
this.curPage = 1;
this.loadData();
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,83 @@
<template>
<view class="flex flex-column" style="width:100vw;height: 100vh;">
<i-loading v-if="loading"></i-loading>
<view class="bg-white px-3 pb-3 mx-2 rounded-lg mt-2">
<view class="pt-3 font30">
<view class="text-muted">反馈内容</view>
<view class="mt-2">{{info.content}}</view>
</view>
<view class="pt-3 font30">
<view class="text-muted">反馈地址</view>
<view class="mt-2">{{info.ticket_region}} {{info.ticket_address}}</view>
</view>
<view class="flex align-center justify-between pt-3 font30">
<view class="text-muted">反馈地址</view>
<view>{{info.create_at}}</view>
</view>
<view class="pt-3 font30" v-if="info.imgs_arr.length > 0">
<view class="text-muted">图片</view>
<view class="mt-2">
<image v-for="(item, index) in info.imgs_arr" :key="index" :src="item" mode="aspectFill" class="rounded-lg" style="width: 100px;height: 100px;margin-right: 10px;" />
</view>
</view>
</view>
<view v-if="info.status == 1" class="bg-white px-3 pb-3 mx-2 rounded-lg mt-2">
<view class="pt-3 font30">
<view class="text-muted">处理记录</view>
<view class="mt-2">
<view v-for="(item, index) in info.logs" :key="index" class="flex flex-column justify-between border-bottom border-light py-2">
<view>处理时间{{item.create_at}}</view>
<view>{{item.content}}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { TaAjax } from '../../common/ajax'
export default {
onLoad(options) {
console.log(options)
this.id = options.id
if (!this.id) {
uni.showToast({
title: '缺少参数',
icon: 'none'
})
return uni.navigateBack()
}
this.loadInfo()
},
data() {
return {
id: 0,
loading: false,
info: {},
}
},
methods: {
loadInfo() {
this.loading = true
TaAjax.get('/ticket/api.auth.UserShare/info?id=' + this.id).then(res => {
console.log(res)
this.info = res.data
}).catch(err => {
uni.showToast({
title: err.info,
icon: 'error',
})
uni.navigateBack()
}).finally(() => {
this.loading = false
})
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,205 @@
<template>
<view class="flex flex-column" style="width:100vw;height: 100vh; background-color: #F5F6F8;">
<view class="flex flex-row align-center px-2 py-1" style="background-color: #FFF8D3; height: 56rpx;">
<image src="@/static/images/icon-warn.png" style="height: 24rpx; width: 24rpx;"></image>
<text style="color: #FFBE0E; font-size: 20rpx">随手拍简单高效的反馈并上传问题</text>
</view>
<view class="bg-white mt-2 p-2 rounded-lg" style="padding-bottom: 200rpx;">
<view class="flex-1" style="color: #666666;">问题类型</view>
<picker class="border-bottom border-light" :range="typeList" range-key="name" @change="handleTypeIdChange">
<view class="py-3 flex align-center justify-between">
<view class=" font28 flex align-center flex-1" v-if="type_name">{{type_name}}
</view>
<view class=" font28 text-light-black flex-1" v-else>请选择问题分类</view>
<uni-icons type="right" color="#cccccc" size="20"></uni-icons>
</view>
</picker>
<view class="flex-1 pt-3" style="color: #666666;">反馈内容</view>
<view class="border border-light rounded py-3 flex align-center justify-between" style="height: 200rpx;">
<textarea v-model="form.content" autoHeight class="flex-1 font28" placeholder="随手拍反馈内容" />
</view>
<view class="flex-1 pt-3">问题地址</view>
<pick-regions defaultRegion="511602" @getRegion="handleGetRegion">
<view class="py-3 flex align-center justify-between">
<view class=" font28 flex align-center flex-1" v-if="province">{{province}}{{city}}{{area}}</view>
<view class=" font28 text-light-black flex-1" v-else>省市区</view>
<uni-icons type="right" color="#cccccc" size="20"></uni-icons>
</view>
</pick-regions>
<view class="border rounded border-light py-3 flex align-center justify-between">
<textarea v-model="form.ticket_address" autoHeight class="flex-1 font28" placeholder="详细地址(例如**街**号**)" />
</view>
<view class="flex-1 py-3">联系方式</view>
<view class="flex align-center justify-between py-3 ">
<view class="flex-1 border-bottom border-light">
<input class="font28" focus placeholder="姓名" v-model="form.contact_name" />
</view>
<view class="flex-1 border-bottom border-light">
<input class="font28" type="number" placeholder="联系方式" v-model="form.contact_phone" />
</view>
</view>
<view class="flex-1 py-3">相关图片</view>
<view class="flex py-3 mb-6">
<div class="flex flex-wrap w-25 position-relative" v-for="(item,index) in img_array" :key='index'>
<img class="img-add" :src="item" @click="previewImage(index)" alt=""/>
<img class='img-delete position-absolute' src='/static/images/delete.png' @click='deleteImage(index)'>
</div>
<div class="flex flex-wrap w-25" @click="chooseImages()">
<img class='img-add' src="/static/images/addImage.png" alt="">
</div>
</view>
</view>
<view class="fixed-bottom border-top bg-white py-2 px-3">
<view class="bg-danger py-3 font30 text-center text-white shadow rounded-circle" @click="onSubmit">
立即提交
</view>
</view>
</view>
</template>
<script>
import { TaCache } from '../../common/cache';
import {
TaAjax, TaPost, baseUrl
} from '@/common/ajax';
export default {
data() {
return {
province: "四川省",
city: "广安市",
area: "广安区",
type_name: "",
form: {
type_id: 0,
title: "用户随手拍",
content: "",
contact_name: "",
contact_phone: "",
ticket_region: "四川省/广安市/广安区",
ticket_address: "",
imgs: "",
ticket_lat: null,
ticket_lng: null,
},
img_array: [],
typeList: [],
}
},
created() {
const that = this;
const userInfo = TaCache.get('auth.user');
if (!userInfo) {
uni.navigateTo({
url: "/pages/user/login"
})
}
uni.getLocation({
type: 'gcj02',
success(res) {
that.form.ticket_lat = res.latitude;
that.form.ticket_lng = res.longitude;
},
fail(err) {
console.warn(err)
}
})
},
onReady() {
this.getTypeList()
},
methods: {
getTypeList() {
TaAjax.get('/ticket/api.type/list').then((result) => {
const data = result.data;
this.typeList = data;
})
},
handleTypeIdChange(e) {
const index = e.detail.value;
const curType = this.typeList[index];
this.type_name = curType.name;
this.form.type_id = curType.id
},
handleGetRegion(region) {
this.province = region[0].name
this.city = region[1].name
this.area = region[2].name
this.form.ticket_region = `${this.province}/${this.city}/${this.area}`
},
chooseImages() {
const that = this;
uni.chooseMedia({
mediaType: ['image', 'video'],
sourceType: ['album', 'camera'],
sizeType: ['original'],
success(res) {
for(let i=0;i<res.tempFiles.length;i++){
const tempFilePath = res.tempFiles[i].tempFilePath
const loadingId = uni.showLoading({
title: '上传中...',
mask: true,
})
uni.uploadFile({
url: baseUrl + '/custom/api.Upload/file',
filePath: tempFilePath,
name: 'file',
success(res) {
const responseStr = res.data;
const response = JSON.parse(res.data);
const data = response.data;
const url = data.url;
that.img_array.push(url);
},
complete() {
uni.hideLoading(loadingId)
},
})
}
},
})
},
previewImage(idx = 0) {
uni.previewImage({
urls: this.img_array,
current: idx,
loop: true,
})
},
deleteImage(idx) {
this.img_array.splice(idx, 1)
},
onSubmit() {
this.form.imgs = this.img_array.join("|")
TaPost('/ticket/api.auth.UserShare/add', this.form).then((result) => {
if (result.code == 0) {
return uni.showToast({
icon: 'error',
title: result.info,
})
}
const id = result.data
uni.switchTab({
url: "/pages/index/index"
})
return uni.showToast({
icon: 'success',
title: result.info,
})
})
},
}
}
</script>
<style scoped>
.img-add {
width: 180rpx;
height: 180rpx;
}
.img-delete {
top: 0;
right: 0;
height: 48rpx;
width: 48rpx;
}
</style>

63
pages/user/address.vue Normal file
View File

@ -0,0 +1,63 @@
<template>
<view class="px-2">
<i-loading v-if="loading"></i-loading>
<i-address-list :resdata="list" @click="toShow" @delete="doDelete" />
<button @click="addAddress" class="fixed-bottom">添加地址</button>
</view>
</template>
<script>
import { TaAjax } from '../../common/ajax'
export default {
data() {
return {
order_no: '',
loading: false,
list:[]
}
},
onLoad(e) {
this.order_no = e.order_no
},
onShow() {
this.loadData()
},
methods: {
loadData() {
this.loading = true
TaAjax.get('/points_mall/api.auth.address/list').then((resp) => {
const data = resp.data;
this.list = data
}).finally(() => {
this.loading = false
})
},
addAddress(e) {
uni.navigateTo({
url:'/pages/user/address_edit'
})
},
toShow(item){
if (this.order_no) {
uni.redirectTo({
url: '/pages/points-mall/buy?order_no=' + this.order_no + '&address_id=' + item.id
})
} else {
uni.navigateBack()
}
},
doDelete(item) {
TaAjax.post('/points_mall/api.auth.address/delete', {
id: item.id,
}).then((resp) => {
this.loadData()
})
},
}
}
</script>
<style>
</style>

141
pages/user/address_edit.vue Normal file
View File

@ -0,0 +1,141 @@
<template>
<view class="mx-2">
<view class="bg-white rounded-lg p-3 mt-3">
<view class="flex align-center justify-between border-bottom border-light py-3">
<view class="flex-1">
<input class="font28" focus placeholder="姓名" v-model="userName" />
</view>
<view class="flex-1">
<input class="font28" type="number" placeholder="联系方式" v-model="tel" />
</view>
</view>
<pick-regions :defaultRegion="defaultRegionCode" @getRegion="handleGetRegion">
<view class=" border-bottom border-light py-3 flex align-center justify-between">
<view class=" font28 flex align-center flex-1" v-if="province">{{province}}{{city}}{{district}}
</view>
<view class=" font28 text-light-black flex-1" v-else>省市区</view>
<uni-icons type="right" color="#cccccc" size="20"></uni-icons>
</view>
</pick-regions>
<view class=" border-bottom border-light py-3 flex align-center justify-between">
<textarea v-model="address" autoHeight class="flex-1 font28" placeholder="详细地址(例如**街**号**)" />
</view>
<view class="flex align-center justify-between">
<view class="flex align-center justify-between mt-2" @click="clear">
<uni-icons type="trash-filled" size="16" color="#cccccc"></uni-icons>
<text class="font24 ml-1 text-muted">清空当前信息</text>
</view>
</view>
</view>
<view class="fixed-bottom border-top bg-white py-2 px-3">
<view class="bg-danger py-3 font30 text-center text-white shadow rounded-circle" @click="toList">立即保存
</view>
</view>
<uni-popup ref="message" type="message">
<uni-popup-message :type="msgType" :message="messageText" :duration="2000"></uni-popup-message>
</uni-popup>
</view>
</template>
<script>
import {
TaAjax
} from '../../common/ajax'
export default {
data() {
return {
id: "",
province: null,
city: null,
district: null,
address: null,
userName: null,
tel: null,
// 弹出验证信息
message: null,
msgType: null,
messageText: null,
region: [],
defaultRegionCode: '110101'
}
},
onLoad(options) {
this.id = options.id || ""
},
methods: {
// 获取选择的地区
handleGetRegion(region) {
this.region = region
this.province = region[0].name
this.city = region[1].name
this.district = region[2].name
},
toList() {
if (this.userName == null || this.userName == '') {
this.msgType = "error"
this.messageText = `请输入联系人姓名`
this.$refs.message.open()
return
}
if (this.tel == null || this.tel == '') {
this.msgType = "error"
this.messageText = `请输入联系人手机号`
this.$refs.message.open()
return
}
if (!/^1[3456789]\d{9}$/.test(this.tel)) {
this.msgType = "error"
this.messageText = `请输入正确手机号`
this.$refs.message.open()
return
}
if (this.province == null || this.province == '') {
this.msgType = "error"
this.messageText = `请选择地址`
this.$refs.message.open()
return
}
const item = {
id: this.id,
user_name: this.userName,
user_phone: this.tel,
region_prov: this.province,
region_city: this.city,
region_area: this.district,
region_addr: this.address,
}
TaAjax.post("/points_mall/api.auth.address/save", item).then((res) => {
if (res.code == 1) {
this.msgType = "success"
this.messageText = `保存成功`
this.$refs.message.open()
setTimeout(() => {
uni.navigateBack()
}, 1000)
} else {
this.msgType = "error"
this.messageText = `保存失败`
this.$refs.message.open()
}
})
},
clear() {
this.address = '',
this.companyName = '',
this.userName = '',
this.tel = '',
this.province = '',
this.city = '',
this.district = ''
},
}
}
</script>
<style>
</style>

150
pages/user/bind/bind.vue Normal file
View File

@ -0,0 +1,150 @@
<template>
<view class="flex flex-column">
<view class="center-list">
<view class="center-list-item">
<text class="list-text">绑定手机</text>
<input class="list-input" v-model="form.phone">
</view>
</view>
<view class="center-list">
<view class="center-list-item">
<text class="list-text">手机验证码</text>
<view class="flex">
<input type="nickname" class="list-input" v-model="form.verify">
<button class="list-btn" :disabled="waiting" @click="getVerify">{{waiting ? `重新获取${waitingTime}s` : '获取验证码'}}</button>
</view>
</view>
</view>
<view style="margin-top:80rpx;" class="flex-center">
<button type="success" size="large" @click="doBind" customStyle="width:600rpx;height:100rpx">绑定</button>
</view>
</view>
</template>
<script>
import { TaAjax, TaPost } from '../../../common/ajax';
import { TaCache } from '../../../common/cache';
export default {
data() {
return {
form: {
phone: '',
verify: ''
},
waiting: false,
waitingTime: 60
}
},
methods: {
getVerify() {
TaAjax.post('/cms/api.auth.Bind/send', {
phone: this.form.phone
}).then(res => {
uni.showToast({
title: res.info,
icon: 'success',
})
this.form.verify = "123456"
this.waiting = true;
this.waitingTime = 60;
this.timer = setInterval(() => {
this.waitingTime--;
if (this.waitingTime <= 0) {
this.waiting = false;
clearInterval(this.timer);
}
}, 1000)
}).catch(err => {
uni.showToast({
title: "网络异常",
icon: 'none',
})
})
},
doBind() {
TaPost("/plugin-account/api.auth.center/bind", this.form).then((ret) => {
if (ret.code === 1) {
TaCache.set('auth.user', ret.data)
uni.showToast({
title: '绑定成功',
icon: 'success',
})
uni.navigateBack()
} else {
uni.showToast({
title: ret.info,
icon: 'none',
})
}
}).catch(err => {
console.log(err)
uni.showToast({
title: "网络异常",
icon: 'none',
})
})
},
}
}
</script>
<style>
page {
background-color: #f8f8f8;
}
.go-login-navigat-arrow {
font-size: 38upx;
color: #FFFFFF;
}
.login-title {
height: 150upx;
flex-direction: column;
align-items: center;
justify-content: center;
margin-left: 20upx;
}
.center-list {
flex-direction: column;
background-color: #FFFFFF;
margin-top: 20upx;
width: 690upx;
margin-left: 30upx;
margin-right: 30upx;
}
.center-list-item {
height: 90upx;
width: 690upx;
display: flex;
flex-direction: row;
padding: 0upx 20upx;
border-radius: 10upx;
box-shadow: #55555555 1rpx 0rpx 2rpx 0rpx;
justify-content: space-between;
}
.list-text {
flex-shrink: 0;
}
.list-text,.list-input {
height: 90upx;
line-height: 90upx;
font-size: 34upx;
color: #555;
}
.list-input {
text-align: right;
}
.list-btn {
font-size: 24rpx;
flex-shrink: 0;
height: 90upx;
line-height: 90upx;
}
</style>

203
pages/user/index.vue Normal file
View File

@ -0,0 +1,203 @@
<template>
<view class="flex flex-column">
<view class="logo" @click="goLogin" :hover-class="!isLogin ? 'logo-hover' : ''">
<image class="logo-img" :src="isLogin ? userInfo.extra.avatarUrl : avatarUrl"></image>
<view class="logo-title">
<text class="user-name">Hi{{userInfo.nickname || userInfo.extra.nickName}}</text>
</view>
</view>
<view class="center-list" @click="goUserInfo">
<view class="center-list-item">
<text class="list-text">账号管理</text>
</view>
</view>
<view class="center-list" @click="goUserUserShare">
<view class="center-list-item">
<text class="list-text">我的随手拍</text>
</view>
</view>
<view class="center-list" @click="goUserPoint">
<view class="center-list-item">
<text class="list-text">用户积分</text>
</view>
</view>
<view class="center-list" @click="goUserOrder">
<view class="center-list-item">
<text class="list-text">我的订单</text>
</view>
</view>
<view class="center-list" @click="goMessage">
<view class="center-list-item">
<text class="list-text">我的消息</text>
</view>
</view>
<view class="center-list" @click="goMorePage">
<view class="center-list-item">
<text class="list-text">更多设置</text>
</view>
</view>
</view>
</template>
<script>
import { TaCache } from '@/common/cache'
export default {
data() {
return {
avatarUrl: '/static/images/user-no-avatar.png',
isLogin: false,
userInfo: {
extra: {
avatarUrl: '/static/images/user-no-avatar.png',
nickname: '未登录',
},
},
}
},
onShow() {
const userInfo = TaCache.get('auth.user');
if (userInfo) {
this.userInfo = userInfo;
this.isLogin = true;
}
},
methods: {
goLogin() {
if (!this.isLogin) {
uni.navigateTo({
url: "/pages/user/login"
})
}
},
goUserInfo() {
if (!this.isLogin) {
uni.navigateTo({
url: "/pages/user/login"
})
} else {
uni.navigateTo({
url: "/pages/user/info",
})
}
},
goUserPoint() {
if (!this.isLogin) {
uni.navigateTo({
url: "/pages/user/login"
})
} else {
uni.navigateTo({
url: "/pages/user/point"
})
}
},
goUserUserShare() {
if (!this.isLogin) {
uni.navigateTo({
url: "/pages/user/login"
})
} else {
uni.navigateTo({
url: "/pages/user/user_share"
})
}
},
goMessage() {
uni.navigateTo({
url: "/pages/message/message",
})
},
goUserOrder() {
uni.navigateTo({
url: "/pages/user/order",
})
},
goMorePage() {
uni.navigateTo({
url: "/pages/const/more"
})
},
}
}
</script>
<style>
page {
background-color: #f8f8f8;
}
.logo {
width: 750upx;
height: 240upx;
padding: 20upx;
background-color: #2F85FC;
flex-direction: row;
align-items: center;
}
.logo-hover {
opacity: 0.8;
}
.logo-img {
width: 150upx;
height: 150upx;
border-radius: 150upx;
}
.logo-title {
height: 150upx;
flex: 1;
align-items: center;
justify-content: space-between;
flex-direction: row;
margin-left: 20upx;
}
.user-name {
height: 60upx;
line-height: 60upx;
font-size: 38upx;
color: #FFFFFF;
}
.go-login-navigat-arrow {
font-size: 38upx;
color: #FFFFFF;
}
.login-title {
height: 150upx;
flex-direction: column;
align-items: center;
justify-content: center;
margin-left: 20upx;
}
.center-list {
flex-direction: column;
background-color: #FFFFFF;
margin-top: 20upx;
width: 690upx;
margin-left: 30upx;
margin-right: 30upx;
}
.center-list-item {
height: 90upx;
width: 690upx;
flex-direction: row;
padding: 0upx 20upx;
border-radius: 10upx;
box-shadow: #55555555 1rpx 0rpx 2rpx 0rpx;
}
.list-text {
height: 90upx;
line-height: 90upx;
font-size: 34upx;
color: #555;
flex: 1;
}
</style>

157
pages/user/info.vue Normal file
View File

@ -0,0 +1,157 @@
<template>
<view class="flex flex-column">
<view class="center-list">
<view class="center-list-item">
<text class="list-text">账号昵称</text>
<input type="nickname" class="list-input" v-model="form.nickname" @nicknamereview="changeName" @confirm="changeName">
</view>
</view>
<view class="center-list">
<view class="center-list-item" @click="setAvatar">
<text class="list-text">修改头像</text>
</view>
</view>
</view>
</template>
<script>
import { TaAjax, TaPost, baseUrl } from '../../common/ajax';
import { TaCache } from '../../common/cache';
import { TaImageToBase64 } from '../../common/image';
export default {
data() {
return {
userInfo: {},
form: {
nickname: "",
}
}
},
onShow() {
const userInfo = TaCache.get('auth.user');
if (userInfo) {
this.userInfo = userInfo;
if (!this.userInfo.phone) {
uni.navigateTo({
url: '/pages/user/bind'
})
}
this.form.nickname = this.userInfo.nickname || this.userInfo.extra.nickName
} else {
uni.navigateTo({
url: '/pages/user/login'
})
}
},
methods: {
changeName() {
uni.showLoading({
title: "修改中..."
})
TaAjax.post('/plugin-account/api.auth.center/set', {
nickname: this.form.nickname,
extra: {
nickName: this.form.nickname
}
}, {
header: {
'Content-Type': 'application/json'
}
}).then(res => {
uni.hideLoading();
if (res.code == 1) {
uni.showToast({
title: "修改成功",
icon: "success"
})
TaCache.set('auth.user', res.data);
} else {
uni.showToast({
title: res.msg,
icon: "none"
})
}
}).finally()
},
setAvatar() {
uni.chooseImage({
count: 1,
sourceType: ['album'],
success: (res) => {
uni.showLoading({
title: "上传中..."
})
uni.uploadFile({
url: baseUrl + '/custom/api.Upload/file',
filePath: res.tempFilePaths[0],
name: 'file',
success(res) {
const responseStr = res.data;
const response = JSON.parse(res.data);
const data = response.data;
const url = data.url;
TaPost('/plugin-account/api.auth.center/set', {
headimg: url
}).then().finally(() => uni.hideLoading())
},
complete() {
uni.hideLoading()
},
})
}
})
},
}
}
</script>
<style>
page {
background-color: #f8f8f8;
}
.go-login-navigat-arrow {
font-size: 38upx;
color: #FFFFFF;
}
.login-title {
height: 150upx;
flex-direction: column;
align-items: center;
justify-content: center;
margin-left: 20upx;
}
.center-list {
flex-direction: column;
background-color: #FFFFFF;
margin-top: 20upx;
width: 690upx;
margin-left: 30upx;
margin-right: 30upx;
}
.center-list-item {
height: 90upx;
width: 690upx;
display: flex;
flex-direction: row;
padding: 0upx 20upx;
border-radius: 10upx;
box-shadow: #55555555 1rpx 0rpx 2rpx 0rpx;
justify-content: space-between;
}
.list-text,.list-input {
height: 90upx;
line-height: 90upx;
font-size: 34upx;
color: #555;
}
.list-input {
text-align: right;
}
</style>

101
pages/user/login.vue Normal file
View File

@ -0,0 +1,101 @@
<template>
<view class="login">
<view class="login-head flex-y">
<text class="login-head-h1">登录</text>
</view>
<view class="login-body flex-y">
<view class="flex-center">
<text class="login-body-name">微信授权</text>
</view>
<view style="margin-top:80rpx;" class="flex-center">
<button type="success" size="large" @click="doLogin" customStyle="width:600rpx;height:100rpx">
</button>
</view>
</view>
<!--
<view class="login-foot">
<view class='login-foot-agent flex-center'>
<checkbox label="1" v-model="agent.value">同意协议</checkbox>
<text @click="agent.show = true">用户隐私协议</text>
</view>
</view> -->
</view>
</template>
<script>
import { TaAjax } from '@/common/ajax';
import { TaCache } from '@/common/cache';
import { TaToast } from '@/common/toast';
export default {
data() {
return {
// 用户协议
agent: {
show: false,
value: true,
},
}
},
created() {
const userInfo = TaCache.get('auth.user')
if (userInfo) {
uni.navigateBack()
}
},
methods: {
// 执行注册登录
doLogin() {
TaToast.loading("登录中")
this.login().then((data) => {
TaCache.set('auth.user', data)
}).finally(() => {
TaToast.loadhide()
})
},
login() {
return new Promise((resolve, reject) => uni.login({
provider: 'weixin',
success(loginRes) {
// 换取会话密钥
let data = {
code: loginRes.code,
iv: '',
encrypted: ''
}
TaAjax.post('/plugin-account/api.wxapp/session', data).then((ret) => {
console.log('SessionDone: ', ret)
TaCache.set('auth.token', ret.data.token)
// 获取用户信息
uni.getUserInfo({
provider: 'weixin',
success: (infoRes) => {
console.log('UserInfo: ', infoRes)
data.iv = infoRes.iv, data.encrypted = infoRes
.encryptedData
TaAjax.post('/plugin-account/api.wxapp/decode', data)
.then((ret) => {
console.log('UserDone: ', ret.data)
resolve(ret.data)
}).catch((ret) => {
console.log('UserFail: ', ret.data)
reject(ret)
})
}
})
}).catch((ret) => {
console.log('SessionFail: ', ret)
reject(ret);
})
}
}))
}
},
}
</script>

167
pages/user/order.vue Normal file
View File

@ -0,0 +1,167 @@
<template>
<view class="flex flex-column overflow-hidden" style="height: 100vh;">
<!-- <view class="flex align-center justify-between pt-3 bg-white flex-shrink">
<view v-for="(item,index) in tabBar" :key="index" class="flex-1 text-center " @click="changeTab(index)">
<text :class="tabIndex==index?'text-danger font-weight-bold':'text-muted'">{{item}}</text>
<view :class="tabIndex==index?'bg-danger':''" style="width: 30rpx;height: 10rpx;" class="rounded-lg d-block mx-auto mt-2 "></view>
</view>
</view> -->
<view class="flex-1" style="overflow-y: auto;">
<scroll-view class="flex-1 list overflow-hidden" :scroll-y="true" :refresher-enabled="true"
:refresher-triggered="refresh" @refresherrefresh="refreshData()" @scrolltolower="loadData()">
<i-order-list :resdata="orderList" @cancel="cancelOrder" @confirm="confirmOrder"></i-order-list>
<uni-load-more :status="more_status" @clickLoadMore="loadData"></uni-load-more>
</scroll-view>
</view>
<!-- <swiper class="flex-1" :current="tabIndex" @change="swiperChange" > -->
<!-- <swiper-item class="flex" v-for="(item,index) in tabBar" :key="index"> -->
<!-- </swiper-item> -->
<!-- </swiper> -->
</view>
</template>
<script>
import { TaAjax } from '../../common/ajax'
import { friendlyDate } from '../../common/util';
export default {
data() {
return {
tabIndex:0,
tabBar:['全部','待发货','待收货','已收货'],
loading: false,
refresh: true,
finish: true,
curPage: 1,
orderList: [],
}
},
computed: {
more_status() {
if (this.finish) {
return 'no-more';
} else if (this.loading) {
return 'loading';
} else {
return 'more';
}
},
},
methods: {
refreshData() {
this.refresh = true;
this.curPage = 1;
this.loadData();
},
loadData() {
if (this.refresh) {
this.orderList.length = 0;
this.finish = false;
}
if (this.finish) {
return;
}
this.loading = true;
TaAjax.get('/points_mall/api.auth.order/get', {
page: this.curPage
}).then((response) => {
const data = response.data;
const data_list = data.list.map((item) => {
item.create_at = friendlyDate(new Date(item.create_time.replace(/\-/g, '/'))
.getTime())
return item;
})
if (this.refresh) {
this.orderList.length = 0
}
this.orderList = this.orderList.concat(data_list)
this.finish = data.page.total <= this.orderList.length;
this.curPage++;
}).catch((e) => {
console.warn(e)
if (this.orderList.length == 0) {
this.finish = true;
}
}).finally(() => {
this.refresh = false;
this.loading = false;
});
},
changeTab(index){
this.tabIndex = index
this.refreshData()
},
swiperChange(e){
this.tabIndex = e.detail.current
this.refreshData()
},
cancelOrder(orderNo) {
uni.showLoading({
title: '取消中'
})
TaAjax.post('/points_mall/api.auth.order/cancel', {
order_no: orderNo,
}).then((response) => {
if (response.code == 1) {
uni.hideLoading()
uni.showToast({
title: '取消成功',
icon: 'success',
})
} else {
uni.hideLoading()
uni.showToast({
title: response.info,
icon: 'none',
})
}
}).catch((e) => {
console.warn(e)
uni.hideLoading()
uni.showToast({
title: '取消失败',
icon: 'none',
})
}).finally(() => {
this.refreshData()
})
},
confirmOrder(orderNo) {
uni.showLoading({
title: '确认中',
})
TaAjax.post('/points_mall/api.auth.order/confirm', {
order_no: orderNo,
}).then((response) => {
if (response.code == 1) {
uni.hideLoading()
uni.showToast({
title: '确认成功',
icon: 'success',
})
} else {
uni.hideLoading()
uni.showToast({
title: response.info,
icon: 'none',
})
}
}).catch((e) => {
console.warn(e)
uni.hideLoading()
uni.showToast({
title: '确认失败',
icon: 'none',
})
}).finally(() => {
this.refreshData()
})
},
}
}
</script>
<style scoped>
</style>

143
pages/user/point.vue Normal file
View File

@ -0,0 +1,143 @@
<template>
<view class="flex flex-column flex-1" style="height: 100vh;">
<view class="flex logo">
<view class="flex flex-1 flex-column center logo-title">
<text class="text-center title title-huge">{{point}}</text>
<text class="text-center title">当前积分</text>
</view>
</view>
<scroll-view class="flex-1 list" :scroll-y="true" :refresher-enabled="true"
:refresher-triggered="refresh" @refresherrefresh="refreshLog" @scrolltolower="getLog">
<uni-list class="flex flex-column flex-1">
<uni-list-item v-for="(item, index) in logList" :key="index">
<template v-slot:body>
<view class="flex flex-1 flex-column">
<text style="font-size: 36rpx;">{{item.reason}}</text>
<text style="font-size: 24rpx; color: gray;">{{item.create_at}}</text>
</view>
</template>
<template v-slot:footer>
<view class="flex align-center justify-center">
<text>{{item.point>0?'+':''}}{{item.point}}</text>
</view>
</template>
</uni-list-item>
</uni-list>
<uni-load-more :status="more_status" @clickLoadMore="getLog"></uni-load-more>
</scroll-view>
</view>
</template>
<script>
import {
TaAjax
} from '@/common/ajax';
import {
friendlyDate
} from '@/common/util';
export default {
computed: {
more_status() {
if (this.finish) {
return 'no-more';
} else if (this.loading) {
return 'loading';
} else {
return 'more';
}
},
},
data() {
return {
point: 0,
logList: [],
loading: false,
refresh: false,
finish: false,
curPage: 1,
}
},
onLoad() {
this.getPoint();
this.getLog();
},
methods: {
getPoint() {
TaAjax.get('/points_mall/api.auth.UserPoint/myPoint').then((response) => {
const data = response.data;
this.point = data.point
})
},
refreshLog() {
this.refresh = true;
this.curPage = 1;
this.getPoint()
this.getLog();
},
getLog() {
if (this.refresh) {
this.logList.length = 0
this.finish = false;
}
if (this.finish) {
return;
}
TaAjax.get('/points_mall/api.auth.UserPoint/myPointLog', {
page: this.curPage
}).then((response) => {
const data = response.data;
const data_list = data.data.map((item) => {
item.create_at = friendlyDate(new Date(item.create_at.replace(/\-/g, '/'))
.getTime())
return item;
})
if (this.refresh) {
this.logList.length = 0
}
this.logList = this.logList.concat(data_list)
this.finish = data.page.total <= this.logList.length;
this.curPage++;
}).catch((e) => {
console.warn(e)
if (this.logList.length == 0) {
this.finish = true;
}
}).finally(() => {
this.refresh = false;
this.loading = false;
});
},
}
}
</script>
<style lang="scss">
.logo {
width: 750upx;
height: 240upx;
padding: 20upx;
background-color: $uni-color-primary;
flex-direction: row;
align-items: center;
}
.logo-title {
height: 150upx;
align-items: center;
justify-content: space-around;
}
.title {
color: white;
font-size: 40rpx;
}
.title-huge {
font-size: 72rpx;
font-weight: bold;
}
.list {
height: calc(100vh - 240rpx);
}
</style>

91
pages/user/user_share.vue Normal file
View File

@ -0,0 +1,91 @@
<template>
<view class="flex flex-column flex-1" style="height: 100vh;">
<i-loading v-if="loading" />
<view class="flex flex-column flex-1" style="height: 100%;">
<scroll-view class="flex-1 overflow-hidden" style="height: 100%;" scroll-y :refresher-enabled="true"
:refresher-triggered="refresh" @refresherrefresh="refreshData" @scrolltolower="loadData">
<view class="px-2 overflow-scroll">
<i-user-share-list :resdata="shareList" />
</view>
<uni-load-more :status="more_status" @clickLoadMore="loadData"></uni-load-more>
</scroll-view>
</view>
</view>
</template>
<script>
import {
TaAjax
} from '@/common/ajax';
import {
friendlyDate
} from '@/common/util';
export default {
computed: {
more_status() {
if (this.finish) {
return 'no-more';
} else if (this.loading) {
return 'loading';
} else {
return 'more';
}
},
},
data() {
return {
shareList: [],
curPage: 1,
loading: true,
refresh: true,
finish: false
}
},
methods: {
loadData() {
if (this.refresh) {
this.shareList.length = 0;
this.finish = false;
}
if (this.finish) {
return;
}
TaAjax.get('/ticket/api.auth.UserShare/index', {
page: this.curPage
}).then((result) => {
const data = result.data;
const data_list = data.data.map((share) => {
share.create_at = friendlyDate(new Date(share.create_at.replace(/\-/g, '/'))
.getTime());
share.imgs = share.imgs_arr;
return share;
});
if (this.refresh) {
this.shareList.length = 0;
}
this.shareList = this.shareList.concat(data_list);
this.finish = data.total <= this.shareList.length;
this.curPage++;
}).catch((e) => {
console.warn(e)
if (this.shareList.length == 0) {
this.finish = true;
}
}).finally(() => {
this.refresh = false;
this.loading = false;
});
},
refreshData() {
this.finish = false;
this.refresh = true;
this.curPage = 1;
this.loadData();
},
}
}
</script>
<style>
</style>