yshop意向点餐系统v1.2.2
No files matched your search
@@ -0,0 +1,41 @@
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
/unpackage
|
||||
|
||||
/dist
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.cache
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
.tmp*
|
||||
.svn
|
||||
.tags
|
||||
*.sublime-*
|
||||
sftp-config.json
|
||||
logs
|
||||
*.log
|
||||
.idea*
|
||||
.yo-rc.json
|
||||
*.swo
|
||||
*.swp
|
||||
/dist
|
||||
/deps
|
||||
yarn.lock
|
||||
dev-stats.json
|
||||
.vscode
|
||||
|
||||
.history
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
// launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
|
||||
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
|
||||
"version" : "0.0",
|
||||
"configurations" : [
|
||||
{
|
||||
"app-plus" : {
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"default" : {
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"mp-weixin" : {
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"type" : "uniCloud"
|
||||
},
|
||||
{
|
||||
"playground" : "standard",
|
||||
"type" : "uni-app:app-ios"
|
||||
},
|
||||
{
|
||||
"playground" : "custom",
|
||||
"type" : "uni-app:app-android"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<script setup>
|
||||
import { onHide,onLaunch,onShow } from '@dcloudio/uni-app'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useMainStore } from '@/store/store'
|
||||
const main = useMainStore()
|
||||
import { isWeixin,parseQuery } from '@/utils/util'
|
||||
import cookie from '@/utils/cookie'
|
||||
import {
|
||||
userAuthSession,
|
||||
wechatAuth
|
||||
} from '@/api/auth'
|
||||
import { APP_ID } from '@/config'
|
||||
|
||||
onLaunch(() => {
|
||||
console.log('App Launch')
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
console.log('App Show')
|
||||
|
||||
// 检查用户登录情况
|
||||
// #ifdef H5
|
||||
if(isWeixin()){
|
||||
|
||||
// H5编译的代码
|
||||
// 判断是否是微信浏览器
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
wechatMiniLogin();
|
||||
// #endif
|
||||
})
|
||||
|
||||
onHide(() => {
|
||||
console.log('App Hide')
|
||||
})
|
||||
|
||||
|
||||
|
||||
const wechatMiniLogin = () => {
|
||||
//this.$u.toast('登录中');
|
||||
uni.login({
|
||||
provider: 'weixin'
|
||||
}).then(async (res) => {
|
||||
let data = await userAuthSession({
|
||||
code: res.code
|
||||
});
|
||||
if (data) {
|
||||
main.SET_OPENID(data.openId)
|
||||
if (data.hasOwnProperty('userInfo') && data.accessToken && data.accessToken != '') {
|
||||
main.SET_MEMBER(data.userInfo);
|
||||
main.SET_TOKEN(data.accessToken);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~@/static/style/app.scss';
|
||||
//@import 'static/iconfont/iconfont.scss';
|
||||
//@import url('./static/style/style.less');
|
||||
@import 'static/style/yshop.css';
|
||||
|
||||
// /*每个页面公共css */
|
||||
// page {
|
||||
// background-color: #f5f5f5;
|
||||
// }
|
||||
</style>
|
||||
@@ -0,0 +1,22 @@
|
||||
import api from './api'
|
||||
|
||||
// 删除用户地址
|
||||
export function addressDelete(data) {
|
||||
return api.post(`/address/del/${data.id}`, undefined, { login: true })
|
||||
}
|
||||
|
||||
// 设置默认地址
|
||||
export function shopGetDistanceFromLocation(data) {
|
||||
return api.post(`/address/getDistanceFromLocation`, data, { login: true })
|
||||
}
|
||||
|
||||
// 添加或修改地址
|
||||
export function getAddressAddAndEdit(data) {
|
||||
return api.post(`/address/addAndEdit`, data, { login: true })
|
||||
}
|
||||
|
||||
// 用户地址列表 l
|
||||
export function addressAll(data) {
|
||||
return api.get(`/address/list`, data, { login: true })
|
||||
}
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
// #ifdef H5
|
||||
// h5端
|
||||
import Fly from 'flyio/dist/npm/fly'
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
// app端
|
||||
import Fly from 'flyio/dist/npm/wx'
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
import Fly from 'flyio/dist/npm/wx'
|
||||
// #endif
|
||||
|
||||
import { handleLoginFailure } from '@/utils'
|
||||
import { isWeixin } from '@/utils/util'
|
||||
import { VUE_APP_API_URL } from '@/config'
|
||||
import cookie from '@/utils/cookie'
|
||||
import { replace } from '@/utils/router'
|
||||
|
||||
const fly = new Fly()
|
||||
fly.config.baseURL = VUE_APP_API_URL
|
||||
|
||||
fly.interceptors.response.use(
|
||||
response => {
|
||||
// console.log(response)
|
||||
// 定时刷新access-token
|
||||
return response
|
||||
},
|
||||
error => {
|
||||
if (error.toString() == 'Error: Network Error') {
|
||||
handleLoginFailure()
|
||||
return Promise.reject({ msg: '未登录', toLogin: true })
|
||||
}
|
||||
if (error.status == 401) {
|
||||
handleLoginFailure()
|
||||
return Promise.reject({ msg: '未登录', toLogin: true })
|
||||
}
|
||||
if (error.response.data.status == 5109) {
|
||||
uni.showToast({
|
||||
title: error.response.data.msg,
|
||||
icon: 'none',
|
||||
duration: 2000,
|
||||
})
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
const defaultOpt = { login: true }
|
||||
|
||||
function baseRequest(options) {
|
||||
const token = cookie.get('accessToken')
|
||||
console.log('--> % token % token:\n', token)
|
||||
|
||||
options.headers = {
|
||||
...options.headers,
|
||||
}
|
||||
|
||||
// if (options.login === true) {
|
||||
options.headers = {
|
||||
...options.headers,
|
||||
Authorization: 'Bearer ' + token,
|
||||
}
|
||||
// }
|
||||
|
||||
// 结构请求需要的参数
|
||||
const { url, params, data, login, ...option } = options
|
||||
|
||||
// 发起请求
|
||||
return fly
|
||||
.request(url, params || data, {
|
||||
...option,
|
||||
})
|
||||
.then(res => {
|
||||
|
||||
const data = res.data || {}
|
||||
//console.log('res.status:',res)
|
||||
// console.log('res.code:',res.code)
|
||||
// #ifdef H5
|
||||
if (res.data.code == 1004004002) {
|
||||
if(isWeixin()){
|
||||
const url = cookie.get('index_url')
|
||||
console.log('redirect_uri:',url)
|
||||
//const url = `${location.origin}/h5/#/pages/index/index`
|
||||
location.href = url
|
||||
return
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
if (res.status !== 200) {
|
||||
return Promise.reject({ msg: '请求失败', res, data })
|
||||
}
|
||||
|
||||
|
||||
if (data.code == 401) {
|
||||
uni.hideLoading()
|
||||
handleLoginFailure()
|
||||
uni.showToast({
|
||||
title: data.msg,
|
||||
icon: 'none',
|
||||
duration: 2000,
|
||||
})
|
||||
return Promise.reject({ msg: data.msg, res, data })
|
||||
}
|
||||
|
||||
if (data.code != 0) {
|
||||
uni.showToast({
|
||||
title: data.msg,
|
||||
icon: 'none',
|
||||
duration: 2000,
|
||||
})
|
||||
return Promise.reject({ data, res })
|
||||
}
|
||||
|
||||
|
||||
return Promise.resolve(data.data, res)
|
||||
|
||||
// if ([401, 403].indexOf(data.status) !== -1) {
|
||||
// handleLoginFailure()
|
||||
// return Promise.reject({ msg: res.data.msg, res, data, toLogin: true })
|
||||
// } else if (data.status === 200) {
|
||||
// return Promise.resolve(data, res)
|
||||
// } else if (data.status == 5101) {
|
||||
// return Promise.reject({ msg: res.data.msg, res, data })
|
||||
// } else {
|
||||
// return Promise.reject({ msg: res.data.msg, res, data })
|
||||
// }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* http 请求基础类
|
||||
* 参考文档 https://www.kancloud.cn/yunye/axios/234845
|
||||
*
|
||||
*/
|
||||
const request = ['post', 'put', 'patch'].reduce((request, method) => {
|
||||
/**
|
||||
*
|
||||
* @param url string 接口地址
|
||||
* @param data object get参数
|
||||
* @param options object axios 配置项
|
||||
* @returns {AxiosPromise}
|
||||
*/
|
||||
request[method] = (url, data = {}, options = {}) => {
|
||||
console.log(url, data)
|
||||
return baseRequest(Object.assign({ url, data, method }, defaultOpt, options))
|
||||
}
|
||||
return request
|
||||
}, {})
|
||||
|
||||
;['get', 'delete', 'head'].forEach(method => {
|
||||
/**
|
||||
*
|
||||
* @param url string 接口地址
|
||||
* @param params object get参数
|
||||
* @param options object axios 配置项
|
||||
* @returns {AxiosPromise}
|
||||
*/
|
||||
request[method] = (url, params = {}, options = {}) => {
|
||||
return baseRequest(Object.assign({ url, params, method }, defaultOpt, options))
|
||||
}
|
||||
})
|
||||
|
||||
export default request
|
||||
@@ -0,0 +1,37 @@
|
||||
import api from './api'
|
||||
|
||||
/**
|
||||
* 使用手机 + 验证码登录
|
||||
*/
|
||||
export function userLogin(data) {
|
||||
return api.post('/member/auth/sms-login', data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用手机 + 验证码登录 member/auth/send-sms-code
|
||||
*/
|
||||
export function smsSend(data) {
|
||||
return api.post('/member/auth/send-sms-code', data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序 member/auth/auth-miniapp-login
|
||||
*/
|
||||
export function userLoginForWechatMini(data) {
|
||||
return api.post('/member/auth/auth-miniapp-login', data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* userAuthSession
|
||||
*/
|
||||
export function userAuthSession(data) {
|
||||
return api.post('/member/auth/auth-session', data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* wechatAuth
|
||||
*/
|
||||
export function wechatAuth(data) {
|
||||
return api.get('/member/auth/auth-wechat-login', data, { login: false })
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import api from './api'
|
||||
|
||||
/**
|
||||
* couponReceive
|
||||
*/
|
||||
export function couponReceive(data) {
|
||||
return api.post('/coupon/receive', data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* couponMine
|
||||
*/
|
||||
export function couponMine(data) {
|
||||
return api.get(`/coupon/my`, data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* couponIndex let couponCount = (params = {}) => vm.$u.get('/coupon/count', params);
|
||||
*/
|
||||
export function couponIndexApi(data) {
|
||||
return api.get(`/coupon/not`, data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* couponCount
|
||||
*/
|
||||
export function couponCount(data) {
|
||||
return api.get(`/coupon/count`, data, { login: false })
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import api from './api'
|
||||
|
||||
/**
|
||||
* 获得banner列表
|
||||
*/
|
||||
export function shopNearby(data) {
|
||||
return api.get('/store/nearby', data, { login: false })
|
||||
}
|
||||
/**
|
||||
* 获取首页信息
|
||||
*/
|
||||
export function menuGoods(data) {
|
||||
return api.get('/product/products', data, { login: false })
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import api from './api'
|
||||
|
||||
/**
|
||||
* shopGetList
|
||||
*/
|
||||
export function shopGetList(data) {
|
||||
return api.get('/store/list', data, { login: false })
|
||||
}
|
||||
|
||||
|
||||
export function menuAds(data) {
|
||||
return api.get('/ad/list', data, { login: false })
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import api from './api'
|
||||
|
||||
/**
|
||||
* 订单列表
|
||||
*/
|
||||
export function orderTakeFoods(data) {
|
||||
return api.get('/order/list', data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单创建
|
||||
*/
|
||||
export function orderSubmit(data) {
|
||||
return api.post(`/order/create`, data, { login: false })
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 订单列表
|
||||
*/
|
||||
export function orderGetOrders(data) {
|
||||
return api.get(`/order/list`, data, { login: false })
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算详情
|
||||
*/
|
||||
export function orderDetail(data) {
|
||||
return api.get(`/order/detail/${data}`, data, { login: false })
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 订单收货
|
||||
*/
|
||||
export function orderReceive(data) {
|
||||
return api.post(`/order/take`, data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单退款
|
||||
*/
|
||||
export function orderRefund(data) {
|
||||
return api.post(`/order/refund`, data, { login: false })
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
*/
|
||||
export function payUnify(data) {
|
||||
return api.post(`/order/pay`, data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* getWechatConfig
|
||||
*/
|
||||
export function getWechatConfig() {
|
||||
return api.get(`/member/wx-mp/create-jsapi-signature`, { url: location.href }, { login: false })
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import api from './api'
|
||||
|
||||
/**
|
||||
* 基本信息
|
||||
*/
|
||||
export function userGetUserInfo(data) {
|
||||
return api.get('/member/user/get-info', data, { login: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
*/
|
||||
export function mineService(data) {
|
||||
return api.get('/service/list', data, { login: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取内容
|
||||
*/
|
||||
export function mineServiceContent(data) {
|
||||
return api.get('/service/content', data, { login: true })
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* save
|
||||
*/
|
||||
export function userEdit(data) {
|
||||
return api.post('/member/user/update-nickname', data, { login: true })
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* balanceGetBillList
|
||||
*/
|
||||
export function balanceGetBillList(data) {
|
||||
return api.get('/member/user/getBill', data, { login: true })
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 充值列表
|
||||
*/
|
||||
export function balanceGetMoneyList(data) {
|
||||
return api.get('/recharge/getMoneyList', data, { login: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 充值
|
||||
*/
|
||||
export function balanceRecharge(data) {
|
||||
return api.post('/member/user/recharge', data, { login: true })
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<view
|
||||
class="blank"
|
||||
:style="{ height: size + 'px' }"
|
||||
></view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
const props = defineProps(['size'])
|
||||
const size = ref(props.size)
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
</style>
|
||||
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<view
|
||||
:class="['card', props.class]"
|
||||
:style="{ width: width ? width + 'rpx' : '100%' }"
|
||||
>
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
const props = defineProps(['class', 'width'])
|
||||
const className = ref(props.class)
|
||||
const width = ref(props.width)
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.card {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
border-radius: 7.5rpx;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,397 @@
|
||||
<template>
|
||||
<view>
|
||||
<text
|
||||
class="uni-input"
|
||||
@tap="open"
|
||||
>{{ value }}</text>
|
||||
<uv-popup
|
||||
ref="popup"
|
||||
mode="bottom"
|
||||
>
|
||||
<view class="cityselect">
|
||||
<view class="cityselect-header">
|
||||
<view class="cityselect-title">
|
||||
<text>请选择地址</text>
|
||||
</view>
|
||||
<view class="cityselect-nav">
|
||||
<view
|
||||
class="item"
|
||||
v-if="provinceActive"
|
||||
@tap="changeNav(0)"
|
||||
>
|
||||
<text>{{ provinceActive.name }}</text>
|
||||
</view>
|
||||
<view
|
||||
class="item"
|
||||
v-if="cityActive"
|
||||
@tap="changeNav(1)"
|
||||
>
|
||||
<text>{{ cityActive.name }}</text>
|
||||
</view>
|
||||
<view
|
||||
class="item"
|
||||
v-if="districtActive"
|
||||
@tap="changeNav(2)"
|
||||
>
|
||||
<text>{{ districtActive.name }}</text>
|
||||
</view>
|
||||
<view
|
||||
class="item active"
|
||||
v-else
|
||||
>
|
||||
<text>请选择</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cityselect-content">
|
||||
<swiper
|
||||
class="swiper"
|
||||
disable-touch="true"
|
||||
touchable="false"
|
||||
:current="current"
|
||||
>
|
||||
<swiper-item>
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="cityScroll"
|
||||
>
|
||||
<view>
|
||||
<view
|
||||
class="cityselect-item"
|
||||
v-for="(item, index) in province"
|
||||
:key="index"
|
||||
@tap="selectProvince(item, index)"
|
||||
>
|
||||
<view
|
||||
class="cityselect-item-box"
|
||||
:class="{ active: isProvinceActive(item) }"
|
||||
>
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="cityScroll"
|
||||
>
|
||||
<view>
|
||||
<view
|
||||
class="cityselect-item"
|
||||
v-for="(item, index) in city"
|
||||
:key="index"
|
||||
@tap="selectCity(item, index)"
|
||||
>
|
||||
<view
|
||||
class="cityselect-item-box"
|
||||
:class="{ active: isCityActive(item) }"
|
||||
>
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="cityScroll"
|
||||
>
|
||||
<view>
|
||||
<view
|
||||
class="cityselect-item"
|
||||
v-for="(item, index) in district"
|
||||
:key="index"
|
||||
@tap="selectDistrict(item, index)"
|
||||
>
|
||||
<view
|
||||
class="cityselect-item-box"
|
||||
:class="{ active: isDistrictActive(item) }"
|
||||
>
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
</uv-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ref, watch,onMounted } from "vue"
|
||||
const props = defineProps(['items', 'defaultValue'])
|
||||
|
||||
const emit = defineEmits(['callback'])
|
||||
|
||||
|
||||
const items = ref(props.items || [])
|
||||
// const defaultValue = ref(props.defaultValue)
|
||||
// console.log("--> % defaultValue:\n", defaultValue)
|
||||
|
||||
const value = ref(props.value || '请选择')
|
||||
const province = ref(props.items)
|
||||
const provinceActive = ref(null)
|
||||
const city = ref([])
|
||||
const cityActive = ref(null)
|
||||
const district = ref([])
|
||||
const districtActive = ref(null)
|
||||
const current = ref(0)
|
||||
const popup = ref(null)
|
||||
|
||||
|
||||
watch(() => props.items, (next) => {
|
||||
province.value = next
|
||||
})
|
||||
|
||||
watch(() => props.defaultValue, (next) => {
|
||||
console.log("--> % defaultValue % next:\n", next)
|
||||
value.value = `${next.province.name} ${next.city.name} ${next.district.name}`
|
||||
setDefaultValue(items.value, next)
|
||||
})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
// setDefaultValue(items, props.defaultValue)
|
||||
})
|
||||
|
||||
const isProvinceActive = (item) => {
|
||||
return provinceActive.value && item.value == provinceActive.value.value
|
||||
}
|
||||
|
||||
const isCityActive = (item) => {
|
||||
return cityActive.value && item.value == cityActive.value.value
|
||||
}
|
||||
|
||||
const isDistrictActive = (item) => {
|
||||
return districtActive.value && item.value == districtActive.value.value
|
||||
}
|
||||
|
||||
const setDefaultValue = (items, value) => {
|
||||
if (!items || !value) {
|
||||
return
|
||||
}
|
||||
province.value = items
|
||||
items.map(prov => {
|
||||
console.log("--> % setDefaultValue % prov:\n", prov)
|
||||
if (prov.name == value.province.name) {
|
||||
city.value = prov.id
|
||||
provinceActive.value = {
|
||||
value: prov.id,
|
||||
name: value.province.name,
|
||||
}
|
||||
prov.children.map(city => {
|
||||
if (city.name == value.city.name) {
|
||||
district.value = city.children
|
||||
cityActive.value = {
|
||||
value: city.id,
|
||||
name: value.city.name,
|
||||
}
|
||||
city.children.map(district => {
|
||||
if (district.name == value.district.name) {
|
||||
districtActive.value = {
|
||||
value: city.id,
|
||||
name: value.district.name,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log(provinceActive.value, cityActive.value, districtActive.value)
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
province.value = props.items
|
||||
provinceActive.value = null
|
||||
cityActive.value = null
|
||||
districtActive.value = null
|
||||
city.value = []
|
||||
district.value = []
|
||||
current.value = 0
|
||||
popup.value.open()
|
||||
|
||||
setDefaultValue(items.value, props.defaultValue.value)
|
||||
}
|
||||
|
||||
const changeNav = (index) => {
|
||||
if (index == 0) {
|
||||
provinceActive.value = null
|
||||
}
|
||||
if (index == 1) {
|
||||
cityActive.value = null
|
||||
districtActive.value = null
|
||||
}
|
||||
if (index == 2) {
|
||||
districtActive.value = null
|
||||
}
|
||||
current.value = index
|
||||
}
|
||||
|
||||
const selectProvince = (selectItem, index) => {
|
||||
provinceActive.value = selectItem
|
||||
city.value = selectItem.children
|
||||
current.value = 1
|
||||
}
|
||||
|
||||
const selectCity = (selectItem, index) => {
|
||||
cityActive.value = selectItem
|
||||
district.value = selectItem.children
|
||||
current.value = 2
|
||||
}
|
||||
|
||||
const selectDistrict = (selectItem, index) => {
|
||||
console.log("--> % selectDistrict % selectItem:\n", selectItem)
|
||||
districtActive.value = selectItem
|
||||
value.value = `${provinceActive.value?.name} ${cityActive.value?.name} ${districtActive.value?.name}`
|
||||
console.log({
|
||||
province: {
|
||||
id: provinceActive.value?.id,
|
||||
name: provinceActive.value?.name,
|
||||
},
|
||||
city: {
|
||||
id: cityActive.value?.id,
|
||||
name: cityActive.value?.name,
|
||||
},
|
||||
district: {
|
||||
id: districtActive.value?.id,
|
||||
name: districtActive.value?.name,
|
||||
},
|
||||
})
|
||||
emit('callback', {
|
||||
province: {
|
||||
id: provinceActive.value?.id,
|
||||
name: provinceActive.value?.name,
|
||||
},
|
||||
city: {
|
||||
id: cityActive.value?.id,
|
||||
name: cityActive.value?.name,
|
||||
},
|
||||
district: {
|
||||
id: districtActive.value?.id,
|
||||
name: districtActive.value?.name,
|
||||
},
|
||||
})
|
||||
popup.value.close()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.cityselect {
|
||||
width: 100%;
|
||||
height: 75%;
|
||||
background-color: #fff;
|
||||
z-index: 1502;
|
||||
position: relative;
|
||||
padding-bottom: 0;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.cityScroll {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
height: 800rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.cityselect-header {
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.cityselect-title {
|
||||
width: 100%;
|
||||
font-size: 30rpx;
|
||||
text-align: center;
|
||||
height: 95rpx;
|
||||
line-height: 95rpx;
|
||||
position: relative;
|
||||
|
||||
&:cityselect-title:after {
|
||||
height: 1px;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
content: '';
|
||||
width: 100%;
|
||||
background-image: linear-gradient(0deg, #ececec 50%, transparent 0);
|
||||
}
|
||||
}
|
||||
|
||||
.cityselect-nav {
|
||||
width: 100%;
|
||||
padding-left: 20rpx;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
.item {
|
||||
font-size: 26rpx;
|
||||
color: #222;
|
||||
display: block;
|
||||
height: 80rpx;
|
||||
line-height: 92rpx;
|
||||
padding: 0 16rpx;
|
||||
position: relative;
|
||||
margin-right: 30rpx;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 40%;
|
||||
|
||||
&.active {
|
||||
color: #f23030 !important;
|
||||
border-bottom: 1rpx solid #f23030;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cityselect-content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cityselect-item {
|
||||
.cityselect-item-box {
|
||||
display: block;
|
||||
padding: 0 40rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 64rpx;
|
||||
max-height: 65rpx;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
|
||||
&.active {
|
||||
color: #f23030 !important;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
height: 1rpx;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-image: linear-gradient(0deg, #ececec 50%, transparent 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<view :class="['container', min ? 'container-min' : '']">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, } from 'vue';
|
||||
const props = defineProps(['min'])
|
||||
const min = ref(props?.min != undefined)
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.container {
|
||||
padding: 0 34rpx;
|
||||
|
||||
&-min {
|
||||
padding: 0 10rpx;
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<view class="layout">
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, defineProps, reactive } from 'vue';
|
||||
const props = defineProps(['size'])
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.layout {
|
||||
min-height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<view
|
||||
class="tui-cell-class tui-list-cell"
|
||||
:class="{ 'tui-cell-arrow': arrow, 'tui-cell-last': last, 'tui-line-left': lineLeft, 'tui-line-right': lineRight, 'tui-radius': radius }"
|
||||
:hover-class="hover ? 'tui-cell-hover' : ''"
|
||||
:style="{ background: bgcolor, fontSize: size + 'rpx', color: color, padding: padding}"
|
||||
:hover-stay-time="150"
|
||||
@tap="handleClick"
|
||||
>
|
||||
<slot></slot>
|
||||
<image src="/static/images/navigator-1.png" class="arrow" v-if="arrow"></image>
|
||||
<!-- <view class="iconfont iconarrow-right arrow" v-if="arrow"></view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
const props = defineProps ({
|
||||
//是否有箭头
|
||||
arrow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//是否有点击效果
|
||||
hover: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
//left 30rpx
|
||||
lineLeft:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//right 30rpx
|
||||
lineRight:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
padding:{
|
||||
type:String,
|
||||
default:"26rpx 30rpx"
|
||||
},
|
||||
last: {
|
||||
type: Boolean,
|
||||
default: false //最后一条数据隐藏线条
|
||||
},
|
||||
radius:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
bgcolor: {
|
||||
type: String,
|
||||
default: "#fff" //背景颜色
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 28 //字体大小
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "#5A5B5C" //字体颜色
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['click'])
|
||||
const handleClick = () => {
|
||||
emit('click', {
|
||||
index: props.index
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tui-list-cell {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.tui-radius {
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tui-cell-hover {
|
||||
background: #f7f7f9 !important;
|
||||
}
|
||||
|
||||
.tui-list-cell::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-bottom: 2rpx solid #eee;
|
||||
-webkit-transform: scaleY(0.8);
|
||||
transform: scaleY(0.8);
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
.tui-line-left::after {
|
||||
left: 30rpx !important;
|
||||
}
|
||||
|
||||
.tui-line-right::after {
|
||||
right: 30rpx !important;
|
||||
}
|
||||
|
||||
.tui-cell-last::after {
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
|
||||
// .arrow {
|
||||
// font-size: 44rpx;
|
||||
// line-height: 100%;
|
||||
// color: $text-color-grey;
|
||||
// position: relative;
|
||||
// margin-right: -12rpx;
|
||||
// }
|
||||
.arrow {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
position: relative;
|
||||
margin-right: -10rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:"logo",
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,347 @@
|
||||
<template>
|
||||
<view @touchmove.stop.prevent>
|
||||
<view class="modal-box" :style="{width:props.width,padding:props.padding,borderRadius:props.radius}" :class="[(fadein || props.show)?'modal-normal':'modal-scale',props.show?'modal-show':'']">
|
||||
<view v-if="props.custom">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="modal-title" v-if="props.title">{{props.title}}</view>
|
||||
<view class="modal-content" :class="[props.title?'':'mtop']" :style="{color:props.color,fontSize:props.size+'rpx'}">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view class="modalBtn-box" :class="[props.button.length!=2?'flex-column':'']">
|
||||
<block v-for="(item,index) in props.button" :key="index">
|
||||
<button class="modal-btn"
|
||||
:class="[
|
||||
''+(item.type || 'primary')+(item.plain?'-outline':''),
|
||||
props.button.length!=2?'btn-width':'',
|
||||
props.button.length>2?'mbtm':'',
|
||||
props.shape=='circle'?'circle-btn':'',
|
||||
'btn-' + (item.size || 'default'),
|
||||
]"
|
||||
:hover-class="''+(item.plain?'outline':(item.type || 'primary'))+'-hover'" :data-index="index" @tap="handleClick">{{item.text || "确定"}}</button>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="modal-mask" :class="[props.show?'mask-show':'']" @tap="handleClickCancel"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
//const props = defineProps(['show','custom','width','padding','radius','title','content','color','size','shape','button','maskClosable','fadein'])
|
||||
const props = defineProps ({
|
||||
show: {type: Boolean,default: false},
|
||||
custom: {type: Boolean,default: false},
|
||||
width: {type: String,default: "84%"},
|
||||
padding: {type: String,default: "40rpx"},
|
||||
radius: {type: String,default: "24rpx"},
|
||||
title: {type: String,default: ""},
|
||||
content: {type: String,default: ""},
|
||||
color: {type: String,default: "#999"},
|
||||
size: {type: Number,default: 28},
|
||||
shape: {type: String,default: 'square'}, //形状 circle, square
|
||||
button: {type: Array,
|
||||
default: function() {
|
||||
return [{
|
||||
text: "取消",
|
||||
type: "red",
|
||||
plain: true //是否空心
|
||||
}, {
|
||||
text: "确定",
|
||||
type: "red",
|
||||
plain: false
|
||||
}]
|
||||
}},
|
||||
maskClosable: {type: Boolean,default: true},
|
||||
custom: {type: Boolean,default: false},
|
||||
fadein: {type: Boolean,default: false} //淡入效果,自定义弹框插入input输入框时传true
|
||||
})
|
||||
|
||||
// const show = ref(props.show)
|
||||
// const maskClosable = ref(props.maskClosable)
|
||||
const emit = defineEmits(['click','cancel','test'])
|
||||
const handleClick = (e) => {
|
||||
if (!props.show) return;
|
||||
const dataset = e.currentTarget.dataset;
|
||||
emit('click', {
|
||||
index: Number(dataset.index)
|
||||
});
|
||||
}
|
||||
const handleClickCancel = () => {
|
||||
if (!props.maskClosable) return;
|
||||
emit('cancel');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.modal-box {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin: auto;
|
||||
background: #fff;
|
||||
z-index: 201;
|
||||
transition: all 0.3s ease-in-out;
|
||||
opacity: 0;
|
||||
box-sizing: border-box;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.modal-scale {
|
||||
transform: translate(-50%, -50%) scale(0);
|
||||
}
|
||||
|
||||
.modal-normal {
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
|
||||
.modal-show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
z-index: 98;
|
||||
transition: all 0.3s ease-in-out;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.mask-show {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
color: #333;
|
||||
padding-top: 20rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
color: #999;
|
||||
font-size: 28rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-bottom: 60rpx;
|
||||
}
|
||||
|
||||
.mtop {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.mbtm {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.modalBtn-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.modal-btn {
|
||||
width: 46%;
|
||||
height: 68rpx;
|
||||
line-height: 68rpx;
|
||||
position: relative;
|
||||
border-radius: 60rpx;
|
||||
font-size: 28rpx;
|
||||
overflow: visible;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
|
||||
&.btn-default {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
&.btn-lg {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
&.btn-sm {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-btn::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
-webkit-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
-webkit-transform: scale(0.5, 0.5);
|
||||
transform: scale(0.5, 0.5);
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-radius: 60rpx;
|
||||
}
|
||||
|
||||
.btn-width {
|
||||
width: 80% !important;
|
||||
}
|
||||
|
||||
.primary {
|
||||
background: #97AF13;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.primary-hover {
|
||||
background: #97AF13;
|
||||
color: #e5e5e5;
|
||||
}
|
||||
|
||||
.primary-outline {
|
||||
color: #97AF13;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.primary-outline::after {
|
||||
border: 1px solid #97AF13;
|
||||
}
|
||||
|
||||
.danger {
|
||||
background: #ed3f14;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.danger-hover {
|
||||
background: #d53912;
|
||||
color: #e5e5e5;
|
||||
}
|
||||
|
||||
.danger-outline {
|
||||
color: #ed3f14;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.danger-outline::after {
|
||||
border: 1px solid #ed3f14;
|
||||
}
|
||||
|
||||
.red {
|
||||
background: #e41f19;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.red-hover {
|
||||
background: #c51a15;
|
||||
color: #e5e5e5;
|
||||
}
|
||||
|
||||
.red-outline {
|
||||
color: #e41f19;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.red-outline::after {
|
||||
border: 1px solid #e41f19;
|
||||
}
|
||||
|
||||
.warning {
|
||||
background: #ff7900;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.warning-hover {
|
||||
background: #e56d00;
|
||||
color: #e5e5e5;
|
||||
}
|
||||
|
||||
.warning-outline {
|
||||
color: #ff7900;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.warning-outline::after {
|
||||
border: 1px solid #ff7900;
|
||||
}
|
||||
|
||||
.green {
|
||||
background: #19be6b;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.green-hover {
|
||||
background: #16ab60;
|
||||
color: #e5e5e5;
|
||||
}
|
||||
|
||||
.green-outline {
|
||||
color: #19be6b;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.green-outline::after {
|
||||
border: 1px solid #19be6b;
|
||||
}
|
||||
|
||||
.white {
|
||||
background: #fff;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.white-hover {
|
||||
background: #f7f7f9;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.white-outline {
|
||||
color: #333;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.white-outline::after {
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.gray {
|
||||
background: #ededed;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.gray-hover {
|
||||
background: #d5d5d5;
|
||||
color: #898989;
|
||||
}
|
||||
|
||||
.gray-outline {
|
||||
color: #999;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.gray-outline::after {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
.outline-hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.circle-btn {
|
||||
border-radius: 40rpx !important;
|
||||
}
|
||||
|
||||
.circle-btn::after {
|
||||
border-radius: 80rpx !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<view
|
||||
:class="classObject"
|
||||
:style="[getStyle]"
|
||||
>
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onMounted } from "vue"
|
||||
const props = defineProps([
|
||||
'direction',
|
||||
'align',
|
||||
'wrap',
|
||||
'justify',
|
||||
'size',
|
||||
'height',
|
||||
'padding',
|
||||
'flex',
|
||||
'border'
|
||||
])
|
||||
|
||||
console.log("--> % props:\n", props)
|
||||
|
||||
|
||||
const classObject = ref({})
|
||||
|
||||
const handleClassObject = (props) => {
|
||||
console.log("--> % handleClassObject % props:\n", props.value)
|
||||
let className = 'yshop-space'
|
||||
let direction = props.direction
|
||||
let align = props.align
|
||||
let wrap = props.wrap
|
||||
let justify = props.justify
|
||||
let flex = props.flex
|
||||
let border = props.border
|
||||
if (border) {
|
||||
className += ' yshop-space-border'
|
||||
}
|
||||
if (direction) {
|
||||
className += ` yshop-space-${direction}`
|
||||
}
|
||||
if (wrap) {
|
||||
className += ` yshop-space-${wrap}`
|
||||
}
|
||||
if (align) {
|
||||
className += ` yshop-space-align-${align}`
|
||||
}
|
||||
if (justify) {
|
||||
className += ` yshop-space-justify-${justify}`
|
||||
}
|
||||
console.log("--> % handleClassObject % className:\n", className)
|
||||
|
||||
classObject.value = className
|
||||
}
|
||||
|
||||
const getStyle = ({
|
||||
size = 6,
|
||||
wrap,
|
||||
height,
|
||||
padding,
|
||||
flex
|
||||
}) => {
|
||||
let innerStyle = {}
|
||||
// let size = size.value
|
||||
// let wrap = wrap.value
|
||||
// let height = height.value
|
||||
// let padding = padding.value
|
||||
|
||||
if (height) {
|
||||
innerStyle.height = `${height}rpx`
|
||||
}
|
||||
if (typeof size === 'number') {
|
||||
innerStyle.gap = size + 'px'
|
||||
}
|
||||
|
||||
|
||||
if (wrap) {
|
||||
innerStyle.flexWrap = 'wrap'
|
||||
}
|
||||
|
||||
if (typeof size === 'string') {
|
||||
switch (size) {
|
||||
case 'small':
|
||||
innerStyle.gap = '8rpx'
|
||||
break
|
||||
case 'middle':
|
||||
innerStyle.gap = '16rpx'
|
||||
break
|
||||
case 'large':
|
||||
innerStyle.gap = '24rpx'
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (typeof padding === 'string') {
|
||||
innerStyle.padding = `${padding}rpx`
|
||||
}
|
||||
|
||||
if (Object.prototype.toString.call(padding) === '[object Array]') {
|
||||
if (typeof padding === 'object') {
|
||||
if (padding.length == 1) {
|
||||
innerStyle.padding = `${padding[0]}rpx`
|
||||
}
|
||||
if (padding.length == 2) {
|
||||
innerStyle.padding = `${padding[0]}rpx ${padding[1]}rpx`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.prototype.toString.call(size) === '[object Array]') {
|
||||
if (typeof size === 'object') {
|
||||
if (size.length == 1) {
|
||||
innerStyle.gap = `${size[0]}rpx`
|
||||
}
|
||||
if (size.length == 2) {
|
||||
innerStyle.gap = `${size[0]}rpx ${size[1]}rpx`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (flex) {
|
||||
innerStyle.flex = flex
|
||||
}
|
||||
|
||||
return innerStyle
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handleClassObject(props)
|
||||
getStyle(props)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
space {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.yshop-space {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
|
||||
&-vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&-align-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&-align-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
&-align-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
&-justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&-justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&-justify-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
&-align-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
&-align-baseline {
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
&-item:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-border {
|
||||
border-bottom: 1rpx solid #f9f9f9;
|
||||
}
|
||||
}
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
.yshop-space {
|
||||
&>view {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
&>text {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
&>image {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.u-tag-wrapper {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.u-tag {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// #endif
|
||||
</style>
|
||||
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<uv-upload
|
||||
:fileList="list"
|
||||
name="1"
|
||||
multiple
|
||||
:maxCount="10"
|
||||
@afterRead="afterRead"
|
||||
@delete="handleDeletePic"
|
||||
></uv-upload>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { VUE_APP_UPLOAD_URL } from '@/config';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const props = defineProps(['modelValue'])
|
||||
console.log("--> % modelValue:\n", props.modelValue)
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const list = ref(props.modelValue)
|
||||
|
||||
const handleDeletePic = (event) => {
|
||||
list.value.splice(event.index, 1)
|
||||
|
||||
emit('update:modelValue', list.value)
|
||||
}
|
||||
|
||||
const afterRead = async (event) => {
|
||||
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
|
||||
let lists = [].concat(event.file)
|
||||
let fileListLen = list.value.length
|
||||
lists.map((item) => {
|
||||
list.value.push({
|
||||
...item,
|
||||
status: 'uploading',
|
||||
message: '上传中'
|
||||
})
|
||||
})
|
||||
for (let i = 0; i < lists.length; i++) {
|
||||
const result = await uploadFilePromise(lists[i].url)
|
||||
console.log("gxs --> % afterRead % result:\n", result)
|
||||
let item = list.value[fileListLen]
|
||||
list.value.splice(fileListLen, 1, Object.assign(item, {
|
||||
status: 'success',
|
||||
message: '',
|
||||
url: result
|
||||
}))
|
||||
fileListLen++
|
||||
}
|
||||
emit('update:modelValue', list.value)
|
||||
}
|
||||
|
||||
const uploadFilePromise = (url) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let a = uni.uploadFile({
|
||||
url: VUE_APP_UPLOAD_URL, // 仅为示例,非真实的接口地址
|
||||
filePath: url,
|
||||
name: 'file',
|
||||
formData: {
|
||||
user: 'test'
|
||||
},
|
||||
success: (res) => {
|
||||
console.log("gxs --> % returnnewPromise % res:\n", res)
|
||||
setTimeout(() => {
|
||||
resolve(res.data.data)
|
||||
}, 10)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.activity {
|
||||
|
||||
&-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
&-info {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
&-title {
|
||||
line-height: 45rpx;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
&-subtitle {
|
||||
margin-left: 10rpx;
|
||||
|
||||
line-height: 33rpx;
|
||||
font-size: 24rpx;
|
||||
color: #EE6D46;
|
||||
}
|
||||
|
||||
&-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
||||
&-info {
|
||||
line-height: 33rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.image {
|
||||
margin-left: 10rpx;
|
||||
display: block;
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&-body {}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,452 @@
|
||||
<template>
|
||||
<uv-button
|
||||
round
|
||||
size="mini"
|
||||
block
|
||||
type="primary"
|
||||
@click="startCountdown"
|
||||
>
|
||||
{{ buttonText }}
|
||||
</uv-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
onUnmounted
|
||||
} from 'vue'
|
||||
import {
|
||||
sendSmsCode
|
||||
} from '@/api/auth'
|
||||
|
||||
const props = defineProps(['mobile', 'scene'])
|
||||
|
||||
const countingDown = ref(false); // 是否正在倒计时
|
||||
const countdownSeconds = ref(60); // 倒计时的总秒数
|
||||
const timer = ref(null); // 倒计时的总秒数
|
||||
|
||||
const buttonText = computed(() => {
|
||||
return countingDown.value ? `${countdownSeconds.value} 秒` : '发送验证码';
|
||||
});
|
||||
|
||||
const startCountdown = () => {
|
||||
if (!countingDown.value) {
|
||||
countingDown.value = true;
|
||||
handleSendSmsCode()
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleSendSmsCode = () => {
|
||||
uni.showLoading({
|
||||
title: '发送验证码中'
|
||||
});
|
||||
console.log("gxs --> % handleSendSmsCode % props.mobile:\n", props.mobile)
|
||||
sendSmsCode({
|
||||
"mobile": props.mobile,
|
||||
"scene": props.scene
|
||||
}).then(res => {
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '验证码已发送',
|
||||
duration: 2000
|
||||
});
|
||||
timer.value = setInterval(() => {
|
||||
countdownSeconds.value--;
|
||||
console.log("gxs --> % timer % countdownSeconds.value:\n", countdownSeconds.value)
|
||||
if (countdownSeconds.value <= 0) {
|
||||
clearInterval(timer.value);
|
||||
countdownSeconds.value = 60; // 倒计时结束后重置为初始值
|
||||
countingDown.value = false;
|
||||
}
|
||||
}, 1000);
|
||||
}).catch(error => {
|
||||
countingDown.value = false;
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer.value);
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.goods {
|
||||
position: relative;
|
||||
padding: 30rpx 0;
|
||||
|
||||
&-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.goods {
|
||||
&-content {
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&-info {
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
|
||||
&-thumb {
|
||||
margin-bottom: 15rpx;
|
||||
width: 100%;
|
||||
height: 203rpx;
|
||||
|
||||
&-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
&-header {}
|
||||
|
||||
&-thumb {
|
||||
background: #FAFAFA;
|
||||
}
|
||||
|
||||
&-content {}
|
||||
|
||||
&-storeName {
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
|
||||
|
||||
&-price {
|
||||
&-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.goods-price {}
|
||||
}
|
||||
|
||||
&-primary {
|
||||
line-height: 42rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #EE6D46;
|
||||
}
|
||||
|
||||
&-default {
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
&-original {
|
||||
margin-left: 9rpx;
|
||||
line-height: 28rpx;
|
||||
font-size: 20rpx;
|
||||
color: #999999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
&-desc {
|
||||
line-height: 33rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
&-info {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
|
||||
&-left {}
|
||||
|
||||
&-action {
|
||||
&-btn {}
|
||||
|
||||
&-desc {
|
||||
line-height: 28rpx;
|
||||
font-size: 20rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
&-image {
|
||||
&-img {}
|
||||
}
|
||||
|
||||
&-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 14rpx;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
|
||||
.goods {
|
||||
&-thumb {
|
||||
margin-bottom: 0;
|
||||
width: 220rpx;
|
||||
height: 220rpx;
|
||||
|
||||
&-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
padding-right: 40rpx;
|
||||
margin-left: 30rpx;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
&-model {
|
||||
display: flex;
|
||||
|
||||
|
||||
margin-bottom: 28rpx;
|
||||
|
||||
&-border {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40rpx;
|
||||
border: 1px solid #CCCCCC;
|
||||
opacity: 1;
|
||||
border-radius: 0rpx;
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
|
||||
&-info {}
|
||||
|
||||
&-label {
|
||||
line-height: 38rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
&-value {
|
||||
line-height: 38rpx;
|
||||
font-size: 24rpx;
|
||||
color: #333333;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
&-action {
|
||||
width: 11rpx;
|
||||
height: 7rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&-min {
|
||||
.goods {
|
||||
&-thumb {
|
||||
margin-bottom: 0;
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
|
||||
&-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// .goods {
|
||||
// padding: 16rpx 14rpx;
|
||||
|
||||
// &-header {
|
||||
// display: flex;
|
||||
// align-items: flex-start;
|
||||
// }
|
||||
|
||||
// &-thumb {
|
||||
|
||||
// width: 220rpx;
|
||||
// height: 220rpx;
|
||||
|
||||
// &-img {
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// display: block;
|
||||
// }
|
||||
// }
|
||||
|
||||
// &-content {
|
||||
// margin-top: 24rpx;
|
||||
// margin-left: 40rpx;
|
||||
// flex: 1
|
||||
// }
|
||||
|
||||
// &-storeName {
|
||||
// line-height: 40rpx;
|
||||
// font-size: 28rpx;
|
||||
// font-weight: 500;
|
||||
// color: #333333;
|
||||
// margin-bottom: 35rpx;
|
||||
// }
|
||||
|
||||
// &-info {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: space-between;
|
||||
|
||||
// &-left {
|
||||
// display: flex;
|
||||
// align-items: flex-end;
|
||||
|
||||
// }
|
||||
|
||||
// &-action {
|
||||
// &-btn {}
|
||||
|
||||
// &-desc {
|
||||
// color: #999999;
|
||||
// font-size: 24rpx;
|
||||
// line-height: 40rpx;
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// &-price {
|
||||
// &-default {
|
||||
// line-height: 28rpx;
|
||||
// font-size: 20rpx;
|
||||
// color: #999999;
|
||||
|
||||
// }
|
||||
|
||||
// &-primary {
|
||||
// line-height: 42rpx;
|
||||
// font-size: 30rpx;
|
||||
// font-weight: 500;
|
||||
// color: #EE6D46;
|
||||
// margin-left: 5rpx;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// &-desc {
|
||||
// color: #999999;
|
||||
// font-size: 24rpx;
|
||||
// line-height: 40rpx;
|
||||
// }
|
||||
|
||||
|
||||
&-model {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
width: auto;
|
||||
height: 40rpx;
|
||||
border: 1px solid #CCCCCC;
|
||||
opacity: 1;
|
||||
border-radius: 0rpx;
|
||||
padding: 0 10rpx;
|
||||
|
||||
margin-bottom: 28rpx;
|
||||
|
||||
&-label {
|
||||
line-height: 38rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
&-value {
|
||||
line-height: 38rpx;
|
||||
font-size: 24rpx;
|
||||
color: #333333;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
&-action {
|
||||
width: 11rpx;
|
||||
height: 7rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// &-model-info {
|
||||
// display: inline-flex;
|
||||
// align-items: center;
|
||||
// width: auto;
|
||||
// height: 40rpx;
|
||||
// opacity: 1;
|
||||
// border-radius: 0rpx;
|
||||
// margin-bottom: 28rpx;
|
||||
|
||||
// &-label {
|
||||
// line-height: 38rpx;
|
||||
// font-size: 24rpx;
|
||||
// color: #999999;
|
||||
// }
|
||||
|
||||
// &-value {
|
||||
// line-height: 38rpx;
|
||||
// font-size: 24rpx;
|
||||
// color: #333333;
|
||||
// margin-right: 10rpx;
|
||||
// }
|
||||
|
||||
// &-action {
|
||||
// width: 11rpx;
|
||||
// height: 7rpx;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
.buy-progress {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
&-info {
|
||||
flex: 1;
|
||||
|
||||
&-desc {
|
||||
color: #999999;
|
||||
font-size: 24rpx;
|
||||
line-height: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&-action {
|
||||
margin-left: 17rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.buy-num {
|
||||
|
||||
&-info-desc {
|
||||
color: #999999;
|
||||
font-size: 24rpx;
|
||||
line-height: 32rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,48 @@
|
||||
export const VUE_APP_API_URL = 'http://localhost:48081/app-api'
|
||||
//export const VUE_APP_API_URL = 'https://apidc.yixiang.co/app-api'
|
||||
export const VUE_APP_RESOURCES_URL = 'https://h5.yixiang.co/static'
|
||||
export const VUE_APP_UPLOAD_URL = VUE_APP_API_URL + '/infra/file/upload'
|
||||
export const APP_ID = 'wxc061dee8806ff712'
|
||||
|
||||
const orderListStatus = {}
|
||||
|
||||
// -1:申请退款
|
||||
// -2:退货成功
|
||||
// 0:待发货;
|
||||
// 1:待收货;
|
||||
// 2:已收货;
|
||||
// 3:待评价;
|
||||
// -1:已退款
|
||||
|
||||
export const orderStatus = {
|
||||
0: '未支付',
|
||||
1: '待发货',
|
||||
2: '待收货',
|
||||
3: '待评价',
|
||||
4: '已完成',
|
||||
5: '退款中',
|
||||
6: '已退款',
|
||||
7: '退款',
|
||||
}
|
||||
|
||||
export const orderReStatus = {
|
||||
0: '等待买家付款',
|
||||
// 1: '等待卖家发货',
|
||||
1: '卖家已发货',
|
||||
2: '等待买家待评价',
|
||||
3: '订单已完成',
|
||||
4: '订单退款中',
|
||||
5: '订单已退款',
|
||||
6: '退款已完成',
|
||||
}
|
||||
|
||||
// export const orderReStatus = {
|
||||
// 0: '等待买家付款',
|
||||
// 1: '等待卖家发货',
|
||||
// 2: '卖家已发货',
|
||||
// 3: '等待买家待评价',
|
||||
// 4: '订单已完成',
|
||||
// 5: '订单退款中',
|
||||
// 6: '订单已退款',
|
||||
// 7: '退款已完成',
|
||||
// }
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './usePage'
|
||||
export * from './useGlobalProperties'
|
||||
@@ -0,0 +1,8 @@
|
||||
// mouse.js
|
||||
import { ref, onMounted, onUnmounted, getCurrentInstance } from 'vue'
|
||||
import { onReady, onReachBottom } from '@dcloudio/uni-app'
|
||||
|
||||
export const useGlobalProperties = () => {
|
||||
const instance = getCurrentInstance()
|
||||
return instance.appContext.app.config.globalProperties
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// mouse.js
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { onReady, onReachBottom } from '@dcloudio/uni-app'
|
||||
|
||||
export const usePage = getPage => {
|
||||
// 页码,默认为1
|
||||
const page = ref(1)
|
||||
|
||||
// 页大小,默认为10
|
||||
const limit = ref(10)
|
||||
|
||||
// 关键字
|
||||
const keyword = ref('')
|
||||
|
||||
// 类别
|
||||
const type = ref('')
|
||||
|
||||
// 分类ID
|
||||
const sid = ref('')
|
||||
|
||||
// 是否新品,不为空的字符串即可
|
||||
const news = ref('')
|
||||
|
||||
// 是否积分兑换商品
|
||||
const isIntegral = ref('')
|
||||
|
||||
// 到底了
|
||||
const loadend = ref(false)
|
||||
|
||||
// 加载中
|
||||
const loading = ref(false)
|
||||
|
||||
const dataList = ref([])
|
||||
|
||||
const handleGetDataList = async () => {
|
||||
console.log('--> % handleGetDataList % loading:\n', loading.value)
|
||||
console.log('--> % handleGetDataList % loadend:\n', loadend.value)
|
||||
if (loading.value || loadend.value) return
|
||||
|
||||
loading.value = true
|
||||
const products = await getPage({
|
||||
page: page.value,
|
||||
limit: limit.value,
|
||||
keyword: keyword.value,
|
||||
type: type.value,
|
||||
sid: sid.value,
|
||||
news: news.value,
|
||||
isIntegral: isIntegral.value,
|
||||
})
|
||||
console.log('--> % handleGetDataList % products:\n', products)
|
||||
if (products) {
|
||||
if (products.length <= 0) {
|
||||
loadend.value = true
|
||||
}
|
||||
dataList.value = dataList.value.concat(products)
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const handleRefresh = () => {
|
||||
loadend.value = false
|
||||
loading.value = false
|
||||
dataList.value = []
|
||||
handleGetDataList()
|
||||
}
|
||||
|
||||
onReady(() => {
|
||||
console.log('onReady')
|
||||
// handleGetDataList()
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
if (loading.value) return
|
||||
page.value += 1
|
||||
})
|
||||
|
||||
// 通过返回值暴露所管理的状态
|
||||
return {
|
||||
type,
|
||||
dataList,
|
||||
page,
|
||||
limit,
|
||||
keyword,
|
||||
loading,
|
||||
loadend,
|
||||
refresh: handleRefresh,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["./*"],
|
||||
"@/api": ["./api"],
|
||||
"@/utils": ["./utils"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"include": ["/**/*"]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* @Author: Gaoxs
|
||||
* @Date: 2023-04-07 15:12:06
|
||||
* @LastEditors: Gaoxs
|
||||
* @Description:
|
||||
*/
|
||||
import util from '@/utils'
|
||||
|
||||
import App from './App'
|
||||
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import { createSSRApp } from 'vue'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
app.use(util)
|
||||
app.use(createPinia())
|
||||
return {
|
||||
app,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,437 @@
|
||||
{
|
||||
"name" : "yshop-miniapp",
|
||||
"appid" : "__UNI__ADC0FB0",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : 1,
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {
|
||||
"Payment" : {},
|
||||
"OAuth" : {}
|
||||
},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
//必选,JSON对象,云端打包配置
|
||||
"android" : {
|
||||
//可选,JSON对象,Android平台云端打包配置
|
||||
"packagename" : "", //必填,字符串类型,Android包名
|
||||
"keystore" : "", //必填,字符串类型,Android签名证书文件路径
|
||||
"password" : "", //必填,字符串类型,Android签名证书文件的密码
|
||||
"aliasname" : "", //必填,字符串类型,Android签名证书别名
|
||||
"schemes" : "", //可选,字符串类型,参考:https://uniapp.dcloud.io/tutorial/app-android-schemes
|
||||
"abiFilters" : [
|
||||
//可选,字符串数组类型,参考:https://uniapp.dcloud.io/tutorial/app-android-abifilters
|
||||
"armeabi-v7a",
|
||||
"arm64-v8a",
|
||||
"x86",
|
||||
"x86_64"
|
||||
],
|
||||
"permissions" : [
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
],
|
||||
"custompermissions" : false, //可选,Boolean类型,是否自定义Android权限配置
|
||||
"permissionExternalStorage" : {
|
||||
//可选,JSON对象,Android平台应用启动时申请读写手机存储权限策略
|
||||
"request" : "always", //必填,字符串类型,申请读写手机存储权限策略,可取值none、once、always
|
||||
"prompt" : "" //可选,字符串类型,当request设置为always值用户拒绝时弹出提示框上的内容
|
||||
},
|
||||
"permissionPhoneState" : {
|
||||
//可选,JSON对象,Android平台应用启动时申请读取设备信息权限配置
|
||||
"request" : "always", //必填,字符串类型,申请读取设备信息权限策略,可取值none、once、always
|
||||
"prompt" : "" //可选,字符串类型,当request设置为always值用户拒绝时弹出提示框上的内容
|
||||
},
|
||||
"minSdkVersion" : 21, //可选,数字类型,Android平台最低支持版本,参考:https://uniapp.dcloud.io/tutorial/app-android-minsdkversion
|
||||
"targetSdkVersion" : 30, //可选,数字类型,Android平台目标版本,参考:https://uniapp.dcloud.io/tutorial/app-android-targetsdkversion
|
||||
"packagingOptions" : [
|
||||
//可选,字符串数组类型,Android平台云端打包时build.gradle的packagingOptions配置项
|
||||
"doNotStrip '*/armeabi-v7a/*.so'",
|
||||
"merge '**/LICENSE.txt'"
|
||||
],
|
||||
"jsEngine" : "v8", //可选,字符串类型,uni-app使用的JS引擎,可取值v8、jsc
|
||||
"debuggable" : false, //可选,Boolean类型,是否开启Android调试开关
|
||||
"locale" : "default", //可选,应用的语言
|
||||
"forceDarkAllowed" : false, //可选,Boolean类型,是否强制允许暗黑模式
|
||||
"resizeableActivity" : false, //可选,Boolean类型,是否支持分屏调整窗口大小
|
||||
"hasTaskAffinity" : false, //可选,Boolean类型,是否设置android:taskAffinity
|
||||
"buildFeatures" : {
|
||||
//(HBuilderX3.5.0+版本支持)可选,JSON对象,Android平台云端打包时build.gradle的buildFeatures配置项
|
||||
"dataBinding" : false, //可选,Boolean类型,是否设置dataBinding
|
||||
"viewBinding" : false //可选,Boolean类型,是否设置viewBinding
|
||||
}
|
||||
},
|
||||
"ios" : {
|
||||
//可选,JSON对象,iOS平台云端打包配置
|
||||
"appid" : "", //必填,字符串类型,iOS平台Bundle ID
|
||||
"mobileprovision" : "", //必填,字符串类型,iOS打包使用的profile文件路径
|
||||
"p12" : "", //必填,字符串类型,iOS打包使用的证书文件路径
|
||||
"password" : "", //必填,字符串类型,iOS打包使用的证书密码
|
||||
"devices" : "iphone", //必填,字符串类型,iOS支持的设备类型,可取值iphone、ipad、universal
|
||||
"urlschemewhitelist" : "baidumap", //可选,字符串类型,应用访问白名单列表,参考:https://uniapp.dcloud.io/tutorial/app-ios-schemewhitelist
|
||||
"urltypes" : "", //可选,字符串类型,参考:https://uniapp.dcloud.io/tutorial/app-ios-schemes
|
||||
"UIBackgroundModes" : "audio", //可选,字符串类型,应用后台运行模式,参考:https://uniapp.dcloud.io/tutorial/app-ios-uibackgroundmodes
|
||||
"frameworks" : [
|
||||
//可选,字符串数组类型,依赖的系统库,已废弃,推荐使用uni原生插件扩展使用系统依赖库
|
||||
"CoreLocation.framework"
|
||||
],
|
||||
"deploymentTarget" : "10.0", //可选,字符串类型,iOS支持的最低版本
|
||||
"privacyDescription" : {
|
||||
//可选,JSON对象,iOS隐私信息访问的许可描述
|
||||
"NSPhotoLibraryUsageDescription" : "", //可选,字符串类型,系统相册读取权限描述
|
||||
"NSPhotoLibraryAddUsageDescription" : "", //可选,字符串类型,系统相册写入权限描述
|
||||
"NSCameraUsageDescription" : "", //可选,字符串类型,摄像头使用权限描述
|
||||
"NSMicrophoneUsageDescription" : "", //可选,字符串类型,麦克风使用权限描述
|
||||
"NSLocationWhenInUseUsageDescription" : "", //可选,字符串类型,运行期访问位置权限描述
|
||||
"NSLocationAlwaysUsageDescription" : "", //可选,字符串类型,后台运行访问位置权限描述
|
||||
"NSLocationAlwaysAndWhenInUseUsageDescription" : "", //可选,字符串类型,运行期后后台访问位置权限描述
|
||||
"NSCalendarsUsageDescription" : "", //可选,字符串类型,使用日历权限描述
|
||||
"NSContactsUsageDescription" : "", //可选,字符串类型,使用通讯录权限描述
|
||||
"NSBluetoothPeripheralUsageDescription" : "", //可选,字符串类型,使用蓝牙权限描述
|
||||
"NSBluetoothAlwaysUsageDescription" : "", //可选,字符串类型,后台使用蓝牙权限描述
|
||||
"NSSpeechRecognitionUsageDescription" : "", //可选,字符串类型,系统语音识别权限描述
|
||||
"NSRemindersUsageDescription" : "", //可选,字符串类型,系统提醒事项权限描述
|
||||
"NSMotionUsageDescription" : "", //可选,字符串类型,使用运动与健康权限描述
|
||||
"NSHealthUpdateUsageDescription" : "", //可选,字符串类型,使用健康更新权限描述
|
||||
"NSHealthShareUsageDescription" : "", //可选,字符串类型,使用健康分享权限描述
|
||||
"NSAppleMusicUsageDescription" : "", //可选,字符串类型,使用媒体资料库权限描述
|
||||
"NFCReaderUsageDescription" : "", //可选,字符串类型,使用NFC权限描述
|
||||
"NSHealthClinicalHealthRecordsShareUsageDescription" : "", //可选,字符串类型,访问临床记录权限描述
|
||||
"NSHomeKitUsageDescription" : "", //可选,字符串类型,访问HomeKit权限描述
|
||||
"NSSiriUsageDescription" : "", //可选,字符串类型,访问Siri权限描述
|
||||
"NSFaceIDUsageDescription" : "", //可选,字符串类型,使用FaceID权限描述
|
||||
"NSLocalNetworkUsageDescription" : "", //可选,字符串类型,访问本地网络权限描述
|
||||
"NSUserTrackingUsageDescription" : "" //可选,字符串类型,跟踪用户活动权限描述
|
||||
},
|
||||
"idfa" : true, //可选,Boolean类型,是否使用广告标识
|
||||
"capabilities" : {},
|
||||
//可选,JSON对象,应用的能力配置(Capabilities)
|
||||
"CFBundleName" : "HBuilder", //可选,字符串类型,CFBundleName名称
|
||||
"validArchitectures" : [
|
||||
//可选,字符串数组类型,编译时支持的CPU指令,可取值arm64、arm64e、armv7、armv7s、x86_64
|
||||
"arm64"
|
||||
],
|
||||
"pushRegisterMode" : "manual", //可选,使用“Push(消息推送)”模块时申请系统推送权限模式,manual表示调用push相关API时申请,其它值表示应用启动时自动申请
|
||||
"privacyRegisterMode" : "manual", //可选,仅iOS有效,设置为manual表示用户同意隐私政策后才获取idfv,设置为其它值表示应用启动时自动获取
|
||||
"dSYMs" : false
|
||||
},
|
||||
"sdkConfigs" : {
|
||||
//可选,JSON对象,三方SDK相关配置
|
||||
"geolocation" : {
|
||||
//可选,JSON对象,Geolocation(定位)模块三方SDK配置
|
||||
"system" : {
|
||||
//可选,JSON对象,使用系统定位
|
||||
"__platform__" : [ "ios", "android" ] //可选,字符串数组类型,支持的平台
|
||||
},
|
||||
"amap" : {
|
||||
//可选,JSON对象,使用高德定位SDK配置
|
||||
"__platform__" : [ "ios", "android" ], //可选,字符串数组类型,支持的平台
|
||||
"appkey_ios" : "", //必填,字符串类型,iOS平台高德定位appkey
|
||||
"appkey_android" : "" //必填,字符串类型,Android平台高德定位appkey
|
||||
},
|
||||
"baidu" : {
|
||||
//可选,JSON对象,使用百度定位SDK配置
|
||||
"__platform__" : [ "ios", "android" ], //可选,字符串数组类型,支持的平台
|
||||
"appkey_ios" : "", //必填,字符串类型,iOS平台百度定位appkey
|
||||
"appkey_android" : "" //必填,字符串类型,Android平台百度定位appkey
|
||||
}
|
||||
},
|
||||
"maps" : {
|
||||
//可选,JSON对象,Maps(地图)模块三方SDK配置
|
||||
"amap" : {
|
||||
//可选,JSON对象,使用高德地图SDK配置
|
||||
"appkey_ios" : "", //必填,字符串类型,iOS平台高德地图appkey
|
||||
"appkey_android" : "" //必填,字符串类型,Android平台高德地图appkey
|
||||
},
|
||||
"baidu" : {
|
||||
//可选,JSON对象,使用百度地图SDK配置
|
||||
"appkey_ios" : "", //必填,字符串类型,iOS平台百度地图appkey
|
||||
"appkey_android" : "" //必填,字符串类型,Android平台百度地图appkey
|
||||
},
|
||||
"google" : {
|
||||
//可选,JSON对象,使用Google地图SDK配置
|
||||
"APIKey_ios" : "", //必填,字符串类型,iOS平台Google地图APIKey
|
||||
"APIKey_android" : "" //必填,字符串类型,Android平台Google地图APIKey
|
||||
}
|
||||
},
|
||||
"oauth" : {
|
||||
//可选,JSON对象,使用苹果登录(Sign in with Apple)SDK配置,无配置参数,仅iOS平台支持
|
||||
"weixin" : {
|
||||
"appid" : "wx7c84ede33062d1e4",
|
||||
"UniversalLinks" : "https://yixiang.co/app/"
|
||||
}
|
||||
},
|
||||
"payment" : {
|
||||
"weixin" : {
|
||||
"__platform__" : [ "ios", "android" ],
|
||||
"appid" : "wx7c84ede33062d1e4",
|
||||
"UniversalLinks" : "https://yixiang.co/app/"
|
||||
}
|
||||
},
|
||||
//可选,JSON对象,使用google支付SDK配置,无配置参数,仅Android平台支持
|
||||
"push" : {
|
||||
//可选,JSON对象,Push(消息推送)模块三方SDK配置
|
||||
"unipush" : {
|
||||
//可选,JSON对象,使用UniPush SDK配置,无需手动配置参数,云端打包自动获取配置参数
|
||||
"icons" : {
|
||||
//可选,JSON对象,推送图标配置
|
||||
"push" : {
|
||||
//可选,JSON对象,Push图标配置
|
||||
"ldpi" : "", //可选,字符串类型,普通屏设备推送图标路径,分辨率要求48x48
|
||||
"mdpi" : "", //可选,字符串类型,大屏设备设备推送图标路径,分辨率要求48x48
|
||||
"hdpi" : "", //可选,字符串类型,高分屏设备推送图标路径,分辨率要求72x72
|
||||
"xdpi" : "", //可选,字符串类型,720P高分屏设备推送图标路径,分辨率要求96x96
|
||||
"xxdpi" : "", //可选,字符串类型,1080P高密度屏幕推送图标路径,分辨率要求144x144
|
||||
"xxxdpi" : "" //可选,字符串类型,4K屏设备推送图标路径,分辨率要求192x192
|
||||
},
|
||||
"smal" : {
|
||||
//可选,JSON对象,Push小图标配置
|
||||
"ldpi" : "", //可选,字符串类型,普通屏设备推送小图标路径,分辨率要求18x18
|
||||
"mdpi" : "", //可选,字符串类型,大屏设备设备推送小图标路径,分辨率要求24x24
|
||||
"hdpi" : "", //可选,字符串类型,高分屏设备推送小图标路径,分辨率要求36x36
|
||||
"xdpi" : "", //可选,字符串类型,720P高分屏设备推送小图标路径,分辨率要求48x48
|
||||
"xxdpi" : "", //可选,字符串类型,1080P高密度屏幕推送小图标路径,分辨率要求72x72
|
||||
"xxxdpi" : "" //可选,字符串类型,4K屏设备推送小图标路径,分辨率要求96x96
|
||||
}
|
||||
}
|
||||
},
|
||||
"igexin" : {
|
||||
//可选,JSON对象,使用个推推送SDK配置,**已废弃,推荐使用UniPush,UniPush是个推推送VIP版,功能更强大**
|
||||
"appid" : "", //必填,字符串类型,个推开放平台申请的appid
|
||||
"appkey" : "", //必填,字符串类型,个推开放平台申请的appkey
|
||||
"appsecret" : "", //必填,字符串类型,个推开放平台申请的appsecret
|
||||
"icons" : {
|
||||
//可选,JSON对象,推送图标配置
|
||||
"push" : {
|
||||
//可选,JSON对象,Push图标配置
|
||||
"ldpi" : "", //可选,字符串类型,普通屏设备推送图标路径,分辨率要求48x48
|
||||
"mdpi" : "", //可选,字符串类型,大屏设备设备推送图标路径,分辨率要求48x48
|
||||
"hdpi" : "", //可选,字符串类型,高分屏设备推送图标路径,分辨率要求72x72
|
||||
"xdpi" : "", //可选,字符串类型,720P高分屏设备推送图标路径,分辨率要求96x96
|
||||
"xxdpi" : "", //可选,字符串类型,1080P高密度屏幕推送图标路径,分辨率要求144x144
|
||||
"xxxdpi" : "" //可选,字符串类型,4K屏设备推送图标路径,分辨率要求192x192
|
||||
},
|
||||
"smal" : {
|
||||
//可选,JSON对象,Push小图标配置
|
||||
"ldpi" : "", //可选,字符串类型,普通屏设备推送小图标路径,分辨率要求18x18
|
||||
"mdpi" : "", //可选,字符串类型,大屏设备设备推送小图标路径,分辨率要求24x24
|
||||
"hdpi" : "", //可选,字符串类型,高分屏设备推送小图标路径,分辨率要求36x36
|
||||
"xdpi" : "", //可选,字符串类型,720P高分屏设备推送小图标路径,分辨率要求48x48
|
||||
"xxdpi" : "", //可选,字符串类型,1080P高密度屏幕推送小图标路径,分辨率要求72x72
|
||||
"xxxdpi" : "" //可选,字符串类型,4K屏设备推送小图标路径,分辨率要求96x96
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"share" : {
|
||||
//可选,JSON对象,Share(分享)模块三方SDK配置
|
||||
"weixin" : {
|
||||
//可选,JSON对象,使用微信分享SDK配置
|
||||
"appid" : "", //必填,字符串类型,微信开放平台申请的appid
|
||||
"UniversalLinks" : "" //可选,字符串类型,微信开放平台配置的iOS平台通用链接
|
||||
},
|
||||
"qq" : {
|
||||
//可选,JSON对象,使用QQ分享SDK配置
|
||||
"appid" : "", //必填,字符串类型,QQ开放平台申请的appid
|
||||
"UniversalLinks" : "" //可选,字符串类型,QQ开放平台配置的iOS平台通用链接
|
||||
},
|
||||
"sina" : {
|
||||
//可选,JSON对象,使用新浪微博分享SDK配置
|
||||
"appkey" : "", //必填,字符串类型,新浪微博开放平台申请的appid
|
||||
"redirect_uri" : "", //必填,字符串类型,新浪微博开放平台配置的redirect_uri
|
||||
"UniversalLinks" : "" //可选,字符串类型,新浪微博开放平台配置的iOS平台通用链接
|
||||
}
|
||||
},
|
||||
"speech" : {
|
||||
//可选,JSON对象,Speech(语音识别)模块三方SDK配置
|
||||
"baidu" : {
|
||||
//可选,JSON对象,使用百度语音识别SDK配置
|
||||
"appid" : "", //必填,字符串类型,百度开放平台申请的appid
|
||||
"apikey" : "", //必填,字符串类型,百度开放平台申请的apikey
|
||||
"secretkey" : "" //必填,字符串类型,百度开放平台申请的secretkey
|
||||
}
|
||||
},
|
||||
"statics" : {
|
||||
//可选,JSON对象,Statistic(统计)模块三方SDK配置
|
||||
"umeng" : {
|
||||
//可选,JSON对象,使用友盟统计SDK配置
|
||||
"appkey_ios" : "", //必填,字符串类型,友盟统计开放平台申请的iOS平台appkey
|
||||
"channelid_ios" : "", //可选,字符串类型,友盟统计iOS平台的渠道标识
|
||||
"appkey_android" : "", //必填,字符串类型,友盟统计开放平台申请的Android平台appkey
|
||||
"channelid_android" : "" //可选,字符串类型,友盟统计Android平台的渠道标识
|
||||
},
|
||||
"google" : {
|
||||
//可选,JSON对象,使用Google Analytics for Firebase配置
|
||||
"config_ios" : "", //必填,字符串类型,Google Firebase统计开发者后台获取的iOS平台配置文件路径
|
||||
"config_android" : "" //必填,字符串类型,Google Firebase统计开发者后台获取的Android平台配置文件路径
|
||||
}
|
||||
},
|
||||
"ad" : {}
|
||||
},
|
||||
//可选,JSON对象,使用互动游戏(变现猫)SDK,无需手动配置,在uni-AD后台申请开通后自动获取配置参数
|
||||
"icons" : {
|
||||
//可选,JSON对象,应用图标相关配置
|
||||
"ios" : {
|
||||
//可选,JSON对象,iOS平台图标配置
|
||||
"appstore" : "", //必填,字符串类型,分辨率1024x1024, 提交app sotre使用的图标路径
|
||||
"iphone" : {
|
||||
//可选,JSON对象,iPhone设备图标配置
|
||||
"app@2x" : "", //可选,字符串类型,分辨率120x120,程序图标路径
|
||||
"app@3x" : "", //可选,字符串类型,分辨率180x180,程序图标路径
|
||||
"spotlight@2x" : "", //可选,字符串类型,分辨率80x80,Spotlight搜索图标路径
|
||||
"spotlight@3x" : "", //可选,字符串类型,分辨率120x120,Spotlight搜索图标路径
|
||||
"settings@2x" : "", //可选,字符串类型,分辨率58x58,Settings设置图标路径
|
||||
"settings@3x" : "", //可选,字符串类型,分辨率87x87,Settings设置图标路径
|
||||
"notification@2x" : "", //可选,字符串类型,分辨率40x40,通知栏图标路径
|
||||
"notification@3x" : "" //可选,字符串类型,分辨率60x60,通知栏图标路径
|
||||
},
|
||||
"ipad" : {
|
||||
//可选,JSON对象,iPad设备图标配置
|
||||
"app" : "", //可选,字符串类型,分辨率76x76,程序图标图标路径
|
||||
"app@2x" : "", //可选,字符串类型,分辨率152x152,程序图标图标路径
|
||||
"proapp@2x" : "", //可选,字符串类型,分辨率167x167,程序图标图标路径
|
||||
"spotlight" : "", //可选,字符串类型,分辨率40x40,Spotlight搜索图标路径
|
||||
"spotlight@2x" : "", //可选,字符串类型,分辨率80x80,Spotlight搜索图标路径
|
||||
"settings" : "", //可选,字符串类型,分辨率29x29,Settings设置图标路径
|
||||
"settings@2x" : "", //可选,字符串类型,分辨率58x58,Settings设置图标路径
|
||||
"notification" : "", //可选,字符串类型,分辨率20x20,通知栏图标路径
|
||||
"notification@2x" : "" //可选,字符串类型,分辨率740x40,通知栏图标路径
|
||||
}
|
||||
},
|
||||
"android" : {
|
||||
//可选,JSON对象,Android平台图标配置
|
||||
"ldpi" : "", //可选,字符串类型,普通屏设备程序图标,分辨率要求48x48,已废弃
|
||||
"mdpi" : "", //可选,字符串类型,大屏设备程序图标,分辨率要求48x48,已废弃
|
||||
"hdpi" : "", //可选,字符串类型,高分屏设备程序图标,分辨率要求72x72
|
||||
"xhdpi" : "", //可选,字符串类型,720P高分屏设备程序图标,分辨率要求96x96
|
||||
"xxhdpi" : "", //可选,字符串类型,1080P高分屏设备程序图标,分辨率要求144x144
|
||||
"xxxhdpi" : "" //可选,字符串类型,2K屏设备程序图标,分辨率要求192x192
|
||||
}
|
||||
},
|
||||
"splashscreen" : {
|
||||
//可选,JSON对象,启动界面配置
|
||||
"iosStyle" : "common", //可选,字符串类型,iOS平台启动界面样式,可取值common、default、storyboard
|
||||
"ios" : {
|
||||
//可选,JSON对象,iOS平台启动界面配置
|
||||
"storyboard" : "", //可选,字符串类型,自定义storyboard启动界面文件路径,iosStyle值为storyboard时生效
|
||||
"iphone" : {
|
||||
//可选,JSON对象,iPhone设备启动图配置,iosStyle值为default时生效
|
||||
"default" : "", //可选,字符串类型,分辨率320x480,iPhone3(G/GS)启动图片路径,已废弃
|
||||
"retina35" : "", //可选,字符串类型,分辨率640x960,3.5英寸设备(iPhone4/4S)启动图片路径,已废弃
|
||||
"retina40" : "", //可选,字符串类型,分辨率640x1136,4.0英寸设备(iPhone5/5S)启动图片路径
|
||||
"retina40l" : "", //可选,字符串类型,分辨率1136x640,4.0英寸设备(iPhone5/5S)横屏启动图片路径
|
||||
"retina47" : "", //可选,字符串类型,分辨率750x1334,4.7英寸设备(iPhone6/7/8)启动图片路径
|
||||
"retina47l" : "", //可选,字符串类型,分辨率1334x750,4.7英寸设备(iPhone6/7/8)横屏启动图片路径
|
||||
"retina55" : "", //可选,字符串类型,分辨率1242x2208,5.5英寸设备(iPhone6/7/8Plus)启动图片路径
|
||||
"retina55l" : "", //可选,字符串类型,分辨率2208x1242,5.5英寸设备(iPhone6/7/8Plus)横屏启动图片路径
|
||||
"iphonex" : "", //可选,字符串类型,分辨率1125x2436,5.8英寸设备(iPhoneX/XS)启动图片路径
|
||||
"iphonexl" : "", //可选,字符串类型,分辨率2436x1125,5.8英寸设备(iPhoneX/XS)横屏启动图片路径
|
||||
"portrait-896h@2x" : "", //可选,字符串类型,分辨率828x1792,6.1英寸设备(iPhoneXR)启动图片路径
|
||||
"landscape-896h@2x" : "", //可选,字符串类型,分辨率1792x828,6.1英寸设备(iPhoneXR)iPhoneXR横屏启动图片路径
|
||||
"portrait-896h@3x" : "", //可选,字符串类型,分辨率1242x2688,6.5英寸设备(iPhoneXS Max)启动图片路径
|
||||
"landscape-896h@3x" : "" //可选,字符串类型,分辨率2688x1242,6.5英寸设备(iPhoneXS Max)横屏启动图片路径
|
||||
},
|
||||
"ipad" : {
|
||||
//可选,JSON对象,iPad设备启动图配置,iosStyle值为default时生效
|
||||
"portrait" : "", //可选,字符串类型,分辨率768x1004,iPad竖屏启动图片路径,已废弃
|
||||
"portrait-retina" : "", //可选,字符串类型,分辨率1536x2008,iPad高分屏竖屏启动图片路径,已废弃
|
||||
"landscape" : "", //可选,字符串类型,分辨率1024x748,iPad横屏启动图片路径,已废弃
|
||||
"landscape-retina" : "", //可选,字符串类型,分辨率2048x1496,iPad高分屏横屏启动图片路径,已废弃
|
||||
"portrait7" : "", //可选,字符串类型,分辨率768x1024,9.7/7.9英寸iPad/mini竖屏启动图片路径
|
||||
"landscape7" : "", //可选,字符串类型,分辨率1024x768,9.7/7.9英寸iPad/mini横屏启动图片路径
|
||||
"portrait-retina7" : "", //可选,字符串类型,分辨率1536x2048,9.7/7.9英寸iPad/mini高分屏竖屏图片路径
|
||||
"landscape-retina7" : "", //可选,字符串类型,分辨率2048x1536,9.7/7.9英寸iPad/mini高分屏横屏启动图片路径
|
||||
"portrait-1112h@2x" : "", //可选,字符串类型,分辨率1668x2224,10.5英寸iPad Pro竖屏启动图片路径
|
||||
"landscape-1112h@2x" : "", //可选,字符串类型,分辨率2224x1668,10.5英寸iPad Pro横屏启动图片路径
|
||||
"portrait-1194h@2x" : "", //可选,字符串类型,分辨率1668x2388,11英寸iPad Pro竖屏启动图片路径
|
||||
"landscape-1194h@2x" : "", //可选,字符串类型,分辨率2388x1668,11英寸iPad Pro横屏启动图片路径
|
||||
"portrait-1366h@2x" : "", //可选,字符串类型,分辨率2048x2732,12.9英寸iPad Pro竖屏启动图片路径
|
||||
"landscape-1366h@2x" : "" //可选,字符串类型,分辨率2732x2048,12.9英寸iPad Pro横屏启动图片路径
|
||||
}
|
||||
},
|
||||
"androidStyle" : "common", //可选,字符串类型,Android平台启动界面样式,可取值common、default
|
||||
"android" : {
|
||||
//可选,JSON对象,Android平台启动图片配置, androidStyle值为default时生效
|
||||
"ldpi" : "", //可选,字符串类型,分辨率320x442,低密度屏幕启动图片路径,已废弃
|
||||
"mdpi" : "", //可选,字符串类型,分辨率240x282,中密度屏幕启动图片路径,已废弃
|
||||
"hdpi" : "", //可选,字符串类型,分辨率480x762,高密度屏幕启动图片路径
|
||||
"xhdpi" : "", //可选,字符串类型,分辨率720x1242,720P高密度屏幕启动图片路径
|
||||
"xxhdpi" : "" //可选,字符串类型,分辨率1080x1882,1080P高密度屏幕启动图片路径
|
||||
}
|
||||
},
|
||||
"orientation" : [
|
||||
//可选,字符串数组类型,应用支持的横竖屏,**已废弃,使用screenOrientation配置**
|
||||
"portrait-primary",
|
||||
"portrait-secondary",
|
||||
"landscape-primary",
|
||||
"landscape-secondary"
|
||||
]
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "wx001e2dc50bf532df",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true,
|
||||
"permission" : {
|
||||
"scope.userLocation" : {
|
||||
"desc" : "定位最近的门店"
|
||||
}
|
||||
},
|
||||
"requiredPrivateInfos" : [ "getLocation", "chooseLocation" ]
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
},
|
||||
"vueVersion" : "3",
|
||||
"fallbackLocale" : "zh-Hans",
|
||||
"h5" : {
|
||||
"router" : {
|
||||
"base" : "/h5/"
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 模块配置 *//* 应用发布信息 *//* android打包配置 */
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
{
|
||||
"name": "yshop-miniapp",
|
||||
"version": "1.2.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@vant/area-data": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vant/area-data/-/area-data-1.5.0.tgz",
|
||||
"integrity": "sha512-SWmDhYmWiOgtAgtJqcW7N4XyGgrg/7l6t1+XSgt8BkPp2oOKO1ZUn8+46brLpT/gzRe/v8BtyTLmdBwMamrmQw=="
|
||||
},
|
||||
"@vant/popperjs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
|
||||
"integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
|
||||
},
|
||||
"@vant/use": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.5.2.tgz",
|
||||
"integrity": "sha512-CBK61iT568dCHUwFFsErGbW6/5tmrPnZJKGtcSy7Tjcrmws8Ku+YZo7IUFD9Xkj9MfSJ4pfhQ7pU2KouP5Cojg=="
|
||||
},
|
||||
"@vue/devtools-api": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
|
||||
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
|
||||
},
|
||||
"@vue/shared": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz",
|
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
|
||||
},
|
||||
"add": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/add/-/add-2.0.6.tgz",
|
||||
"integrity": "sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q=="
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmmirror.com/asn1/-/asn1-0.2.6.tgz",
|
||||
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmmirror.com/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA=="
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmmirror.com/aws4/-/aws4-1.12.0.tgz",
|
||||
"integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmmirror.com/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmmirror.com/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g=="
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"flyio": {
|
||||
"version": "0.6.14",
|
||||
"resolved": "https://registry.npmmirror.com/flyio/-/flyio-0.6.14.tgz",
|
||||
"integrity": "sha512-RE2OXE1ZZmcXOKb0jCtGyquHDxpAqHg17CZ8lmQKRfl3x1kP+NBpaQDx4WgN7DNpLJjFnspTzTEQpwRGg6/xaA==",
|
||||
"requires": {
|
||||
"request": "^2.85.0"
|
||||
}
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw=="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmmirror.com/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q=="
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmmirror.com/har-validator/-/har-validator-5.1.5.tgz",
|
||||
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
|
||||
"requires": {
|
||||
"ajv": "^6.12.3",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz",
|
||||
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmmirror.com/jsprim/-/jsprim-1.4.2.tgz",
|
||||
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.4.0",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"jweixin-module": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/jweixin-module/-/jweixin-module-1.6.0.tgz",
|
||||
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"requires": {
|
||||
"mime-db": "1.52.0"
|
||||
}
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmmirror.com/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
|
||||
},
|
||||
"pinia": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.6.tgz",
|
||||
"integrity": "sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==",
|
||||
"requires": {
|
||||
"@vue/devtools-api": "^6.5.0",
|
||||
"vue-demi": ">=0.14.5"
|
||||
}
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmmirror.com/psl/-/psl-1.9.0.tgz",
|
||||
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz",
|
||||
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.5.3.tgz",
|
||||
"integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA=="
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.2",
|
||||
"resolved": "https://registry.npmmirror.com/request/-/request-2.88.2.tgz",
|
||||
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmmirror.com/sshpk/-/sshpk-1.17.0.tgz",
|
||||
"integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"requires": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmmirror.com/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||
},
|
||||
"vant": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmmirror.com/vant/-/vant-4.6.2.tgz",
|
||||
"integrity": "sha512-6EHCCAGM5a9VVzpBg/wZNPDFmJ8T1a4k29DPNcEMW3X670awW3rnD7+/x3dw+bE17JhhSg49V/+fQwBP2iQkAg==",
|
||||
"requires": {
|
||||
"@vant/popperjs": "^1.3.0",
|
||||
"@vant/use": "^1.5.1",
|
||||
"@vue/shared": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"extsprintf": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.4.1.tgz",
|
||||
"integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-demi": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.5.tgz",
|
||||
"integrity": "sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA=="
|
||||
},
|
||||
"weixin-js-sdk": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmmirror.com/weixin-js-sdk/-/weixin-js-sdk-1.6.3.tgz",
|
||||
"integrity": "sha512-5jYNtVcxWmgHNqCLSPoX6vXab9G4RPDZx0klX8IsVwGjDTwx/UDmgfF7fkRMGguRpuFv0O7tk1jb+Oay2QiV1w=="
|
||||
},
|
||||
"yarn": {
|
||||
"version": "1.22.19",
|
||||
"resolved": "https://registry.npmmirror.com/yarn/-/yarn-1.22.19.tgz",
|
||||
"integrity": "sha512-/0V5q0WbslqnwP91tirOvldvYISzaqhClxzyUKXYxs07yUILIs5jx/k6CFe8bvKSkds5w+eiOqta39Wk3WxdcQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "yshop-miniapp",
|
||||
"version": "1.2.0",
|
||||
"description": "",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@vant/area-data": "^1.5.0",
|
||||
"add": "^2.0.6",
|
||||
"flyio": "^0.6.14",
|
||||
"jweixin-module": "^1.6.0",
|
||||
"pinia": "^2.1.6",
|
||||
"vant": "^4.6.2",
|
||||
"weixin-js-sdk": "^1.6.3",
|
||||
"yarn": "^1.22.19"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path" : "pages/menu/menu",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
|
||||
}
|
||||
,{
|
||||
"path" : "pages/order/order",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
|
||||
}
|
||||
,{
|
||||
"path" : "pages/mine/mine",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
|
||||
}
|
||||
,{
|
||||
"path" : "pages/cart/cart",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
}
|
||||
],
|
||||
"subPackages": [{
|
||||
"root": "pages/components",
|
||||
"pages": [ {
|
||||
"path": "pages/mine/content",
|
||||
"style": {
|
||||
"navigationBarTitleText": "内容",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/pay/pay",
|
||||
"style": {
|
||||
"navigationBarTitleText": "支付",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/remark/remark",
|
||||
"style": {
|
||||
"navigationBarTitleText": "备注",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/packages/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "可用优惠券",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/login",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/logout",
|
||||
"style": {
|
||||
"navigationBarTitleText": "退出登录"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/address/address",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的地址",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/address/add",
|
||||
"style": {
|
||||
"navigationBarTitleText": "添加地址",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/orders/orders",
|
||||
"style": {
|
||||
"navigationBarTitleText": "历史订单",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"enablePullDownRefresh": true,
|
||||
"onReachBottomDistance": 50
|
||||
}
|
||||
}, {
|
||||
"path": "pages/orders/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "订单详情",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/coupons/coupons",
|
||||
"style": {
|
||||
"enablePullDownRefresh": true,
|
||||
"navigationBarTitleText": "我的卡券",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/mine/userinfo",
|
||||
"style": {
|
||||
"navigationBarTitleText": "用户信息",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/shop/shop",
|
||||
"style": {
|
||||
"navigationBarTitleText": "店铺",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/balance/bill",
|
||||
"style": {
|
||||
"navigationBarTitleText": "账单",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}
|
||||
,{
|
||||
"path" : "pages/orders/refund",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
}],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": " ",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8",
|
||||
"navigationStyle": "custom"
|
||||
},
|
||||
"tabBar": {
|
||||
"color": "#919293",
|
||||
"selectedColor": "#dd524d",
|
||||
"backgroundColor": "#fff",
|
||||
"borderStyle": "black",
|
||||
"list": [{
|
||||
"pagePath": "pages/index/index",
|
||||
"text": "首页",
|
||||
"iconPath": "static/images/tabBar/index.png",
|
||||
"selectedIconPath": "static/images/tabBar/index_selected.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/menu/menu",
|
||||
"text": "点餐",
|
||||
"iconPath": "static/images/tabBar/drink.png",
|
||||
"selectedIconPath": "static/images/tabBar/drink-selected.png"
|
||||
}, {
|
||||
"pagePath": "pages/cart/cart",
|
||||
"text": "购物车",
|
||||
"iconPath": "static/images/tabBar/cart.png",
|
||||
"selectedIconPath": "static/images/tabBar/cart-selected.png"
|
||||
},{
|
||||
"pagePath": "pages/order/order",
|
||||
"text": "订单",
|
||||
"iconPath": "static/images/tabBar/order.png",
|
||||
"selectedIconPath": "static/images/tabBar/order-selected.png"
|
||||
}, {
|
||||
"pagePath": "pages/mine/mine",
|
||||
"text": "我的",
|
||||
"iconPath": "static/images/tabBar/mine.png",
|
||||
"selectedIconPath": "static/images/tabBar/mine_selected.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
"uniIdRouter": {}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="cart-popup">
|
||||
<view class="top flex justify-between">
|
||||
<text>已点{{ getCartGoodsNumber }}份</text>
|
||||
<text @tap="handleCartClear">清空</text>
|
||||
</view>
|
||||
<scroll-view class="cart-list" scroll-y>
|
||||
<view class="wrapper">
|
||||
<uv-empty mode="car" v-if="cart.length == 0"></uv-empty>
|
||||
<view class="item" v-for="(item, index) in cart" :key="index">
|
||||
<view class="left">
|
||||
<view class="name">{{ item.name }}</view>
|
||||
<view class="props">{{ item.valueStr }}</view>
|
||||
</view>
|
||||
<view class="center">
|
||||
<text>¥{{ item.price }}</text>
|
||||
</view>
|
||||
<view class="right">
|
||||
<button type="default" plain size="mini" class="btn" hover-class="none"
|
||||
@tap="handleCartItemReduce(index)">
|
||||
<view class="iconfont iconsami-select"></view>
|
||||
</button>
|
||||
<view class="number">{{ item.number }}</view>
|
||||
<button type="primary" class="btn" size="min" hover-class="none"
|
||||
@tap="handleCartItemAdd(index)">
|
||||
<view class="iconfont iconadd-select"></view>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="fixed-bottom flex justify-between align-center bg-white ">
|
||||
<view class="mx-2 ont-weight-light">应付:<text class="text-danger">¥{{ getCartGoodsPrice }}</text></view>
|
||||
<view><uv-button type="warning" color="#dd524d" :customStyle="customStyle" size="large" text="去结算" @click="toPay"></uv-button></view>
|
||||
</view>
|
||||
<uv-toast ref="uToast"></uv-toast>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow} from '@dcloudio/uni-app'
|
||||
const main = useMainStore()
|
||||
const { orderType,address, store,location,isLogin } = storeToRefs(main)
|
||||
const title = ref('购物车')
|
||||
const cart = ref([])
|
||||
const uToast = ref()
|
||||
|
||||
// onLoad(() => {
|
||||
// cart.value = uni.getStorageSync('cart')
|
||||
// })
|
||||
onShow(() => {
|
||||
//cart.value = []
|
||||
cart.value = uni.getStorageSync('cart')
|
||||
})
|
||||
const getCartGoodsNumber = computed(() => { //计算购物车总数
|
||||
if(cart.value.length == 0) {
|
||||
return 0
|
||||
}
|
||||
return cart.value.reduce((acc, cur) => acc + cur.number, 0)
|
||||
})
|
||||
const getCartGoodsPrice = computed(() =>{ //计算购物车总价
|
||||
if(cart.value.length == 0) {
|
||||
return 0
|
||||
}
|
||||
let price = cart.value.reduce((acc, cur) => acc + cur.number * cur.price, 0);
|
||||
return parseFloat(price).toFixed(2);
|
||||
})
|
||||
const customStyle = computed(() =>{
|
||||
return {
|
||||
paddingLeft:'60rpx',
|
||||
paddingRight:'60rpx'
|
||||
}
|
||||
})
|
||||
const handleCartItemAdd = (index) => {
|
||||
cart.value[index].number += 1
|
||||
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
||||
}
|
||||
const handleCartItemReduce = (index) => {
|
||||
if (cart.value[index].number === 1) {
|
||||
cart.value.splice(index, 1)
|
||||
} else {
|
||||
cart.value[index].number -= 1
|
||||
}
|
||||
if (!cart.value.length) {
|
||||
cartPopupVisible.value = false
|
||||
}
|
||||
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
||||
}
|
||||
const handleCartClear = () => { //清空购物车
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定清空购物车么',
|
||||
success: ({
|
||||
confirm
|
||||
}) => {
|
||||
if (confirm) {
|
||||
cart.value = []
|
||||
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
const toPay = () => {
|
||||
|
||||
if(cart.value.length == 0){
|
||||
uToast.value.show({message:'请先去点餐哦',type: 'error'});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isLogin.value) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/login/login'
|
||||
})
|
||||
return
|
||||
} else {
|
||||
if (store.value.status == 0) {
|
||||
uToast.value.show({message:'不在店铺营业时间内',type: 'error'});
|
||||
return;
|
||||
}
|
||||
// 判断当前是否在配送范围内
|
||||
if (orderType.value == 'takeout' && store.value.distance < store.value.far) {
|
||||
uToast.value.show({message:'选中的地址不在配送范围',type: 'error'});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
})
|
||||
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
||||
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/pay/pay'
|
||||
})
|
||||
}
|
||||
|
||||
uni.hideLoading()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cart-popup {
|
||||
.top {
|
||||
background-color: $bg-color-primary;
|
||||
//color: $color-primary;
|
||||
color: #5A5B5C;
|
||||
padding: 10rpx 30rpx;
|
||||
font-size: 24rpx;
|
||||
text-align: right;
|
||||
}
|
||||
.cart-list {
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
min-height: 1vh;
|
||||
max-height: 60vh;
|
||||
|
||||
.wrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: 156rpx;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx 0;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: $border-color;
|
||||
height: 2rpx;
|
||||
transform: scaleY(0.6);
|
||||
}
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin-right: 30rpx;
|
||||
|
||||
.name {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-color-base;
|
||||
}
|
||||
.props {
|
||||
color: $text-color-assist;
|
||||
font-size: 24rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-right: 120rpx;
|
||||
font-size: $font-size-base;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn {
|
||||
width: 46rpx;
|
||||
height: 46rpx;
|
||||
border-radius: 100%;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
line-height: 46rpx;
|
||||
}
|
||||
|
||||
.number {
|
||||
font-size: $font-size-base;
|
||||
width: 46rpx;
|
||||
height: 46rpx;
|
||||
text-align: center;
|
||||
line-height: 46rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container">
|
||||
<view class="form-box">
|
||||
<view class="form">
|
||||
<list-cell :hover="false">
|
||||
<view class="form-input">
|
||||
<view class="label">收货人</view>
|
||||
<input class="input" placeholder="请输入收货人" v-model="form.realName" placeholder-class="text-color-assist" />
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false">
|
||||
<view class="form-input">
|
||||
<view class="label">联系方式</view>
|
||||
<input class="input" placeholder="请输入收货人联系方式" v-model="form.phone" placeholder-class="text-color-assist" />
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false">
|
||||
<view class="form-input">
|
||||
<view class="label">收货地址</view>
|
||||
<view class="input" @click="chooseLocation">{{form.address ? form.address : '请选择收货地址'}}</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false">
|
||||
<view class="form-input">
|
||||
<view class="label">详细地址</view>
|
||||
<input class="input" placeholder="请输入收货人详细地址" v-model="form.detail" placeholder-class="text-color-assist" />
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false">
|
||||
<view class="form-input">
|
||||
<view class="label">默认地址</view>
|
||||
<view class="radio-group">
|
||||
<view class="radio" :class="{'checked': !form.isDefault}" style="margin-right: 10rpx;" @tap="form.isDefault=0">否</view>
|
||||
<view class="radio" :class="{'checked': form.isDefault}" @tap="form.isDefault=1">是</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
</view>
|
||||
<view class="btn-section">
|
||||
<button type="primary" size="default" @tap="save">保存</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow } from '@dcloudio/uni-app'
|
||||
import { formatDateTime,prePage } from '@/utils/util'
|
||||
import {
|
||||
getAddressAddAndEdit
|
||||
} from '@/api/address'
|
||||
const main = useMainStore()
|
||||
const { isLogin,addresses } = storeToRefs(main)
|
||||
const title = ref('编辑地址')
|
||||
|
||||
const form = ref({
|
||||
realName: '',
|
||||
isDefault: 0,
|
||||
phone: '',
|
||||
address: '',
|
||||
detail: '',
|
||||
latitude: '',
|
||||
longitude: ''
|
||||
})
|
||||
|
||||
onLoad((option) => {
|
||||
//为了方便演示,这里用本地缓存
|
||||
console.log('option:',option)
|
||||
if (option.id) {
|
||||
form.value = addresses.value.find(item => item.id == option.id)
|
||||
}
|
||||
})
|
||||
|
||||
const save = async() => {
|
||||
let data = {}
|
||||
if (form.value.hasOwnProperty('id')) {
|
||||
data = await getAddressAddAndEdit(form.value);
|
||||
} else {
|
||||
data = await getAddressAddAndEdit(form.value);
|
||||
}
|
||||
if (data) {
|
||||
setTimeout(function(){
|
||||
uni.navigateBack()
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
const chooseLocation = async() => {
|
||||
uni.chooseLocation({
|
||||
success: function (res) {
|
||||
form.value.address = res.address + ' ' + res.name;
|
||||
form.value.latitude = res.latitude;
|
||||
form.value.longitude = res.longitude;
|
||||
}
|
||||
});
|
||||
// let [error, res] = await uni.chooseLocation();
|
||||
// if (res) {
|
||||
// form.value.address = res.address + ' ' + res.name;
|
||||
// form.value.latitude = res.latitude;
|
||||
// form.value.longitude = res.longitude;
|
||||
// }
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: $text-color-base;
|
||||
|
||||
.form-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 200rpx;
|
||||
font-size: $font-size-lg;
|
||||
color: $text-color-base;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.input {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.radio-group {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
.radio {
|
||||
padding: 10rpx 30rpx;
|
||||
border-radius: 6rpx;
|
||||
border: 2rpx solid $text-color-assist;
|
||||
color: $text-color-assist;
|
||||
font-size: $font-size-base;
|
||||
|
||||
&.checked {
|
||||
background-color: $color-primary;
|
||||
color: $text-color-white;
|
||||
border: 2rpx solid $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-section {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
font-size: $font-size-base;
|
||||
height: 90rpx;
|
||||
border-radius: 50rem !important;
|
||||
width: 85%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container">
|
||||
<view class="main">
|
||||
<uv-empty v-if="addresses.length == 0" mode="address"></uv-empty>
|
||||
<template v-else>
|
||||
<uv-swipe-action>
|
||||
<uv-swipe-action-item class="address-wrapper" :options="swipeOption"
|
||||
@click="handleSwipeClick(address.id)" v-for="(address, index) in addresses" :key="index">
|
||||
<view class="address" @tap="chooseAddress(address)">
|
||||
<view class="left flex-fill overflow-hidden mr-20">
|
||||
<view class="font-size-lg font-weight-bold text-truncate"
|
||||
style="margin-bottom: 10rpx;white-space:normal;">
|
||||
{{ address.address + ' ' + address.detail }}
|
||||
</view>
|
||||
<view class="font-size-sm text-color-assist">
|
||||
{{ address.realName }} {{ address.isDefault ? '默认' : '' }} {{ address.phone }}
|
||||
</view>
|
||||
</view>
|
||||
<image src="/static/images/edit.png" class="edit-icon" @tap.stop="edit(address.id)"></image>
|
||||
</view>
|
||||
</uv-swipe-action-item>
|
||||
</uv-swipe-action>
|
||||
</template>
|
||||
</view>
|
||||
<view class="btn-box">
|
||||
<button type="primary" size="default" @tap="add">新增地址</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow } from '@dcloudio/uni-app'
|
||||
import { formatDateTime,prePage } from '@/utils/util'
|
||||
import {
|
||||
addressAll,
|
||||
addressDelete,
|
||||
shopGetDistanceFromLocation
|
||||
} from '@/api/address'
|
||||
const main = useMainStore()
|
||||
const { isLogin,addresses,store } = storeToRefs(main)
|
||||
const title = ref('我的地址')
|
||||
|
||||
const scene = ref('menu')
|
||||
const is_choose = ref(false)
|
||||
const swipeOption = ref(
|
||||
[{
|
||||
text: '删除',
|
||||
style: {
|
||||
backgroundColor: '#D12E32'
|
||||
}
|
||||
}])
|
||||
|
||||
onLoad((option) => {
|
||||
console.log('option:',option)
|
||||
is_choose.value = option.is_choose || false
|
||||
scene.value = option.scene || 'menu'
|
||||
})
|
||||
onShow(() => {
|
||||
init();
|
||||
})
|
||||
|
||||
const init = async() => {
|
||||
let data = await addressAll();
|
||||
if (data) {
|
||||
main.SET_ADDRESSES(data)
|
||||
}
|
||||
}
|
||||
const add = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/address/add'
|
||||
})
|
||||
}
|
||||
const edit = (id) => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/address/add?id=' + id
|
||||
})
|
||||
}
|
||||
const handleSwipeClick = async(id) => {
|
||||
let [error, res] = await uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要删除?'
|
||||
});
|
||||
if (res && res.confirm) {
|
||||
let data = await addressDelete({
|
||||
id: id
|
||||
});
|
||||
if (data) {
|
||||
const index = addresses.value.findIndex(item => item.id == id)
|
||||
const newaddresses = JSON.parse(JSON.stringify(addresses.value))
|
||||
newaddresses.splice(index, 1)
|
||||
main.SET_ADDRESSES(newaddresses)
|
||||
uni.showToast({
|
||||
title: '删除成功!',
|
||||
icon: 'success'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
const chooseAddress = async(address) => {
|
||||
if (!is_choose.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('scene.value:',scene.value)
|
||||
|
||||
if (scene.value == 'menu' || scene.value == 'pay') {
|
||||
let data = await shopGetDistanceFromLocation({
|
||||
lat: address.latitude,
|
||||
lng: address.longitude,
|
||||
lat2: main.store.lat,
|
||||
lng2: main.store.lng
|
||||
});
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parseFloat(data) > store.value.distance) {
|
||||
uni.showToast({
|
||||
title: '不在配送范围!',
|
||||
icon: 'error'
|
||||
})
|
||||
return;
|
||||
}
|
||||
main.SET_ADDRESS(address)
|
||||
main.SET_ORDER_TYPE('takeout')
|
||||
main.store.far = data
|
||||
main.store.far_text = data + 'km'
|
||||
main.SET_STORE(main.store)
|
||||
main.SET_LOCATION({
|
||||
latitude: address.lat,
|
||||
longitude: address.lng
|
||||
});
|
||||
|
||||
if (scene.value == 'menu') {
|
||||
uni.switchTab({
|
||||
url: '/pages/menu/menu'
|
||||
})
|
||||
} else if (scene.value == 'pay') {
|
||||
uni.navigateBack();
|
||||
}
|
||||
} else if (scene.value == 'scoreShop') {
|
||||
main.SET_ADDRESS(address)
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.main {
|
||||
width: 100%;
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 100rpx;
|
||||
|
||||
.address-wrapper {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.address {
|
||||
width: 100%;
|
||||
padding: 40rpx 30rpx;
|
||||
background-color: #FFFFFF;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.edit-icon {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
height: 100rpx;
|
||||
background-color: #FFFFFF;
|
||||
box-shadow: 0 0 20rpx rgba($color: $text-color-assist, $alpha: 0.1);
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 10rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
height: 80rpx;
|
||||
width: 80%;
|
||||
border-radius: 50rem !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view>
|
||||
<view class="wrap">
|
||||
<view class="bg-white" v-if="cate == 0">
|
||||
<uv-tabs activeColor="#f29100" ref="tabs" :list="list" :current="current" @change="change" :scrollable="false" swiperWidth="750"></uv-tabs>
|
||||
</view>
|
||||
<view class="bg-white" v-else>
|
||||
<uv-tabs activeColor="#f29100" ref="tabs" :list="list1" :current="current" @change="change" :scrollable="false" swiperWidth="750"></uv-tabs>
|
||||
</view>
|
||||
<swiper class="swiper-box" :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish">
|
||||
|
||||
<swiper-item class="swiper-item" v-for="(item, index) in orderList" :key="index">
|
||||
<scroll-view scroll-y style="height: 100%;width: 100%;" @scrolltolower="reachBottom">
|
||||
<view class="page-box">
|
||||
<view v-if="item.length == 0">
|
||||
<view class="centre" v-if="loadStatus[index] != 'loading'">
|
||||
<view class="explain">
|
||||
您还没有相关的账单
|
||||
<view class="tips">可以去看看有那些想买的</view>
|
||||
</view>
|
||||
<view class="btn">
|
||||
<navigator open-type="switchTab" url="/pages/menu/menu">随便逛逛</navigator>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<u-loadmore :status="loadStatus[index]" bgColor="#f2f2f2"></u-loadmore>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="order" v-for="(res, resIndex) in orderList[index]" :key="resIndex">
|
||||
<view class="type">
|
||||
<view>{{res.title}}</view>
|
||||
<view>{{res.mark}}</view>
|
||||
</view>
|
||||
<view class="total">
|
||||
<view>
|
||||
{{res.pm == 0 ? '-':'+'}}¥{{res.number}}元
|
||||
</view>
|
||||
<view>
|
||||
{{formatDateTime(res.createTime)}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-loadmore :status="loadStatus[index]" bgColor="#f2f2f2"></u-loadmore>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
watch
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow} from '@dcloudio/uni-app'
|
||||
import { formatDateTime } from '@/utils/util'
|
||||
import {
|
||||
balanceGetBillList
|
||||
} from '@/api/user'
|
||||
const main = useMainStore()
|
||||
const { isLogin } = storeToRefs(main)
|
||||
const title = ref('账单')
|
||||
const orderList = ref([[], [], [], []])
|
||||
const list = ref([
|
||||
{
|
||||
name: '全部'
|
||||
},
|
||||
{
|
||||
name: '消费'
|
||||
},
|
||||
{
|
||||
name: '充值'
|
||||
},
|
||||
{
|
||||
name: '退款'
|
||||
}
|
||||
]
|
||||
)
|
||||
const list1 = ref([
|
||||
{
|
||||
name: '全部'
|
||||
},
|
||||
{
|
||||
name: '消费'
|
||||
}
|
||||
]
|
||||
)
|
||||
const current = ref(0)
|
||||
const swiperCurrent = ref(0)
|
||||
const tabsHeight =ref(0)
|
||||
const dx = ref(0)
|
||||
const loadStatus = ref(['loadmore','loadmore','loadmore','loadmore'])
|
||||
const page = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const tabs = ref()
|
||||
const cate = ref(0)
|
||||
|
||||
onLoad((option) => {
|
||||
console.log('cate:',option.cate)
|
||||
cate.value = option.cate
|
||||
getBill();
|
||||
})
|
||||
|
||||
const getBill = async() => {
|
||||
if (loadStatus.value[swiperCurrent.value] == 'loading') {
|
||||
return;
|
||||
}
|
||||
loadStatus.value.splice(swiperCurrent.value,1,"loading")
|
||||
let data = await balanceGetBillList({cate:cate.value,type:swiperCurrent.value,page:page.value,pagesize:pageSize.value});
|
||||
if (page.value == 1 ){
|
||||
orderList.value[swiperCurrent.value] = [];
|
||||
}
|
||||
if (data && data.length > 0) {
|
||||
page.value++;
|
||||
orderList.value[swiperCurrent.value] = orderList.value[swiperCurrent.value].concat(data);
|
||||
|
||||
loadStatus.value.splice(swiperCurrent.value,1,"loadmore")
|
||||
} else{
|
||||
loadStatus.value.splice(swiperCurrent.value,1,"nomore")
|
||||
}
|
||||
}
|
||||
const reachBottom = () => {
|
||||
if (loadStatus.value[swiperCurrent.value] == 'nomore') {
|
||||
return;
|
||||
}
|
||||
getBill();
|
||||
}
|
||||
// tab栏切换
|
||||
const change = (e) => {
|
||||
swiperCurrent.value = e.index;
|
||||
page.value = 1;
|
||||
}
|
||||
const transition = ({ detail: { dx } }) => {
|
||||
}
|
||||
const animationfinish = ({ detail }) => {
|
||||
swiperCurrent.value = detail.current;
|
||||
current.value = detail.current;
|
||||
page.value = 1;
|
||||
getBill();
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* #ifndef H5 */
|
||||
page {
|
||||
height: 100%;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
/* #endif */
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order {
|
||||
width: 710rpx;
|
||||
background-color: #ffffff;
|
||||
margin: 20rpx auto;
|
||||
border-radius: 20rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
.total {
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
|
||||
.total-price {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
float: right;
|
||||
}
|
||||
.type {
|
||||
display: inline-block;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
.centre {
|
||||
text-align: center;
|
||||
margin: 200rpx auto;
|
||||
font-size: 32rpx;
|
||||
image {
|
||||
width: 164rpx;
|
||||
height: 164rpx;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.tips {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
.btn {
|
||||
margin: 80rpx auto;
|
||||
width: 200rpx;
|
||||
border-radius: 32rpx;
|
||||
line-height: 64rpx;
|
||||
color: #ffffff;
|
||||
font-size: 26rpx;
|
||||
background: linear-gradient(270deg, rgba(249, 116, 90, 1) 0%, rgba(255, 158, 1, 1) 100%);
|
||||
}
|
||||
}
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - var(--window-top));
|
||||
width: 100%;
|
||||
}
|
||||
.swiper-box {
|
||||
flex: 1;
|
||||
}
|
||||
.swiper-item {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,557 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container position-relative w-100 h-100 overflow-hidden">
|
||||
<view class="exchange-box">
|
||||
<view class="input-box">
|
||||
<input type="text" v-model="exchange_code" placeholder="请输入兑换码" placeholder-class="text-color-assist font-size-base" />
|
||||
<button type="primary" @click="exchange">兑换</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tabbar">
|
||||
<view class="tab" :class="{active: activeTabIndex == index}"
|
||||
v-for="(item, index) in tabs" :key="index" @tap="handleTab(index)">
|
||||
<view class="title">{{ item.title }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-fill">
|
||||
<scroll-view scroll-y class="coupon-list" @scrolltolower="getCoupons(activeTabIndex)">
|
||||
<view class="wrapper" v-if="0 === activeTabIndex">
|
||||
<uv-empty v-if="myCoupons.length == 0" mode="list"></uv-empty>
|
||||
<view class="coupon" v-for="(item, index) in myCoupons" :key="index" @tap="openDetailModal(item,index)">
|
||||
<view class="taobao">
|
||||
<view class="ticket">
|
||||
<view class="left">
|
||||
<image
|
||||
class="picture"
|
||||
:src="item.image"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
¥
|
||||
<text class="big">{{item.value}}</text>
|
||||
<view>
|
||||
满{{item.least}}减{{item.value}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{formatDateTime(item.startTime, 'yyyy-MM-dd')}}-{{formatDateTime(item.endTime, 'yyyy-MM-dd')}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 1">
|
||||
<view class="use immediate-use" :round="true" @tap="receive(item, index)" >立即领取</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.status == 0" class="use immediate-use" :round="true" @tap="useCouponWith(item)" >立即使用</view>
|
||||
<view v-else class="used">已使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wrapper" v-if="1 === activeTabIndex">
|
||||
<uv-empty v-if="notCoupons.length == 0" mode="list"></uv-empty>
|
||||
<view class="coupon" v-for="(item, index) in notCoupons" :key="index" @tap="openDetailModal(item,index)">
|
||||
<view class="taobao">
|
||||
<view class="ticket">
|
||||
<view class="left">
|
||||
<image
|
||||
class="picture"
|
||||
:src="item.image"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
¥
|
||||
<text class="big">{{item.value}}</text>
|
||||
<view>
|
||||
满{{item.least}}减{{item.value}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{formatDateTime(item.startTime, 'yyyy-MM-dd')}}-{{formatDateTime(item.endTime, 'yyyy-MM-dd')}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 1">
|
||||
<view class="use immediate-use" :round="true" @tap="receive(item, index)" >立即领取</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.status == 0" class="use immediate-use" :round="true" @tap="useCouponWith(item)" >立即使用</view>
|
||||
<view v-else class="used">已使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<modal custom :show="detailModalVisible" @cancel="closeDetailModal" width="90%">
|
||||
<view class="modal-content">
|
||||
<view class="d-flex font-size-extra-lg text-color-base just-content-center mb-20">{{ coupon.title }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
有效期:{{formatDateTime(coupon.startTime, 'yyyy-MM-dd')}}-{{formatDateTime(coupon.endTime, 'yyyy-MM-dd')}}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
领取时间:{{formatDateTime(coupon.createTime)}}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
券价值:满{{ coupon.least }}减{{ coupon.value }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-if="activeTabIndex == 1">
|
||||
每人限领:{{ coupon.limit }} 张
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
适用范围:{{typeInfo(coupon.type)}}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
适用店铺:{{coupon.shopName}}
|
||||
</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 0">
|
||||
<button type="primary" @tap="useCoupon" class="use-coupon-btn">立即使用</button>
|
||||
</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 1">
|
||||
<button type="primary" @tap="receive(coupon, couponIndex)" class="use-coupon-btn">立即领取</button>
|
||||
</view>
|
||||
</view>
|
||||
</modal>
|
||||
|
||||
<!--轻提示-->
|
||||
<uv-toast ref="uToast"></uv-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
watch
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow ,onPullDownRefresh,onHide} from '@dcloudio/uni-app'
|
||||
import { formatDateTime,kmUnit } from '@/utils/util'
|
||||
import {
|
||||
couponReceive,
|
||||
couponMine,
|
||||
couponIndexApi
|
||||
} from '@/api/coupon'
|
||||
const main = useMainStore()
|
||||
const { isLogin } = storeToRefs(main)
|
||||
const title = ref('优惠券')
|
||||
|
||||
const tabs = ref([
|
||||
{title: '我的优惠券', page:1, pagesize:10,
|
||||
coupons: []
|
||||
},
|
||||
{title: '未领优惠券', page:1, pagesize:10,
|
||||
coupons: []
|
||||
}
|
||||
])
|
||||
const activeTabIndex = ref(0)
|
||||
const detailModalVisible = ref(false)
|
||||
const coupon = ref({})
|
||||
const couponIndex = ref(0)
|
||||
const exchange_code = ref('')
|
||||
const uToast = ref()
|
||||
const myCoupons = ref([])
|
||||
const notCoupons = ref([])
|
||||
|
||||
onShow(() => {
|
||||
getCoupons(0)
|
||||
})
|
||||
onPullDownRefresh(() => {
|
||||
if(activeTabIndex.value == 0) {
|
||||
myCoupons.value = []
|
||||
}
|
||||
if(activeTabIndex.value == 1) {
|
||||
notCoupons.value = []
|
||||
}
|
||||
tabs.value[activeTabIndex.value].page = 1;
|
||||
getCoupons(activeTabIndex.value)
|
||||
})
|
||||
watch(activeTabIndex, () => {
|
||||
getCoupons(activeTabIndex.value)
|
||||
})
|
||||
|
||||
// 兑换
|
||||
const exchange = async() => {
|
||||
let data = await couponReceive({code:this.exchange_code});
|
||||
if (data) {
|
||||
uToast.value.show({
|
||||
message: '兑换成功',
|
||||
type: 'success'
|
||||
});
|
||||
tabs.value[0].coupons = [];
|
||||
tabs.value[0].page = 1;
|
||||
getCoupons(0)
|
||||
tabs.value[1].coupons = [];
|
||||
tabs.value[1].page = 1;
|
||||
getCoupons(1)
|
||||
}
|
||||
}
|
||||
// 使用范围
|
||||
const typeInfo = (type) => {
|
||||
if (type == 0) {
|
||||
return '通用'
|
||||
}
|
||||
if (type == 1) {
|
||||
return '自取'
|
||||
}
|
||||
if (type == 2) {
|
||||
return '外卖'
|
||||
}
|
||||
}
|
||||
const handleTab = (index) => {
|
||||
console.log('activeTabIndex2:',index)
|
||||
activeTabIndex.value = index
|
||||
}
|
||||
const getCoupons = async(type) => {
|
||||
let page = tabs.value[type].page;
|
||||
let pagesize = tabs.value[type].pagesize;
|
||||
// 我的优惠券
|
||||
let data = [];
|
||||
if (type == 0) {
|
||||
myCoupons.value = await couponMine({page:page,pagesize:pagesize});
|
||||
}
|
||||
// 未领优惠券
|
||||
if (type == 1) {
|
||||
notCoupons.value = await couponIndexApi({page:page,pagesize:pagesize});
|
||||
}
|
||||
//console.log('data:',data)
|
||||
uni.stopPullDownRefresh();
|
||||
|
||||
console.log('tabs.value:',tabs.value[type].title)
|
||||
//tabs.value[type].page++;
|
||||
}
|
||||
const openDetailModal = (coupon,index) => {
|
||||
couponIndex.value = index;
|
||||
coupon.value = coupon
|
||||
detailModalVisible.value = true
|
||||
}
|
||||
const useCouponWith = (coupon) => {
|
||||
//coupon.value = coupon
|
||||
useCoupon();
|
||||
}
|
||||
const closeDetailModal = () => {
|
||||
detailModalVisible.value = false
|
||||
coupon.value = {}
|
||||
}
|
||||
const useCoupon = () => {
|
||||
uni.switchTab({
|
||||
url: '/pages/menu/menu'
|
||||
})
|
||||
}
|
||||
const showTip1 = () => {
|
||||
uni.showToast({
|
||||
title: '您暂时还没有赠送中卡券哦~',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
const showTip2 = () => {
|
||||
uni.showToast({
|
||||
title: '您暂时还没有券码哦~',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
// 领取优惠券
|
||||
const receive = async(coupon,index) => {
|
||||
let data = await couponReceive({id:coupon.id});
|
||||
if (data) {
|
||||
uToast.value.show({
|
||||
message: '领取成功',
|
||||
type: 'success'
|
||||
});
|
||||
detailModalVisible.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* #ifdef H5 */
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.exchange-box {
|
||||
flex-shrink: 0;
|
||||
height: 200rpx;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.input-box {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
width: 70%;
|
||||
flex-shrink: 0;
|
||||
input {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
border: 1rpx solid #eee;
|
||||
border-right: 0;
|
||||
border-radius: 8rpx 0 0 8rpx;
|
||||
// padding: 20rpx;
|
||||
font-size: $font-size-base;
|
||||
color: $text-color-base;
|
||||
}
|
||||
button {
|
||||
border-radius: 0 8rpx 8rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabbar {
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: $font-size-base;
|
||||
color: $text-color-base;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
padding: 15rpx 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $color-primary;
|
||||
|
||||
.title {
|
||||
border-bottom: 5rpx solid $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-box {
|
||||
height: 80rpx;
|
||||
flex-shrink: 0;
|
||||
.item {
|
||||
padding: 0 20rpx;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
border-right: 1rpx solid $text-color-assist;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transform: scaleX(0.5) scaleY(0.8);
|
||||
}
|
||||
|
||||
&:nth-last-child(1)::after {
|
||||
border-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-list {
|
||||
height: calc(100vh - 120rpx - 200rpx);
|
||||
/* #ifdef H5 */
|
||||
height: calc(100vh - 120rpx - 200rpx - 44px);
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.coupon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #FFFFFF;
|
||||
margin-bottom: 30rpx;
|
||||
//padding: 0 30rpx;
|
||||
border-radius: 6rpx;
|
||||
box-shadow: 0 10rpx 10rpx -10rpx rgba(15, 15, 15, 0.1);
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-color: $bg-color;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
bottom: 65rpx;
|
||||
left: -15rpx;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-color: $bg-color;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
bottom: 65rpx;
|
||||
right: -15rpx;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.detail {
|
||||
padding: 20rpx 0;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 1rpx dashed #c6c6c6;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.coupon-img {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.use-coupon-btn {
|
||||
width: 95%;
|
||||
border-radius: 50rem !important;
|
||||
}
|
||||
|
||||
|
||||
.taobao {
|
||||
background-color: white;
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 30rpx;
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.store {
|
||||
font-weight: 500;
|
||||
}
|
||||
.buddha {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.entrance {
|
||||
color: $uv-info;
|
||||
border: solid 2rpx $uv-info;
|
||||
line-height: 48rpx;
|
||||
padding: 0 30rpx;
|
||||
background: none;
|
||||
border-radius: 15px;
|
||||
}
|
||||
}
|
||||
.ticket {
|
||||
display: flex;
|
||||
.left {
|
||||
width: 70%;
|
||||
padding: 20rpx;
|
||||
background-color: white;//rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
border-right: dashed 2rpx rgb(224, 215, 211);
|
||||
display: flex;
|
||||
.picture {
|
||||
//width: 172rpx;
|
||||
border-radius: 20rpx;
|
||||
width: 190rpx;
|
||||
height: 190rpx;
|
||||
}
|
||||
.introduce {
|
||||
margin-left: 10rpx;
|
||||
.top{
|
||||
color:$uv-warning;
|
||||
font-size: 28rpx;
|
||||
.big{
|
||||
font-size: 60rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
.type{
|
||||
font-size: 28rpx;
|
||||
color: $uv-info-dark;
|
||||
}
|
||||
.date{
|
||||
margin-top: 10rpx;
|
||||
font-size: 20rpx;
|
||||
color: $uv-info-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
.right {
|
||||
width: 30%;
|
||||
padding: 40rpx 20rpx;
|
||||
background-color: white;//rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.use {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 40rpx;
|
||||
color: #ffffff!important;
|
||||
background-color: $uv-warning!important;
|
||||
line-height: 40rpx;
|
||||
color: rgb(117, 142, 165);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.used {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 40rpx;
|
||||
//color: #ffffff!important;
|
||||
//background-color: $u-type-warning!important;
|
||||
line-height: 40rpx;
|
||||
//color: rgb(117, 142, 165);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
.right_log {
|
||||
text-align: center;
|
||||
width: 30%;
|
||||
padding: 80rpx 0rpx;
|
||||
background-color: white;//rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,326 @@
|
||||
<template>
|
||||
<layout>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="wrap">
|
||||
<view class="top"></view>
|
||||
<view class="content">
|
||||
<view class="title">欢迎登录</view>
|
||||
|
||||
<input class="u-border-bottom" type="number" v-model="mobile" placeholder="请输入手机号" />
|
||||
<view class="tips">未注册的手机号验证后自动创建账号</view>
|
||||
|
||||
|
||||
<view style="display: flex;">
|
||||
<view style="width: 50%;">
|
||||
<input style="height: 100rpx;" class="u-border-bottom" type="number" v-model="captcha" placeholder="请输入验证码" />
|
||||
</view>
|
||||
<view style="width: 50%;">
|
||||
<button style="height: 100rpx;" @tap="getCaptcha" :style="[captchaStyle]" class="getCaptcha">
|
||||
{{captchaText}}
|
||||
<uv-code :seconds="seconds" @end="endCaptcha" @start="startCaptcha" ref="uCode" @change="changeCapcha"></uv-code>
|
||||
<!-- <u-verification-code :seconds="seconds" @end="endCaptcha" @change="changeCapcha" @start="startCaptcha" ref="uCode" >
|
||||
|
||||
</u-verification-code> -->
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<button @tap="submit" style="color:#fff;background-color: #f9ae3d;" type="primary" class="login">登录</button>
|
||||
|
||||
</view>
|
||||
<view class="buttom">
|
||||
<view class="loginType">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button type="primary" size="default" class="login-btn" open-type="getPhoneNumber" @getphonenumber="loginForWechatMini">
|
||||
<!-- <image src="/static/images/mine/wechat.png"></image> -->
|
||||
手机号快捷登录
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="hint">
|
||||
<!-- <label class="label"> -->
|
||||
<radio value="isChecked" @tap.stop="onChange" />
|
||||
我已经阅读并遵守
|
||||
<text class="link" @tap="serv(29,'用户协议')">《用户协议》</text>与
|
||||
<text class="link" @tap="serv(30,'隐私政策')">《隐私政策》</text>
|
||||
<!-- </label> -->
|
||||
</view>
|
||||
</view>
|
||||
<uv-toast ref="uToast"></uv-toast>
|
||||
</view>
|
||||
</layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import {
|
||||
userLoginForWechatMini,
|
||||
smsSend,
|
||||
userLogin
|
||||
} from '@/api/auth'
|
||||
import * as util from '@/utils/util'
|
||||
import { mobile as testMobible } from '@/uni_modules/uv-ui-tools/libs/function/test'
|
||||
const main = useMainStore()
|
||||
const title = ref('登录')
|
||||
const mobile = ref('')
|
||||
const captcha = ref('')
|
||||
const captchaText = ref('获取验证码')
|
||||
const password = ref('')
|
||||
const seconds = ref(60)
|
||||
const isChecked = ref(false)
|
||||
const openid = ref(main.openid)
|
||||
const uToast = ref()
|
||||
const uCode = ref()
|
||||
|
||||
const captchaStyle = computed(() => {
|
||||
let style = {};
|
||||
if(mobile.value && captchaText.value == '获取验证码') {
|
||||
style.color = "#fff";
|
||||
style.backgroundColor = '#f9ae3d';
|
||||
}
|
||||
return style;
|
||||
});
|
||||
|
||||
|
||||
const loginForWechatMini = async (e) => {
|
||||
if(!isChecked.value){
|
||||
uToast.value.show({
|
||||
message: '请勾选下面协议',
|
||||
type: 'error'
|
||||
});
|
||||
return
|
||||
}
|
||||
if (e.detail.encryptedData && e.detail.iv) {
|
||||
let data = await userLoginForWechatMini({
|
||||
encryptedData: e.detail.encryptedData,
|
||||
iv: e.detail.iv,
|
||||
openid: openid.value
|
||||
});
|
||||
if (data) {
|
||||
main.SET_MEMBER(data.userInfo);
|
||||
main.SET_TOKEN(data.accessToken);
|
||||
uToast.value.show({
|
||||
title: '登录成功',
|
||||
type: 'success'
|
||||
});
|
||||
setTimeout(function() {
|
||||
uni.navigateBack();
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getCaptcha = async () => {
|
||||
|
||||
if (testMobible(mobile.value) == false) {
|
||||
uToast.value.show({
|
||||
message: '手机号码格式不对',
|
||||
type: 'error'
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
let data = await smsSend({
|
||||
mobile: mobile.value,
|
||||
scene: 1
|
||||
});
|
||||
if (data) {
|
||||
uCode.value.start();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 验证码开始计时
|
||||
const startCaptcha = () => {
|
||||
console.log('start')
|
||||
}
|
||||
// 验证码结束
|
||||
const endCaptcha = () => {
|
||||
console.log('end')
|
||||
captchaText.value = '获取验证码';
|
||||
}
|
||||
const changeCapcha = (text) => {
|
||||
console.log('change:' + text)
|
||||
captchaText.value = text;
|
||||
}
|
||||
// 提交
|
||||
const submit = () => {
|
||||
|
||||
if (testMobible(mobile.value) == false) {
|
||||
uToast.value.show({
|
||||
message: '手机号码格式不对',
|
||||
type: 'error'
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
if(!isChecked.value){
|
||||
uToast.value.show({
|
||||
message: '请勾选下面协议',
|
||||
type: 'error'
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
login()
|
||||
|
||||
}
|
||||
|
||||
// 登录
|
||||
const login = async () => {
|
||||
let from = 'routine'
|
||||
// #ifdef H5
|
||||
from = 'h5'
|
||||
if(util.isWeixin()){
|
||||
from = 'wechat'
|
||||
}
|
||||
|
||||
// #endif
|
||||
let data = await userLogin({
|
||||
mobile: mobile.value,
|
||||
code: captcha.value,
|
||||
from: from,
|
||||
openid: openid.value
|
||||
})
|
||||
if (data) {
|
||||
uni.setStorage({
|
||||
key: 'userinfo',
|
||||
data: data.userInfo
|
||||
});
|
||||
uni.setStorage({
|
||||
key: 'accessToken',
|
||||
data: data.accessToken
|
||||
});
|
||||
main.SET_MEMBER(data.userInfo);
|
||||
main.SET_TOKEN(data.accessToken);
|
||||
uToast.value.show({
|
||||
message: '登录成功',
|
||||
type: 'success'
|
||||
});
|
||||
setTimeout(function() {
|
||||
uni.navigateBack();
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
const serv = (id,name) => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/mine/content?id=' + id + '&name=' + name
|
||||
})
|
||||
}
|
||||
|
||||
const onChange = () => {
|
||||
isChecked.value = !isChecked.value
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrap {
|
||||
background-color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
.content {
|
||||
width: 600rpx;
|
||||
margin: 0 auto;
|
||||
|
||||
.title {
|
||||
text-align: left;
|
||||
font-size: 60rpx;
|
||||
font-weight: 500;
|
||||
margin-bottom: 100rpx;
|
||||
}
|
||||
input {
|
||||
text-align: left;
|
||||
margin-bottom: 10rpx;
|
||||
padding-bottom: 6rpx;
|
||||
}
|
||||
.tips {
|
||||
color: $uv-info;
|
||||
margin-bottom: 60rpx;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
.getCaptcha {
|
||||
background-color: rgb(253, 243, 208);
|
||||
color: $uv-tips-color;
|
||||
border: none;
|
||||
font-size: 30rpx;
|
||||
padding: 12rpx 0;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
.login {
|
||||
background-color: rgb(253, 243, 208);
|
||||
color: $uv-tips-color;
|
||||
border: none;
|
||||
font-size: 30rpx;
|
||||
padding: 12rpx 0;
|
||||
margin-top: 40rpx;
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
.alternative {
|
||||
color: $uv-tips-color;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
}
|
||||
.buttom {
|
||||
//position: absolute;
|
||||
bottom: 0;
|
||||
//display: flex;
|
||||
//flex-direction: column;
|
||||
//align-items: center;
|
||||
//justify-content: center;
|
||||
.loginType {
|
||||
padding: 80rpx;
|
||||
//justify-content:space-between;
|
||||
|
||||
.login-btn {
|
||||
background-color: #1aad19!important;
|
||||
width: 100%;
|
||||
border-radius: 50rem !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10rpx 0;
|
||||
text-align: center;
|
||||
image {
|
||||
width: 36rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 10rpx;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hint {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20rpx 40rpx;
|
||||
font-size: 20rpx;
|
||||
color: $uv-tips-color;
|
||||
|
||||
.link {
|
||||
color: $uv-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<!-- <layout> -->
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="top">
|
||||
<button type="primary" size="default" class="login-btn" @click="logout">
|
||||
确定退出登录
|
||||
</button>
|
||||
<uv-toast ref="uToast"></uv-toast>
|
||||
</view>
|
||||
<!-- </layout> -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
const main = useMainStore()
|
||||
const { member,isLogin } = storeToRefs(main)
|
||||
const uToast = ref()
|
||||
const title = ref('退出')
|
||||
|
||||
const logout = () => {
|
||||
uni.removeStorageSync( 'userinfo');
|
||||
uni.removeStorageSync( 'accessToken');
|
||||
main.SET_MEMBER({});
|
||||
main.SET_TOKEN('');
|
||||
uToast.value.show({
|
||||
message: '已退出',
|
||||
type: 'success'
|
||||
});
|
||||
setTimeout(function() {
|
||||
uni.navigateBack();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
button{
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<layout>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view>
|
||||
<rich-text :nodes="content"></rich-text>
|
||||
</view>
|
||||
</layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
import { onLoad,onShow} from '@dcloudio/uni-app'
|
||||
import {
|
||||
mineServiceContent
|
||||
} from '@/api/user'
|
||||
|
||||
|
||||
const title = ref('内容')
|
||||
const content = ref('')
|
||||
|
||||
onLoad((option) => {
|
||||
if (option.name) {
|
||||
title.value = option.name
|
||||
}
|
||||
if (option.id) {
|
||||
getContent(option.id);
|
||||
}
|
||||
})
|
||||
const getContent = async(id) => {
|
||||
let data = await mineServiceContent({id:id});
|
||||
if (data) {
|
||||
content.value = data.content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container d-flex flex-column">
|
||||
<view class="flex-fill form">
|
||||
<list-cell :hover="false">
|
||||
<view class="form-input w-100 d-flex align-items-center">
|
||||
<view class="label">头像</view>
|
||||
<view class="input flex-fill">
|
||||
<view class="form-input w-100 d-flex align-items-center" style="position: relative;">
|
||||
<view class="flex user-box">
|
||||
<view class="mr-1">
|
||||
<uv-avatar :src="member.avatar" size="60"></uv-avatar>
|
||||
</view>
|
||||
<view v-if="!member.avatar" class="flex-1" style="right:0;height: 60rpx;">
|
||||
<button style="background-color: #dd524d;color:#fff;" size='mini' open-type="chooseAvatar" @chooseavatar="chooseavatar" type="success">更改头像</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</list-cell>
|
||||
<list-cell :hover="false">
|
||||
<view class="form-input w-100 d-flex align-items-center">
|
||||
<view class="label">昵称</view>
|
||||
<view class="input flex-fill">
|
||||
<input type="nickname" placeholder="请填写昵称" placeholder-class="text-color-assist font-size-base"
|
||||
v-model="member.nickname">
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false">
|
||||
<view class="form-input w-100 d-flex align-items-center" style="position: relative;">
|
||||
<view class="label">手机号码</view>
|
||||
<view class="input flex-fill">
|
||||
<input type="text" v-model="member.mobile" disabled>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false">
|
||||
<view class="form-input w-100 d-flex align-items-center">
|
||||
<view class="label">性别</view>
|
||||
<view class="input flex-fill">
|
||||
<view class="radio-group">
|
||||
<view class="radio" :class="{'checked': member.gender == '0'}" style="margin-right: 10rpx;" @tap="member.gender=0">先生</view>
|
||||
<view class="radio" :class="{'checked': member.gender == '1'}" @tap="member.gender=1">女士</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false" :arrow="!member.birthday">
|
||||
<view class="form-input w-100 d-flex align-items-center">
|
||||
<view class="label">生日</view>
|
||||
<view class="input flex-fill">
|
||||
<picker mode="date" :value="member.birthday" :start="startDate" :end="endDate" @change="handleDateChange">
|
||||
{{member.birthday ? member.birthday : '无'}}
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false" last>
|
||||
<view class="form-input w-100 d-flex align-items-center">
|
||||
<view class="label">加入时间</view>
|
||||
<view class="input flex-fill">
|
||||
<input type="text" v-model="member.createTime" disabled>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
</view>
|
||||
<view class="btn-box d-flex align-items-center just-content-center">
|
||||
<button type="primary" class="save-btn" @tap="save">保存</button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow} from '@dcloudio/uni-app'
|
||||
import { formatDateTime } from '@/utils/util'
|
||||
import {
|
||||
userEdit
|
||||
} from '@/api/user'
|
||||
import { VUE_APP_UPLOAD_URL } from '@/config';
|
||||
const main = useMainStore()
|
||||
const { openid, lang } = storeToRefs(main)
|
||||
|
||||
const title = ref('用户设置')
|
||||
//const currentDate = ref('')
|
||||
const date = ref('')
|
||||
const member = ref({})
|
||||
|
||||
onLoad(() => {
|
||||
member.value = main.member;
|
||||
//this.$util
|
||||
member.value.createTime = formatDateTime(member.value.createTime);
|
||||
})
|
||||
onShow(() => {
|
||||
date.value = getDate({format: true})
|
||||
})
|
||||
|
||||
const startDate = computed(() => {
|
||||
return getDate('start');
|
||||
})
|
||||
const endDate = computed(() => {
|
||||
return getDate('end');
|
||||
})
|
||||
|
||||
const chooseavatar = (e) => {
|
||||
console.log('detal:',e.detail);
|
||||
uni.uploadFile({
|
||||
url: VUE_APP_UPLOAD_URL,
|
||||
filePath: e.detail.avatarUrl,
|
||||
name: 'file',
|
||||
header: {
|
||||
Authorization: 'Bearer ' + member.value.accessToken,
|
||||
lang: lang.value,
|
||||
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8'
|
||||
},
|
||||
success(uploadFileResult){
|
||||
console.log('uploadFileResult:',uploadFileResult)
|
||||
if (uploadFileResult) {
|
||||
const upload = JSON.parse(uploadFileResult.data);
|
||||
console.log('upload:',upload.data)
|
||||
member.value.avatar = upload.data;
|
||||
}
|
||||
},
|
||||
fail(e){
|
||||
console.log('网络链接错误');
|
||||
console.log(e)
|
||||
}
|
||||
});
|
||||
}
|
||||
const getDate = (type) => {
|
||||
const date = new Date();
|
||||
let year = date.getFullYear();
|
||||
let month = date.getMonth() + 1;
|
||||
let day = date.getDate();
|
||||
|
||||
if (type === 'start') {
|
||||
year = year - 60;
|
||||
} else if (type === 'end') {
|
||||
year = year + 2;
|
||||
}
|
||||
month = month > 9 ? month : '0' + month;;
|
||||
day = day > 9 ? day : '0' + day;
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
const handleDateChange = (e) => {
|
||||
member.value.birthday = e.target.value
|
||||
}
|
||||
const save = async() => {
|
||||
let data = await userEdit({
|
||||
nickname: member.value.nickname,
|
||||
mobile: member.value.mobile,
|
||||
gender: member.value.gender,
|
||||
birthday: member.value.birthday,
|
||||
avatar: member.value.avatar
|
||||
});
|
||||
if (data) {
|
||||
const member = Object.assign(main.member, member.value)
|
||||
main.SET_MEMBER(member)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 20rpx 30rpx;
|
||||
}
|
||||
|
||||
.form {
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
.label {
|
||||
width: 160rpx;
|
||||
font-size: $font-size-base;
|
||||
color: $text-color-base;
|
||||
}
|
||||
|
||||
.input {
|
||||
}
|
||||
|
||||
.radio-group {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
.radio {
|
||||
padding: 10rpx 30rpx;
|
||||
border-radius: 6rpx;
|
||||
border: 2rpx solid $text-color-assist;
|
||||
color: $text-color-assist;
|
||||
font-size: $font-size-base;
|
||||
|
||||
&.checked {
|
||||
background-color: $color-primary;
|
||||
color: $text-color-white;
|
||||
border: 2rpx solid $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
height: calc((100vh - 40rpx) / 2);
|
||||
}
|
||||
.save-btn {
|
||||
width: 90%;
|
||||
border-radius: 50rem !important;
|
||||
font-size: $font-size-lg;
|
||||
}
|
||||
.logout-btn {
|
||||
width: 90%;
|
||||
border-radius: 50rem !important;
|
||||
font-size: $font-size-lg;
|
||||
background-color:rgb(237, 81, 29);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,488 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container" style="padding:20rpx;">
|
||||
<view style="padding-bottom: 100rpx;">
|
||||
<view class="bg-white">
|
||||
<view class="section">
|
||||
<!-- store info begin -->
|
||||
<list-cell :hover="false">
|
||||
<view class="w-100 d-flex align-items-center">
|
||||
<view class="d-flex flex-column w-60">
|
||||
<view class="w-100 font-size-lg text-color-base text-truncate">{{ order.shop.name }}</view>
|
||||
</view>
|
||||
<view class="d-flex justify-content-end align-items-center w-40">
|
||||
<view class="iconfont-yshop icon-mobile" @click="makePhoneCall(order.shop)" style="font-size: 45rpx;margin-right: 40rpx;"></view>
|
||||
<view class="iconfont-yshop icon-location" @click="openLocation(order.shop)" style="font-size: 45rpx;"></view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<!-- store info end -->
|
||||
<list-cell :hover="false" padding="50rpx 30rpx">
|
||||
<view class="w-100 d-flex flex-column">
|
||||
<view class="d-flex align-items-center just-content-center">
|
||||
<view class="sort-num">{{ order.numberId }}</view>
|
||||
</view>
|
||||
<!-- steps begin -->
|
||||
<view class="d-flex just-content-center">
|
||||
<view class="steps d-flex flex-column w-80">
|
||||
<view class="steps__img-column">
|
||||
<view class="steps__img-column-item">
|
||||
<view class="iconfont-yshop icon-lamp"></view>
|
||||
</view>
|
||||
<view class="steps__img-column-item">
|
||||
<view class="iconfont-yshop icon-daojishi" v-if="{active: order.paid == 1 && order.status == 0}"></view>
|
||||
<view class="iconfont-yshop icon-daojishi unactive" v-else></view>
|
||||
</view>
|
||||
<view class="steps__img-column-item" v-if="order.orderType == 'takeout'">
|
||||
<view class="iconfont-yshop icon-takeout" v-if="order.status == 1"></view>
|
||||
<view class="iconfont-yshop icon-takeout unactive" v-else></view>
|
||||
</view>
|
||||
<view class="steps__img-column-item" >
|
||||
<view class="iconfont-yshop icon-doorbell" v-if="order.status >= 2"></view>
|
||||
<view class="iconfont-yshop icon-doorbell unactive" v-else></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="steps__text-column">
|
||||
<view class="steps__text-column-item active">
|
||||
<view class="steps__column-item-line bg-transparent"></view>
|
||||
<view class="steps__text-column-item-text">已下单</view>
|
||||
<view class="steps__column-item-line"></view>
|
||||
</view>
|
||||
<view class="steps__text-column-item activ" :class="{active: order.paid == 1}">
|
||||
<view class="steps__column-item-line"></view>
|
||||
<view class="steps__text-column-item-text">制作中</view>
|
||||
<view class="steps__column-item-line"></view>
|
||||
</view>
|
||||
<view class="steps__text-column-item" :class="{active: order.status == 1}" v-if="order.orderType == 'takeout'">
|
||||
<view class="steps__column-item-line"></view>
|
||||
<view class="steps__text-column-item-text">配送中</view>
|
||||
<view class="steps__column-item-line bg-transparent"></view>
|
||||
</view>
|
||||
<view class="steps__text-column-item" :class="{active: order.status >= 2}">
|
||||
<view class="steps__column-item-line"></view>
|
||||
<view class="steps__text-column-item-text">
|
||||
{{ order.orderType == 'takeout' ? '已送达' : '请取餐' }}
|
||||
</view>
|
||||
<view class="steps__column-item-line bg-transparent"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- steps end -->
|
||||
<view v-if="order.status==0 && order.paid > 0" class="d-flex just-content-center align-items-center font-size-base text-color-assist mb-40">
|
||||
您前面还有 <text class="text-color-primary mr-10 ml-10">{{order.preNum}}</text> 单待制作
|
||||
</view>
|
||||
<!-- goods begin -->
|
||||
<view class="w-100 d-flex flex-column position-relative mt-30" style="margin-bottom: -40rpx;">
|
||||
<view class="w-100 d-flex align-items-center mb-40" v-for="(good, index) in order.products" :key="index">
|
||||
<view class="d-flex flex-column w-60 overflow-hidden">
|
||||
<view class="font-size-lg text-color-base mb-10 text-truncate">{{ good.title }}</view>
|
||||
<view class="font-size-sm text-color-assist text-truncate">{{ good.spec }}</view>
|
||||
</view>
|
||||
<view class="d-flex w-40 align-items-center justify-content-between pl-30">
|
||||
<view class="font-size-base text-color-base">x{{ good.number }}</view>
|
||||
<view class="font-size-base text-color-base font-weight-bold">¥{{ good.price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- goods end -->
|
||||
</view>
|
||||
</list-cell>
|
||||
</view>
|
||||
<view class="section">
|
||||
<!-- goods begin -->
|
||||
<list-cell :hover="false" padding="30rpx 30rpx">
|
||||
<view class="w-100 d-flex flex-column position-relative">
|
||||
<view class="w-100 d-flex align-items-center mb-40" v-for="(good, index) in order.cartInfo" :key="index">
|
||||
<image :src="good.image" mode="aspectFill" class="image"></image>
|
||||
<view class="d-flex flex-column w-60 overflow-hidden">
|
||||
<view class="font-size-lg text-color-base mb-10 text-truncate">{{ good.title }}</view>
|
||||
<view class="font-size-sm text-color-assist text-truncate">{{ good.spec }}</view>
|
||||
</view>
|
||||
<view class="d-flex w-40 align-items-center justify-content-between pl-30">
|
||||
<view class="font-size-base text-color-base">x{{ good.number }}</view>
|
||||
<view class="font-size-base text-color-base font-weight-bold">¥{{ good.price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<!-- goods end -->
|
||||
<!-- payment and amount begin -->
|
||||
<list-cell :hover="false" padding="50rpx 30rpx">
|
||||
<view class="w-100 d-flex flex-column">
|
||||
<view class="pay-cell">
|
||||
<view>支付方式</view>
|
||||
<view class="font-weight-bold">{{ order._status._payType }}</view>
|
||||
</view>
|
||||
<view class="pay-cell">
|
||||
<view>订单金额</view>
|
||||
<view class="font-weight-bold">¥{{ order.totalPrice }}</view>
|
||||
</view>
|
||||
<view class="pay-cell" v-if="order.orderType == 'takeout'">
|
||||
<view>配送费</view>
|
||||
<view class="font-weight-bold">¥{{ order.payPostage }}</view>
|
||||
</view>
|
||||
<view class="pay-cell">
|
||||
<view>优惠金额</view>
|
||||
<view class="font-weight-bold">¥{{ order.couponPrice }}</view>
|
||||
</view>
|
||||
<view class="pay-cell">
|
||||
<view>实付金额</view>
|
||||
<view class="font-weight-bold">¥{{ order.payPrice }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<!-- payment and amount end -->
|
||||
</view>
|
||||
<view class="section">
|
||||
<!-- order info begin -->
|
||||
<list-cell :hover="false" padding="50rpx 30rpx">
|
||||
<view class="w-100 d-flex flex-column">
|
||||
<view class="pay-cell">
|
||||
<view>下单时间</view>
|
||||
<view class="font-weight-bold">{{ formatDateTime(order.createTime )}}</view>
|
||||
</view>
|
||||
<view class="pay-cell">
|
||||
<view>下单门店</view>
|
||||
<view class="font-weight-bold">{{ order.shop.name }}</view>
|
||||
</view>
|
||||
<view class="pay-cell">
|
||||
<view>订单号</view>
|
||||
<view class="font-weight-bold">{{ order.id }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<!-- order info end -->
|
||||
</view>
|
||||
<!-- order other info begin -->
|
||||
<list-cell :hover="false" padding="50rpx 30rpx 20rpx" last>
|
||||
<view class="w-100 d-flex flex-column">
|
||||
<view class="pay-cell">
|
||||
<view>享用方式</view>
|
||||
<view class="font-weight-bold">{{order.orderType == 'takein' ? '自取' : '外卖'}}</view>
|
||||
</view>
|
||||
<view class="pay-cell">
|
||||
<view>取餐时间</view>
|
||||
<view class="font-weight-bold">{{order.getTime ? formatDateTime(order.getTime) : '立即取餐'}}</view>
|
||||
</view>
|
||||
<view class="pay-cell">
|
||||
<view>制作完成时间</view>
|
||||
<view class="font-weight-bold">{{ order.deliveryTime ? formatDateTime(order.deliveryTime) : '无' }}</view>
|
||||
</view>
|
||||
<view class="pay-cell">
|
||||
<view>备注</view>
|
||||
<view class="font-weight-bold">{{ order.remark ? order.remark : '无' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<!-- order other info end -->
|
||||
</view>
|
||||
<view class="fixed-bottom flex justify-end bg-white p-2" v-if="order.paid > 0 && order.refundStatus == 0">
|
||||
<view class="mr-1"><uv-button type="success" v-if="order.status < 2" :plain="true" size="small" text="确认收到餐" @click="receive(order)"></uv-button></view>
|
||||
<view><uv-button type="warning" :plain="true" size="small" text="申请退款" @click="refund(order)"></uv-button></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
import { onLoad} from '@dcloudio/uni-app'
|
||||
import { formatDateTime } from '@/utils/util'
|
||||
import {
|
||||
orderDetail,
|
||||
orderReceive,
|
||||
} from '@/api/order'
|
||||
const title = ref('订单详情')
|
||||
const order = ref({
|
||||
shop:{name:''},
|
||||
_status:{_payType:''}
|
||||
})
|
||||
const numForMading = ref(5)
|
||||
|
||||
onLoad((option) => {
|
||||
detail(option.id);
|
||||
})
|
||||
|
||||
const detail = async(id) => {
|
||||
let data = await orderDetail(id);
|
||||
if (data) {
|
||||
order.value = data;
|
||||
}
|
||||
}
|
||||
const openLocation = () => {
|
||||
let shop = order.value.shop;
|
||||
uni.openLocation({
|
||||
address: shop.addressMap + shop.address + " " + shop.name,
|
||||
latitude: parseFloat(shop.lat),
|
||||
longitude: parseFloat(shop.lng),
|
||||
fail(res) {
|
||||
console.log(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
const makePhoneCall = () =>{
|
||||
let shop = order.value.shop;
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: shop.mobile,
|
||||
fail(res) {
|
||||
console.log(res)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 确认收到货
|
||||
const receive = async(order) => {
|
||||
let data = await orderReceive({uni:order.orderId});
|
||||
if (data) {
|
||||
await getOrders(true)
|
||||
}
|
||||
}
|
||||
//提交退款
|
||||
const refund = (order) => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/orders/refund?orderId=' + order.orderId + '&payPrice=' + order.payPrice + '&totalPrice=' + order.totalPrice
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.image {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
margin-right: 30rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
// @mixin arch {
|
||||
// content: "";
|
||||
// position: absolute;
|
||||
// background-color: $bg-color;
|
||||
// width: 30rpx;
|
||||
// height: 30rpx;
|
||||
// bottom: -15rpx;
|
||||
// z-index: 10;
|
||||
// border-radius: 100%;
|
||||
// }
|
||||
|
||||
// .section {
|
||||
// position: relative;
|
||||
|
||||
// &::before {
|
||||
// @include arch;
|
||||
// left: -15rpx;
|
||||
// }
|
||||
|
||||
// &::after {
|
||||
// @include arch;
|
||||
// right: -15rpx;
|
||||
// }
|
||||
// }
|
||||
|
||||
.pay-cell {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: $font-size-base;
|
||||
color: $text-color-base;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
&:nth-last-child(1) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.invote-box {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
background-color: #ffffff;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 120rpx;
|
||||
box-shadow: 0 0 20rpx rgba($color: #000000, $alpha: 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
z-index: 11;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20rpx 10rpx;
|
||||
flex: 1;
|
||||
flex-shrink: 0;
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
border-radius: 50rem !important;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* #ifdef H5 */
|
||||
page {
|
||||
min-height: 100%;
|
||||
background-color: $bg-color;
|
||||
}
|
||||
/* #endif */
|
||||
.order-box {
|
||||
padding: 20rpx;
|
||||
/* #ifdef H5 */
|
||||
margin-bottom: 100rpx;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.drinks-img {
|
||||
width: 260rpx;
|
||||
height: 260rpx;
|
||||
}
|
||||
|
||||
.tips {
|
||||
margin: 60rpx 0 80rpx;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
|
||||
.drink-btn {
|
||||
width: 320rpx;
|
||||
border-radius: 50rem !important;
|
||||
margin-bottom: 40rpx;
|
||||
font-size: $font-size-base;
|
||||
line-height: 3.0;
|
||||
}
|
||||
|
||||
@mixin arch {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-color: $bg-color;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
bottom: -15rpx;
|
||||
z-index: 10;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.section {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
@include arch;
|
||||
left: -15rpx;
|
||||
}
|
||||
|
||||
&::after {
|
||||
@include arch;
|
||||
right: -15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.pay-cell {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: $font-size-base;
|
||||
color: $text-color-base;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
&:nth-last-child(1) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-num {
|
||||
font-size: 64rpx;
|
||||
font-weight: bold;
|
||||
color: $text-color-base;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.steps__img-column {
|
||||
display: flex;
|
||||
margin: 30rpx 0;
|
||||
|
||||
.steps__img-column-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
image {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
.unactive {
|
||||
color: #919293;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.steps__text-column {
|
||||
display: flex;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.steps__text-column-item {
|
||||
flex: 1;
|
||||
display: inline-flex;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: $font-size-base;
|
||||
color: $text-color-assist;
|
||||
|
||||
&.active {
|
||||
color: $text-color-base;
|
||||
font-weight: bold;
|
||||
|
||||
.steps__column-item-line {
|
||||
background-color: $text-color-base;
|
||||
}
|
||||
}
|
||||
|
||||
.steps__column-item-line{
|
||||
flex: 1;
|
||||
height: 2rpx;
|
||||
background-color: #919293;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.steps__text-column-item-text {
|
||||
margin: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon-lamp, .icon-daojishi, .icon-takeout, .icon-doorbell{
|
||||
font-size: 60rpx;
|
||||
}
|
||||
.iconfont-yshop {
|
||||
color: #dd524d;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container">
|
||||
<view class="bg-white">
|
||||
<uv-tabs :list="tabList" :current="current" @change="change" keyName="name" :scrollable="false"></uv-tabs>
|
||||
</view>
|
||||
<view class="orders-list d-flex flex-column w-100" style="padding: 20rpx; padding-bottom: 0;">
|
||||
<view class="order-item" v-for="(item, index) in orders" :key="index" style="margin-bottom: 30rpx;" @tap="detail(item.orderId)">
|
||||
<list-cell :hover="false">
|
||||
<view class="w-100 d-flex align-items-center">
|
||||
<view class="flex-fill d-flex flex-column">
|
||||
<view class="font-size-lg text-color-base" style="margin-bottom: 20rpx;">
|
||||
{{ item.shop.name }}
|
||||
</view>
|
||||
<view class="font-size-sm text-color-assist">取餐号:{{ item.numberId }}</view>
|
||||
<view class="font-size-sm text-color-assist">订单编号:{{ item.orderId }}</view>
|
||||
</view>
|
||||
<view class="font-size-lg text-color-primary">
|
||||
{{ item._status._title }}
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false" last>
|
||||
<view class="w-100 d-flex flex-column">
|
||||
<view class="w-100 text-truncate font-size-lg text-color-base" style="margin-bottom: 20rpx;">
|
||||
<!-- {{ orderGoodsName(item.cartInfo) }} -->
|
||||
<view class="flex mb-2" v-for="(good,index) in item.cartInfo" :key="index">
|
||||
<image :src="good.image" mode="aspectFill" class="image"></image>
|
||||
<view class="flex flex-column">
|
||||
<view class="font-size-medium mt-1 text-color-base">{{ good.title }}</view>
|
||||
<view class="font-size-sm mt-1">{{ good.spec }}</view>
|
||||
<view class="font-size-sm mt-2">×{{ good.number }} ¥{{ good.price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="d-flex justify-content-between align-items-center" style="margin-bottom: 30rpx;">
|
||||
<view class="font-size-sm text-color-assist">
|
||||
{{formatDateTime(item.createTime) }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base align-items-center">
|
||||
<view style="margin-right: 10rpx;">共{{ goodsNum(item.cartInfo) }}件商品,实付</view>
|
||||
<view class="font-size-lg">¥{{ item.payPrice }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="d-flex align-items-center justify-content-end">
|
||||
<view>
|
||||
<button v-if="item.paid > 0 && item.status < 2 && item.refundStatus == 0" class="left-margin" plain size="mini" @tap.stop="receive(item)">确认收到餐</button>
|
||||
<button class="left-margin" plain size="mini" @tap="detail(item.orderId)">订单详情</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
</view>
|
||||
</view>
|
||||
<uv-empty v-if="orders.length == 0" mode="order"></uv-empty>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onPullDownRefresh,onReachBottom} from '@dcloudio/uni-app'
|
||||
import { formatDateTime,kmUnit } from '@/utils/util'
|
||||
import {
|
||||
orderGetOrders,
|
||||
orderReceive
|
||||
} from '@/api/order'
|
||||
const main = useMainStore()
|
||||
const { isLogin } = storeToRefs(main)
|
||||
const title = ref('我的订单')
|
||||
|
||||
const page = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const orders = ref([])
|
||||
const tabList = ref([{
|
||||
type: -1,
|
||||
name: '全部',
|
||||
}, {
|
||||
type: 0,
|
||||
name: '待支付',
|
||||
}, {
|
||||
type: 1,
|
||||
name: '进行中'
|
||||
}, {
|
||||
type: 4,
|
||||
name: '已完成'
|
||||
}, {
|
||||
type: -3,
|
||||
name: '退款单'
|
||||
}]
|
||||
)
|
||||
const current = ref(0)
|
||||
const type = ref(-1)
|
||||
|
||||
const orderGoodsName = computed(() => { //计算单个饮品添加到购物车的数量
|
||||
return (goods) => {
|
||||
let arr = []
|
||||
goods.forEach(good => arr.push(good.title + '*' + good.number))
|
||||
return arr.join(',')
|
||||
}
|
||||
})
|
||||
const goodsNum = computed(() => { //计算单个饮品添加到购物车的数量
|
||||
return (goods) => {
|
||||
let num = 0;
|
||||
goods.forEach(good => num += parseInt(good.number))
|
||||
return num;
|
||||
}
|
||||
})
|
||||
onLoad(() => {
|
||||
if(!isLogin.value) {
|
||||
uni.navigateTo({url: '/pages/components/pages/login/login'})
|
||||
}
|
||||
getOrders(false)
|
||||
})
|
||||
onPullDownRefresh(() => {
|
||||
getOrders(false)
|
||||
})
|
||||
onReachBottom(() => {
|
||||
getOrders(false)
|
||||
})
|
||||
|
||||
// tab栏切换
|
||||
const change = (e) => {
|
||||
type.value = e.type
|
||||
getOrders(true)
|
||||
}
|
||||
|
||||
const getOrders = async(isRefresh = false) => {
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
})
|
||||
if(isRefresh) {
|
||||
orders.value = []
|
||||
page.value = 1
|
||||
}
|
||||
let ordersData = await orderGetOrders({page:page.value, limit:pageSize.value,type:type.value});
|
||||
|
||||
if(ordersData) {
|
||||
orders.value = orders.value.concat(ordersData)
|
||||
page.value += 1
|
||||
}
|
||||
uni.stopPullDownRefresh();
|
||||
uni.hideLoading()
|
||||
}
|
||||
const detail = (id) => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/orders/detail?id=' + id
|
||||
})
|
||||
}
|
||||
// 确认收到货
|
||||
const receive = async(order) => {
|
||||
let data = await orderReceive({uni:order.orderId});
|
||||
if (data) {
|
||||
await getOrders(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left-margin {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
.image {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
margin-right: 30rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="p-2">
|
||||
<uv-list>
|
||||
<uv-list-item title="订单金额" :rightText="'¥'+totalPrice"></uv-list-item>
|
||||
<uv-list-item title="退款金额" :rightText="'¥'+payPrice"></uv-list-item>
|
||||
<uv-list-item title="退款类型" rightText="整个订单"></uv-list-item>
|
||||
<uv-list-item title="退款原因" rightText="协商一致"></uv-list-item>
|
||||
<uv-list-item title="退款留言" >
|
||||
<template #footer><uv-input placeholder="请输入内容" border="none" v-model="refundReasonWapExplain"></uv-input></template>
|
||||
</uv-list-item>
|
||||
</uv-list>
|
||||
<view class="mt-2">
|
||||
<uv-button shape="circle" type="warning" :plain="true" size="small" text="申请退款" @click="refund()"></uv-button>
|
||||
</view>
|
||||
<uv-toast ref="toast"></uv-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
import { onLoad} from '@dcloudio/uni-app'
|
||||
import {
|
||||
orderRefund
|
||||
} from '@/api/order'
|
||||
const title = ref('申请退款')
|
||||
const orderId = ref('')
|
||||
const payPrice = ref('')
|
||||
const totalPrice = ref('')
|
||||
const refundReasonWapExplain = ref('')
|
||||
const toast = ref()
|
||||
onLoad((option) => {
|
||||
console.log('option:',option)
|
||||
orderId.value = option.orderId
|
||||
payPrice.value = option.payPrice
|
||||
totalPrice.value = option.totalPrice
|
||||
})
|
||||
|
||||
const refund = async() => {
|
||||
let data = await orderRefund({refundReasonWapExplain:refundReasonWapExplain.value,uni:orderId.value,text:'协商一致'});
|
||||
if (data) {
|
||||
uni.showToast({
|
||||
title: '提交成功',
|
||||
icon: 'success'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@@ -0,0 +1,395 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container position-relative w-100 h-100 overflow-hidden">
|
||||
<uv-empty v-if="coupons.length == 0" mode="coupon"></uv-empty>
|
||||
|
||||
<scroll-view scroll-y class="coupon-list">
|
||||
<view class="wrapper">
|
||||
<view class="coupon" v-for="(item, index) in coupons" :key="index" @tap="openDetailModal(item, index)">
|
||||
<view class="taobao">
|
||||
<view class="ticket" :style="{border: item.id == coupon_id ? '1rpx solid red':''}">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill"></image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
¥
|
||||
<text class="big">{{ item.value }}</text>
|
||||
<view>满{{ item.least }}减{{ item.value }}</view>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{formatDateTime(item.startTime, 'yyyy-MM-dd')}}-{{formatDateTime(item.endTime, 'yyyy-MM-dd')}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.id != coupon_id" class="use immediate-use" :round="true" @tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else class="use immediate-use" :round="true" @tap="cancelCoupon(item)">取消使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<modal custom :show="detailModalVisible" @cancel="closeDetailModal" width="90%">
|
||||
<view class="modal-content">
|
||||
<view class="d-flex font-size-extra-lg text-color-base just-content-center mb-20">{{ coupon.title }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">有效期:{{formatDateTime(coupon.startTime, 'yyyy-MM-dd')}}至{{formatDateTime(coupon.endTime, 'yyyy-MM-dd')}}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">领取时间:{{ coupon.createtime_text }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">卷价值:满{{ coupon.least }}减{{ coupon.value }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">适用范围:{{ typeInfo(coupon.type) }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">适用店铺:{{ coupon.shopName }}</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 0">
|
||||
<button type="primary" @tap="useCoupon" class="use-coupon-btn">立即使用</button>
|
||||
</view>
|
||||
</view>
|
||||
</modal>
|
||||
|
||||
<!--轻提示-->
|
||||
<uv-toast ref="uToast"></uv-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
watch,
|
||||
toRaw
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow ,onPullDownRefresh,onHide} from '@dcloudio/uni-app'
|
||||
import { formatDateTime,prePage } from '@/utils/util'
|
||||
import {
|
||||
couponMine
|
||||
} from '@/api/coupon'
|
||||
const main = useMainStore()
|
||||
const { isLogin } = storeToRefs(main)
|
||||
const title = ref('优惠券')
|
||||
const activeTabIndex = ref(0)
|
||||
const detailModalVisible = ref(false)
|
||||
const coupon = ref({})
|
||||
const couponIndex = ref(0)
|
||||
const coupons = ref([])
|
||||
const amount = ref(0)
|
||||
const buttonLock = ref(false)
|
||||
const coupon_id = ref(0)
|
||||
const shop_id = ref(0)
|
||||
const type = ref(0)
|
||||
const uToast = ref()
|
||||
|
||||
onLoad((options) => {
|
||||
if (options.amount) {
|
||||
amount.value = options.amount;
|
||||
}
|
||||
if (options.coupon_id) {
|
||||
coupon_id.value = options.coupon_id
|
||||
}
|
||||
if (options.shop_id) {
|
||||
shop_id.value = options.shop_id;
|
||||
}
|
||||
if (options.type) {
|
||||
type.value = options.type;
|
||||
}
|
||||
activeTabIndex.value = 0;
|
||||
getCoupons();
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
getCoupons();
|
||||
})
|
||||
|
||||
// 使用范围
|
||||
const typeInfo = (type) => {
|
||||
if (type == 0) {
|
||||
return '外卖和自取';
|
||||
}
|
||||
if (type == 1) {
|
||||
return '自取';
|
||||
}
|
||||
if (type == 2) {
|
||||
return '外卖';
|
||||
}
|
||||
}
|
||||
const getCoupons = async() => {
|
||||
let data = await couponMine({shop_id: shop_id.value, type: type.value, page:1, pagesize:10000});
|
||||
uni.stopPullDownRefresh();
|
||||
if (data) {
|
||||
coupons.value = data;
|
||||
}
|
||||
}
|
||||
const openDetailModal = (mycoupon, index) => {
|
||||
couponIndex.value = index;
|
||||
coupon.value = mycoupon;
|
||||
detailModalVisible.value = true;
|
||||
}
|
||||
// 使用优惠券
|
||||
const useCouponWith = (mycoupon) => {
|
||||
coupon.value = mycoupon;
|
||||
useCoupon();
|
||||
}
|
||||
// 取消优惠券
|
||||
const cancelCoupon = () => {
|
||||
coupon.value = {}
|
||||
coupon_id.value = 0
|
||||
prePage().coupon = {}
|
||||
}
|
||||
const closeDetailModal = () => {
|
||||
detailModalVisible.value = false;
|
||||
coupon.value = {};
|
||||
}
|
||||
// 使用优惠及
|
||||
|
||||
const useCoupon = () => {
|
||||
if (buttonLock.value == true) {
|
||||
return;
|
||||
}
|
||||
buttonLock.value = true
|
||||
//console.log('coupon:',coupon.value);
|
||||
if (parseFloat(coupon.value.least) > parseFloat(amount.value)) {
|
||||
//console.log('pages3:');
|
||||
uToast.value.show({
|
||||
message: '订单金额满'+coupon.value.least+'才能使用',
|
||||
type: 'error'
|
||||
});
|
||||
buttonLock.value = false
|
||||
} else {
|
||||
main.SET_COUPON(coupon)
|
||||
console.log('main.myconpon:',main.mycoupon)
|
||||
//prePage().coupon = coupon.value;
|
||||
//prePage().coupons = 1; // 哨兵
|
||||
|
||||
uni.navigateBack({
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* #ifdef H5 */
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.bottom-box {
|
||||
height: 80rpx;
|
||||
flex-shrink: 0;
|
||||
.item {
|
||||
padding: 0 20rpx;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: ' ';
|
||||
border-right: 1rpx solid $text-color-assist;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transform: scaleX(0.5) scaleY(0.8);
|
||||
}
|
||||
|
||||
&:nth-last-child(1)::after {
|
||||
border-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-list {
|
||||
margin-top: 30rpx;
|
||||
height:calc(100vh - 120rpx);
|
||||
// height: calc(100vh - 120rpx - 200rpx);
|
||||
/* #ifdef H5 */
|
||||
// height: calc(100vh - 120rpx - 200rpx - 44px);
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.coupon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #ffffff;
|
||||
margin-bottom: 30rpx;
|
||||
//padding: 0 30rpx;
|
||||
border-radius: 6rpx;
|
||||
box-shadow: 0 10rpx 10rpx -10rpx rgba(15, 15, 15, 0.1);
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: $bg-color;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
bottom: 65rpx;
|
||||
left: -15rpx;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: $bg-color;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
bottom: 65rpx;
|
||||
right: -15rpx;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.detail {
|
||||
padding: 20rpx 0;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 1rpx dashed #c6c6c6;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.coupon-img {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.use-coupon-btn {
|
||||
width: 95%;
|
||||
border-radius: 50rem !important;
|
||||
}
|
||||
|
||||
.taobao {
|
||||
background-color: white;
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 30rpx;
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.store {
|
||||
font-weight: 500;
|
||||
}
|
||||
.buddha {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.entrance {
|
||||
color: $uv-info;
|
||||
border: solid 2rpx $uv-info;
|
||||
line-height: 48rpx;
|
||||
padding: 0 30rpx;
|
||||
background: none;
|
||||
border-radius: 15px;
|
||||
}
|
||||
}
|
||||
.ticket {
|
||||
display: flex;
|
||||
.left {
|
||||
width: 70%;
|
||||
padding: 20rpx;
|
||||
background-color: white; //rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
border-right: dashed 2rpx rgb(224, 215, 211);
|
||||
display: flex;
|
||||
.picture {
|
||||
//width: 172rpx;
|
||||
border-radius: 20rpx;
|
||||
width: 190rpx;
|
||||
height: 190rpx;
|
||||
}
|
||||
.introduce {
|
||||
margin-left: 10rpx;
|
||||
.top {
|
||||
color: $uv-warning;
|
||||
font-size: 28rpx;
|
||||
.big {
|
||||
font-size: 60rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
.type {
|
||||
font-size: 28rpx;
|
||||
color: $uv-info-dark;
|
||||
}
|
||||
.date {
|
||||
margin-top: 10rpx;
|
||||
font-size: 20rpx;
|
||||
color: $uv-info-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
.right {
|
||||
width: 30%;
|
||||
padding: 40rpx 20rpx;
|
||||
background-color: white; //rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.use {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 40rpx;
|
||||
color: #ffffff !important;
|
||||
background-color: $uv-warning !important;
|
||||
line-height: 40rpx;
|
||||
color: rgb(117, 142, 165);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.used {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 40rpx;
|
||||
//color: #ffffff!important;
|
||||
//background-color: $u-type-warning!important;
|
||||
line-height: 40rpx;
|
||||
//color: rgb(117, 142, 165);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
.right_log {
|
||||
text-align: center;
|
||||
width: 30%;
|
||||
padding: 80rpx 0rpx;
|
||||
background-color: white; //rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,814 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container position-relative">
|
||||
<view style="margin-bottom: 130rpx;">
|
||||
<view class="section-1">
|
||||
<template v-if="store.distance > 0">
|
||||
<list-cell class="location">
|
||||
<view class="flex-fill d-flex justify-content-between align-items-center">
|
||||
<view class="store-name flex-fill">{{ orderType == 'takeout' ? '外卖配送' : '点餐自取' }}</view>
|
||||
<uv-switch activeColor="#dd524d" v-model="active" @change="takout">
|
||||
</uv-switch>
|
||||
</view>
|
||||
</list-cell>
|
||||
</template>
|
||||
|
||||
<template v-if="orderType == 'takeout'">
|
||||
<list-cell @click="chooseAddress">
|
||||
<view v-if="address.realName" class="w-100 d-flex flex-column">
|
||||
<view class="d-flex align-items-center justify-content-between mb-10">
|
||||
<view class="font-size-lg text-color-base">
|
||||
{{ address.address + ' ' + address.detail }}
|
||||
</view>
|
||||
<image src="/static/images/navigator-1.png" class="arrow"></image>
|
||||
</view>
|
||||
<view class="d-flex text-color-assist font-size-sm align-items-center">
|
||||
<view class="mr-10">{{ address.realName }}</view>
|
||||
<view>{{ address.phone }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="flex-fill d-flex justify-content-between align-items-center">
|
||||
<view class="store-name flex-fill">选择收货地址</view>
|
||||
<image src="/static/images/navigator-1.png" class="arrow"></image>
|
||||
</view>
|
||||
</list-cell>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<view class="section-1">
|
||||
<template>
|
||||
<list-cell class="location" @click="goToShop">
|
||||
<view class="flex-fill d-flex justify-content-between align-items-center">
|
||||
<view class="store-name flex-fill">{{ store.name }}</view>
|
||||
<image src="/static/images/navigator-1.png" class="arrow"></image>
|
||||
</view>
|
||||
</list-cell>
|
||||
</template>
|
||||
|
||||
<template>
|
||||
<list-cell arrow class="meal-time" v-if="orderType == 'takein'">
|
||||
<view class="flex-fill d-flex justify-content-between align-items-center"
|
||||
@click="takeinTIme = !takeinTIme">
|
||||
<view class="title">取餐时间</view>
|
||||
<view class="time">
|
||||
{{ takeinRange[defaultSelector[0]].name }}
|
||||
<u-picker v-model="takeinTIme" :range="takeinRange" range-key="name" mode="selector"
|
||||
@cancel="takeinCancelTime" @confirm="takeinConfirmTime"
|
||||
:default-selector="defaultSelector"></u-picker>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell class="contact" last :hover="false" v-if="orderType == 'takein'">
|
||||
<view class="flex-fill d-flex justify-content-between align-items-center">
|
||||
<view class="title flex-fill">联系电话</view>
|
||||
<view class="time"><input class="text-right" placeholder="请输入手机号码" :value="member.mobile" />
|
||||
</view>
|
||||
<button class="contact-tip font-size-sm">自动填写</button>
|
||||
</view>
|
||||
</list-cell>
|
||||
</template>
|
||||
<template v-if="orderType == 'takeout'">
|
||||
<list-cell>
|
||||
<view class="w-100 d-flex flex-column">
|
||||
<view class="d-flex align-items-center font-size-base text-color-base">
|
||||
<view class="flex-fill">预计送达时间</view>
|
||||
<view class="mr-10">
|
||||
{{ defaultTime }}
|
||||
<u-picker :default-time="defaultTime" v-model="takeoutTIme" :params="paramsTime"
|
||||
mode="time" @cancel="cancelTime" @confirm="choiceTime"></u-picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
</template>
|
||||
</view>
|
||||
<!-- 购物车列表 begin -->
|
||||
<view class="section-2">
|
||||
<view class="cart d-flex flex-column">
|
||||
<list-cell last v-for="(item, index) in cart" :key="index">
|
||||
<view class="w-100 d-flex flex-column">
|
||||
<view class="d-flex align-items-center mb-10">
|
||||
<view
|
||||
class="d-flex flex-fill justify-content-between align-items-center text-color-base font-size-lg">
|
||||
<image style="width: 80rpx;height: 80rpx;" mode="aspectFill" :src="item.image">
|
||||
</image>
|
||||
</view>
|
||||
<view class="name-and-props overflow-hidden">
|
||||
<view class="text-color-base font-size-lg">{{ item.name }}</view>
|
||||
</view>
|
||||
<view
|
||||
class="d-flex flex-fill justify-content-between align-items-center text-color-base font-size-lg">
|
||||
<view>x{{ item.number }}</view>
|
||||
<view>¥{{ item.price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="text-truncate font-size-base text-color-assist">{{ item.valueStr }}</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
</view>
|
||||
<list-cell arrow @click="goToPackages">
|
||||
<view class="flex-fill d-flex justify-content-between align-items-center">
|
||||
<view class="text-color-base">优惠券</view>
|
||||
<view v-if="coupons == 0" class="text-color-base">暂无可用</view>
|
||||
<view v-else-if="coupon.title" class="text-color-danger">
|
||||
{{ coupon.title }}(满{{ coupon.least }}减{{ coupon.value }})
|
||||
</view>
|
||||
<view v-else class="text-color-primary">可用优惠券{{ coupons }}张</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell last>
|
||||
<view class="flex-fill d-flex justify-content-end align-items-center">
|
||||
<view>
|
||||
总计¥{{ total }}
|
||||
<text v-if="orderType == 'takeout'">,配送费¥{{ store.deliveryPrice }}</text>
|
||||
<text v-if="coupon.value">,¥-{{ coupon.value }}</text>
|
||||
,实付
|
||||
</view>
|
||||
<view class="font-size-extra-lg font-weight-bold">¥{{ amount }}</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
</view>
|
||||
<!-- 购物车列表 end -->
|
||||
<view class="d-flex align-items-center justify-content-start font-size-sm text-color-warning"
|
||||
style="padding: 20rpx 0;">
|
||||
</view>
|
||||
<!-- 支付方式 begin -->
|
||||
<view class="payment">
|
||||
<list-cell last :hover="false"><text>支付方式</text></list-cell>
|
||||
<list-cell>
|
||||
<view class="d-flex align-items-center justify-content-between w-100 disabled"
|
||||
@click="setPayType('yue')">
|
||||
<view class="iconfont iconbalance line-height-100 payment-icon"></view>
|
||||
<view class="flex-fill">余额支付(余额¥{{ member.nowMoney }})</view>
|
||||
<view class="font-size-sm" v-if="member.nowMoney == 0">余额不足</view>
|
||||
<view class="iconfont line-height-100 checkbox checked iconradio-button-on" v-if="payType == 'yue'">
|
||||
</view>
|
||||
<view class="iconfont line-height-100 checkbox iconradio-button-off" v-else></view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell last>
|
||||
<view class="d-flex align-items-center justify-content-between w-100" @click="setPayType('weixin')">
|
||||
<view class="iconfont iconwxpay line-height-100 payment-icon" style="color: #7EB73A"></view>
|
||||
<view class="flex-fill">微信支付</view>
|
||||
<view class="iconfont line-height-100 checkbox checked iconradio-button-on" v-if="payType == 'weixin'">
|
||||
</view>
|
||||
<view class="iconfont line-height-100 checkbox iconradio-button-off" v-else></view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<!-- #ifdef H5 -->
|
||||
<list-cell>
|
||||
<view class="d-flex align-items-center justify-content-between w-100" @click="setPayType('alipay')">
|
||||
<view class="iconfont-yshop icon-alipay line-height-100 payment-icon" style="color:#07b4fd" ></view>
|
||||
<view class="flex-fill">支付宝</view>
|
||||
<view class="iconfont line-height-100 checkbox checked iconradio-button-on" v-if="payType == 'alipay'" ></view>
|
||||
<view class="iconfont line-height-100 checkbox iconradio-button-off" v-else ></view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<!-- 支付方式 end -->
|
||||
<!-- 备注 begin -->
|
||||
<list-cell last @click="goToRemark">
|
||||
<view class="d-flex flex-fill align-items-center justify-content-between overflow-hidden" style="margin-bottom: 110rpx;">
|
||||
<view class="flex-shrink-0 mr-20">备注</view>
|
||||
<view class="text-color-primary flex-fill text-truncate text-right">{{ form.remark || '点击填写备注' }}
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<!-- 备注 end -->
|
||||
</view>
|
||||
<!-- 付款栏 begin -->
|
||||
<view style="z-index: 1;"
|
||||
class="w-100 pay-box position-fixed fixed-bottom d-flex align-items-center justify-content-between bg-white">
|
||||
<view class="font-size-sm" style="margin-left: 20rpx;">合计:</view>
|
||||
<view class="font-size-lg flex-fill">¥{{ amount }}</view>
|
||||
<view class="bg-primary h-100 d-flex align-items-center just-content-center text-color-white font-size-base"
|
||||
style="padding: 0 60rpx;" @tap="debounce(submit, 500)">付款</view>
|
||||
</view>
|
||||
<!-- 付款栏 end -->
|
||||
<modal :show="ensureAddressModalVisible" custom :mask-closable="false" :radius="'0rpx'" width="90%">
|
||||
<view class="modal-content">
|
||||
<view class="d-flex justify-content-end">
|
||||
<image src="/static/images/pay/close.png" style="width: 40rpx; height: 40rpx;"
|
||||
@tap="ensureAddressModalVisible = false"></image>
|
||||
</view>
|
||||
<view class="d-flex just-content-center align-items-center" style="margin-bottom: 40px;">
|
||||
<view class="font-size-extra-lg text-color-base">请再次确认下单地址</view>
|
||||
</view>
|
||||
<view
|
||||
class="d-flex font-size-base text-color-base font-weight-bold align-items-center justify-content-between mb-20">
|
||||
<view>{{ address.realName }}</view>
|
||||
<view>{{ address.phone }}</view>
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-assist align-items-center justify-content-between mb-40">
|
||||
<view style="max-width: 60%;">{{ address.address + address.detail }}</view>
|
||||
<button type="primary" size="mini" plain class="change-address-btn" style="white-space: nowrap;"
|
||||
@click="chooseAddress">修改地址</button>
|
||||
</view>
|
||||
<button type="primary" class="pay_btn" @tap="debounce(pay, 500)">确认并付款</button>
|
||||
</view>
|
||||
</modal>
|
||||
<uv-toast ref="uToast"></uv-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
nextTick
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow ,onPullDownRefresh,onHide} from '@dcloudio/uni-app'
|
||||
import { formatDateTime,isWeixin } from '@/utils/util'
|
||||
import debounce from '@/uni_modules/uv-ui-tools/libs/function/debounce'
|
||||
|
||||
import {
|
||||
orderSubmit,
|
||||
payUnify,
|
||||
getWechatConfig
|
||||
} from '@/api/order'
|
||||
import {
|
||||
couponCount
|
||||
} from '@/api/coupon'
|
||||
// #ifdef H5
|
||||
import * as jweixin from 'weixin-js-sdk'
|
||||
// #endif
|
||||
const main = useMainStore()
|
||||
const { orderType,address, store,location,isLogin,member,mycoupon } = storeToRefs(main)
|
||||
const active = ref(false)
|
||||
const title = ref('支付')
|
||||
const jsStr = ref('')
|
||||
const cart = ref([])
|
||||
const form = ref({
|
||||
remark: ''
|
||||
})
|
||||
const ensureAddressModalVisible = ref(false)
|
||||
const takeoutTIme = ref(false) // 外卖取餐时间picker
|
||||
const paramsTime = ref({
|
||||
year: false,
|
||||
month: false,
|
||||
day: false,
|
||||
hour: true,
|
||||
minute: true,
|
||||
second: false
|
||||
})
|
||||
const defaultTime = ref('00:00')
|
||||
const takeinTIme = ref(false) // 到店自取时间selector
|
||||
const takeinRange = ref([{
|
||||
name: '立即用餐',
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: '10分钟后',
|
||||
value: 10
|
||||
},
|
||||
{
|
||||
name: '20分钟后',
|
||||
value: 20
|
||||
},
|
||||
{
|
||||
name: '30分钟后',
|
||||
value: 30
|
||||
},
|
||||
{
|
||||
name: '40分钟后',
|
||||
value: 40
|
||||
},
|
||||
{
|
||||
name: '50分钟后',
|
||||
value: 50
|
||||
}
|
||||
])
|
||||
const defaultSelector = ref([0])
|
||||
const payType = ref('weixin') // 付款方式
|
||||
const coupons = ref(0) // 可用优惠券数量
|
||||
const coupon = ref(main.mycoupon) // 选中的
|
||||
const subscribeMss = ref({
|
||||
'takein': '',
|
||||
'takeout': '',
|
||||
'takein_made': '',
|
||||
'takeout_made': ''
|
||||
})// 微信订阅信息
|
||||
const uToast = ref()
|
||||
|
||||
const total = computed(() =>{
|
||||
return cart.value.reduce((acc, cur) => acc + cur.number * cur.price, 0);
|
||||
})
|
||||
const amount = computed(() =>{
|
||||
let amount = cart.value.reduce((acc, cur) => acc + cur.number * cur.price, 0);
|
||||
// 加配送费
|
||||
if (store.value.distance > 0 && orderType.value == 'takeout') {
|
||||
amount += parseFloat(store.value.deliveryPrice);
|
||||
}
|
||||
|
||||
|
||||
// 减去优惠券
|
||||
if (main.mycoupon.hasOwnProperty('id')) {
|
||||
amount -= parseFloat(main.mycoupon.value);
|
||||
}
|
||||
return amount.toFixed(2);
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
coupon.value = main.mycoupon
|
||||
let date = new Date(new Date().getTime() + 3600000); // 一个小时后
|
||||
let hour = date.getHours();
|
||||
let minute = date.getMinutes();
|
||||
if (hour < 10) {
|
||||
hour = '0' + hour;
|
||||
}
|
||||
if (minute < 10) {
|
||||
minute = '0' + minute;
|
||||
}
|
||||
defaultTime.value = hour + ':' + minute;
|
||||
|
||||
console.log('member:',member.value)
|
||||
|
||||
if(orderType.value == 'takeout'){
|
||||
active.value = true
|
||||
}else{
|
||||
active.value = false
|
||||
}
|
||||
|
||||
getCoupons();
|
||||
|
||||
let paytype = uni.getStorageSync('paytype');
|
||||
payType.value = paytype ? paytype : 'weixin';
|
||||
|
||||
})
|
||||
onHide(() => {
|
||||
subscribeMss.value = [];
|
||||
coupons.value = 0;
|
||||
})
|
||||
onLoad((option) => {
|
||||
cart.value = uni.getStorageSync('cart')
|
||||
if(option.remark) {
|
||||
form.value.remark = option.remark
|
||||
}
|
||||
})
|
||||
|
||||
const getSubscribeMss = async() => {
|
||||
let data = []
|
||||
if (data) {
|
||||
subscribeMss.value = data;
|
||||
}
|
||||
}
|
||||
// 更改支付方式
|
||||
const setPayType = (paytype) => {
|
||||
payType.value = 'weixin';
|
||||
payType.value= paytype;
|
||||
uni.setStorage({
|
||||
key: 'paytype',
|
||||
data: paytype
|
||||
})
|
||||
}
|
||||
const getCoupons = async() => {
|
||||
//0=通用,1=自取,2=外卖
|
||||
let type = orderType.value == 'takein' ? 1 : 2;
|
||||
let data = await couponCount({
|
||||
shop_id: store.value.id ? store.value.id : 0,
|
||||
type: type
|
||||
});
|
||||
if (data) {
|
||||
coupons.value = data;
|
||||
}
|
||||
}
|
||||
// 选择时间
|
||||
const choiceTime = (value) => {
|
||||
let hour = value.hour;
|
||||
let minute = value.minute;
|
||||
|
||||
let date = new Date(new Date().getTime() + 3600000); // 一个小时后
|
||||
let nowhour = date.getHours();
|
||||
let nowminute = date.getMinutes();
|
||||
|
||||
if ((hour * 60 * 60 + minute * 60) * 1000 - 3600000 < (nowhour * 60 * 60 + nowminute * 60) * 1000) {
|
||||
uToast.value.show({
|
||||
message: '请至少选择一个小时之后',
|
||||
type: 'error'
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
if (hour < 10) {
|
||||
hour = '0' + hour;
|
||||
}
|
||||
if (minute < 10) {
|
||||
minute = '0' + minute;
|
||||
}
|
||||
defaultTime,value = hour + ':' + minute;
|
||||
takeoutTIme.value = false;
|
||||
}
|
||||
const cancelTime = (value) => {
|
||||
takeoutTIme.value = false;
|
||||
}
|
||||
// 到店自取-取消选择取餐时间
|
||||
const takeinCancelTime = (value) => {
|
||||
takeinTIme.value = false;
|
||||
}
|
||||
// 到店自取-选择取餐时间
|
||||
const takeinConfirmTime = (value) => {
|
||||
defaultSelector.value = value;
|
||||
}
|
||||
// 是否外卖开关
|
||||
const takout = (value) => {
|
||||
let type = 'takeout';
|
||||
if (value == false) {
|
||||
type = 'takein';
|
||||
}
|
||||
main.SET_ORDER_TYPE(type);
|
||||
|
||||
// 如果存在优惠券看看需不需要清除
|
||||
if (coupon.value.hasOwnProperty('type')) {
|
||||
//0=通用,1=自取,2=外卖
|
||||
if (coupon.value.type != 0) {
|
||||
if (coupon.value.type == 1 && orderType.value == 'takeout') {
|
||||
coupon.value = {};
|
||||
}
|
||||
if (coupon.value.type == 2 && orderType.value == 'takeint') {
|
||||
coupon.value = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
subscribeMss.value = [];
|
||||
coupons.value = 0;
|
||||
getCoupons();
|
||||
}
|
||||
const goToRemark = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/remark/remark?remark=' + form.value.remark
|
||||
});
|
||||
}
|
||||
const chooseAddress = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/address/address?is_choose=true&scene=pay'
|
||||
});
|
||||
}
|
||||
const goToPackages = () => {
|
||||
let newamount = amount.value;
|
||||
let coupon_id = coupon.value.id ? coupon.value.id : 0;
|
||||
let type = orderType.value == 'takein' ? 1 : 2;
|
||||
let shop_id = store.value.id;
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/packages/index?amount=' + newamount + '&coupon_id=' + coupon_id +
|
||||
'&shop_id=' + shop_id + '&type=' + type
|
||||
});
|
||||
}
|
||||
const goToShop = () => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/components/pages/shop/shop`
|
||||
});
|
||||
}
|
||||
const submit = () => {
|
||||
if (orderType.value == 'takeout') {
|
||||
// 外卖类型
|
||||
if (typeof address.value.id == 'undefined') {
|
||||
uToast.value.show({
|
||||
message: '请选择收货地址',
|
||||
type: 'error'
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
// 起送价钱
|
||||
if (store.value.min_price > total.value) {
|
||||
uToast.value.show({
|
||||
message: '本店外卖起送价为¥' + store.value.min_price,
|
||||
type: 'error'
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
pay();
|
||||
|
||||
} else {
|
||||
pay();
|
||||
}
|
||||
}
|
||||
const pay = async() => {
|
||||
let that = this;
|
||||
// #ifdef MP-WEIXIN
|
||||
await new Promise(function(revolve) {
|
||||
//订阅号信息id
|
||||
let subscribeMss = ['KBtfY9G1IWCzC6q-ZKo-Q-MmdP7aaF79nx0XFcBf3h4'];
|
||||
|
||||
wx.showModal({
|
||||
title: '温馨提示',
|
||||
content: '为更好的促进您与商家的交流,小程序需要在您成交时向您发送消息',
|
||||
confirmText: "同意",
|
||||
cancelText: "拒绝",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
uni.requestSubscribeMessage({
|
||||
tmplIds: subscribeMss,
|
||||
complete(res) {
|
||||
console.log(res)
|
||||
revolve(true)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
revolve(true)
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
// #endif
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
|
||||
let data = {
|
||||
orderType: orderType.value, // 购买类型:takein=自取,takeout=外卖
|
||||
addressId:orderType.value == 'takeout' ? address.value.id : 0, // 外卖配送地址
|
||||
shopId: store.value.id, // 店铺id
|
||||
mobile: member.value.mobile, // 联系电话
|
||||
gettime: takeinRange.value[defaultSelector.value[0]].value, // 取餐时间
|
||||
payType: payType.value, // 支付类型
|
||||
remark: form.value.remark, // 备注
|
||||
productId: [],
|
||||
spec: [],
|
||||
number: [],
|
||||
couponId: coupon.value.id ? coupon.value.id : 0 // 优惠券id
|
||||
};
|
||||
|
||||
cart.value.forEach((item, index) => {
|
||||
data.productId.push(item.id);
|
||||
data.spec.push(item.valueStr.replace(/,/g, '|'));
|
||||
//data.spec.push(item.valueStr);
|
||||
data.number.push(item.number);
|
||||
});
|
||||
|
||||
//console.log(data);
|
||||
let order = await orderSubmit(data);
|
||||
if (!order) {
|
||||
uni.hideLoading();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (payType.value == 'weixin') {
|
||||
// 微信支付
|
||||
weixinPay(order);
|
||||
} else if (payType.value == 'yue') {
|
||||
// 余额支付
|
||||
balancePay(order);
|
||||
} else if (payType.value == 'alipay') {
|
||||
// 余额支付
|
||||
aliPay(order);
|
||||
}
|
||||
uni.hideLoading()
|
||||
return
|
||||
}
|
||||
const balancePay = async(order) => {
|
||||
let from = 'routine'
|
||||
// #ifdef H5
|
||||
from = 'h5'
|
||||
// #endif
|
||||
let pay = await payUnify({
|
||||
uni: order.orderId,
|
||||
from: from,
|
||||
paytype: 'yue'
|
||||
});
|
||||
|
||||
uni.hideLoading();
|
||||
if (!pay) {
|
||||
return;
|
||||
}
|
||||
|
||||
member.value.money -= amount.value
|
||||
main.SET_MEMBER(member.value)
|
||||
uni.removeStorageSync('cart');
|
||||
uni.switchTab({
|
||||
url: '/pages/order/order',
|
||||
fail(res) {
|
||||
console.log(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
const weixinPay = async(order) => {
|
||||
let from = 'routine'
|
||||
// #ifdef H5
|
||||
from = 'h5'
|
||||
if(isWeixin()){
|
||||
from = 'wechat'
|
||||
}
|
||||
|
||||
// #endif
|
||||
//let that = this;
|
||||
let data = await payUnify({
|
||||
uni: order.orderId,
|
||||
from: from,
|
||||
paytype: 'weixin'
|
||||
});
|
||||
console.log('param2:',data)
|
||||
if (!data) {
|
||||
uni.hideLoading();
|
||||
return;
|
||||
}
|
||||
if (data.trade_type == 'MWEB') {
|
||||
// #ifdef H5
|
||||
// 微信外的H5
|
||||
console.log('data:',data)
|
||||
location.href = data.data;
|
||||
// #endif
|
||||
console.log('data1:',data)
|
||||
} else if (data.trade_type == 'JSAPI') {
|
||||
console.log('param:',data)
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
timeStamp: data.data.timeStamp,
|
||||
nonceStr: data.data.nonceStr,
|
||||
package: data.data.package,
|
||||
signType: 'MD5',
|
||||
paySign: data.data.paySign,
|
||||
success: function(res) {
|
||||
|
||||
uni.removeStorageSync('cart');
|
||||
uni.switchTab({
|
||||
url: '/pages/order/order'
|
||||
});
|
||||
},
|
||||
fail: function(err) {
|
||||
console.log('fail:' + JSON.stringify(err));
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
} else if (data.trade_type == 'W-JSAPI'){
|
||||
//公众号支付
|
||||
|
||||
|
||||
}else if (data.trade_type == 'APP') {
|
||||
|
||||
}
|
||||
}
|
||||
const aliPay = async(order) => {
|
||||
|
||||
// #ifdef H5
|
||||
//let that = this;
|
||||
if(isWeixin()){
|
||||
uni.showToast({
|
||||
title: '请普通浏览器打开进行支付宝支付~',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
let data = await payUnify({
|
||||
uni: order.orderId,
|
||||
from: 'h5',
|
||||
paytype: 'alipay'
|
||||
});
|
||||
|
||||
console.log('data:',data.data)
|
||||
// 支付宝支付,这里只要提交表单
|
||||
let form = data.data
|
||||
const div = document.createElement('formdiv');
|
||||
div.innerHTML = form;
|
||||
document.body.appendChild(div);
|
||||
//document.forms[0].setAttribute('target', ' self');
|
||||
document.forms[0].submit();
|
||||
//div.remove();
|
||||
|
||||
// #endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
position: relative;
|
||||
margin-right: -10rpx;
|
||||
}
|
||||
|
||||
.location {
|
||||
.store-name {
|
||||
font-size: $font-size-lg;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 50rpx;
|
||||
line-height: 100%;
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.section-1 {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.contact {
|
||||
.contact-tip {
|
||||
margin-left: 10rpx;
|
||||
border: 2rpx solid $color-primary;
|
||||
padding: 6rpx 10rpx;
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section-2 {
|
||||
.name-and-props {
|
||||
width: 65%;
|
||||
}
|
||||
}
|
||||
|
||||
.payment {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.disabled {
|
||||
color: $text-color-grey;
|
||||
}
|
||||
|
||||
.payment-icon {
|
||||
font-size: 44rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
font-size: 36rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.checked {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.pay-box {
|
||||
box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.1);
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
.change-address-btn {
|
||||
line-height: 2;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
.pay_btn {
|
||||
width: 100%;
|
||||
border-radius: 50rem !important;
|
||||
line-height: 3;
|
||||
}
|
||||
}
|
||||
|
||||
.choice {
|
||||
background-color: $bg-color-grey;
|
||||
border-radius: 38rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: $font-size-sm;
|
||||
padding: 0 38rpx;
|
||||
color: $text-color-assist;
|
||||
|
||||
.dinein,
|
||||
.takeout {
|
||||
width: 50%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&.active {
|
||||
padding: 14rpx 38rpx;
|
||||
color: #ffffff;
|
||||
background-color: $color-primary;
|
||||
border-radius: 38rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.takeout {
|
||||
margin-left: 20rpx;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
padding: 14rpx 0;
|
||||
}
|
||||
|
||||
.dinein.active {
|
||||
//margin-left: -38rpx;
|
||||
}
|
||||
|
||||
.takeout.active {
|
||||
//margin-right: -38rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container w-100 h-100 overflow-hidden">
|
||||
<view class="textarea">
|
||||
<textarea placeholder-class="text-color-assist font-size-base" v-model="remark"
|
||||
class="bg-white w-100 border-box font-size-base remark"
|
||||
:class="{'text-color-danger': remarkLength > 50, 'text-color-assist' : remarkLength <=50}"
|
||||
placeholder="请填写备注信息" focus/>
|
||||
<view class="tips" :class="{'text-color-danger': remarkLength > 50, 'text-color-assist' : remarkLength <=50}">
|
||||
{{ remarkLength }}/50
|
||||
</view>
|
||||
</view>
|
||||
<view class="d-flex font-size-base text-color-assist" style="margin: 40rpx 0;">
|
||||
快捷输入
|
||||
</view>
|
||||
<view class="quick-inputs d-flex flex-wrap justify-content-start">
|
||||
<view class="quick-input" v-for="(item, index) in quickInputs" :key="index" @tap="handleQuickInput(item)">
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="d-flex just-content-center align-items-center" style="margin-top: 60rpx;">
|
||||
<button type="primary" class="submit-btn font-size-base" @tap="submit">完成</button>
|
||||
</view>
|
||||
<!--轻提示-->
|
||||
<uv-toast ref="uToast"></uv-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { onLoad} from '@dcloudio/uni-app'
|
||||
|
||||
const remark = ref('')
|
||||
const quickInputs = ref( ['请放门把手上', '请放门口', '请放前台桌上', '如地址封闭管理,请电话与我联系'])
|
||||
const uToast = ref()
|
||||
|
||||
onLoad((opt) => {
|
||||
remark.value = opt.remark
|
||||
})
|
||||
|
||||
const remarkLength = computed(() => {
|
||||
return remark.value.length
|
||||
})
|
||||
const isDanger = computed(() => {
|
||||
return remark.value.length > 50
|
||||
})
|
||||
|
||||
const handleQuickInput = (item) => {
|
||||
remark.value = remark.value.concat(" ", item)
|
||||
}
|
||||
const submit = () => {
|
||||
if (remark.value.length > 50) {
|
||||
uToast.value.show({
|
||||
message: '不能超过50个字符',
|
||||
type: 'error'
|
||||
});
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: "/pages/components/pages/pay/pay?remark=" + remark.value
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
padding: 30rpx 40rpx;
|
||||
|
||||
.textarea {
|
||||
position: relative;
|
||||
|
||||
.remark {
|
||||
border-radius: 8rpx;
|
||||
padding: 30rpx 40rpx;
|
||||
height: 320rpx;
|
||||
color: $font-size-base;
|
||||
}
|
||||
|
||||
.tips {
|
||||
position: absolute;
|
||||
bottom: 30rpx;
|
||||
right: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.quick-inputs {
|
||||
padding-right: 20rpx;
|
||||
|
||||
.quick-input {
|
||||
background-color: #FFFFFF;
|
||||
border: 2rpx solid $color-primary;
|
||||
color: $color-primary;
|
||||
font-size: $font-size-base;
|
||||
padding: 16rpx 26rpx;
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 90%;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
line-height: 80rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view>
|
||||
<view>
|
||||
<uv-search margin="30rpx" v-model="keywork" @custom="search(keywork)"></uv-search>
|
||||
</view>
|
||||
<view v-for="(item,index) in list" :key="index">
|
||||
<uni-card @click="choice(item)" :border="item.id == store.id" :title="item.name" :thumbnail="item.image" :thumb-width="80" :sub-title="item.status_text">
|
||||
<view class="body">
|
||||
<view class="body-left">
|
||||
<view>距离您 {{kmUnit(item.dis)}}</view>
|
||||
<view v-if="item.distance > 0">配送距离:{{item.distance + 'km '}} & 配送费:{{item.delivery_price}}</view>
|
||||
<view v-else>外卖不配送</view>
|
||||
<view>{{item.addressMap + ' ' + item.address}}</view>
|
||||
<view>营业时间 {{formatDateTime(item.startTime,'hh:mm')}} - {{formatDateTime(item.endTime,'hh:mm')}}</view>
|
||||
</view>
|
||||
<view class="body-right">
|
||||
<uv-button @click="openLocation(item)">导航</uv-button>
|
||||
<uv-button @click="call(item.mobile)">致电</uv-button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow ,onPullDownRefresh,onHide} from '@dcloudio/uni-app'
|
||||
import { formatDateTime,kmUnit,prePage } from '@/utils/util'
|
||||
import {
|
||||
shopNearby,
|
||||
menuGoods
|
||||
} from '@/api/goods'
|
||||
import {
|
||||
shopGetList
|
||||
} from '@/api/market'
|
||||
const main = useMainStore()
|
||||
const { store,location } = storeToRefs(main)
|
||||
const title = ref('店铺')
|
||||
const list = ref([])
|
||||
const keywork = ref('')
|
||||
const page = ref(1)
|
||||
const pagesize = ref(10)
|
||||
|
||||
onLoad(() => {
|
||||
getShop();
|
||||
})
|
||||
|
||||
const getShop = async(keywork = '') => {
|
||||
let data = await shopGetList({
|
||||
lat: location.value.latitude ? location.value.latitude : 0,
|
||||
lng: location.value.longitude ? location.value.longitude : 0,
|
||||
kw: keywork,
|
||||
shop_id: 0
|
||||
});
|
||||
if (data) {
|
||||
//console.log(data);
|
||||
if (page.value == 1) {
|
||||
list.value = data;
|
||||
} else {
|
||||
for(let i in data) {
|
||||
list.value.push(data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//打开定位
|
||||
const openLocation = (shop) => {
|
||||
//console.log(shop);
|
||||
uni.openLocation({
|
||||
latitude: parseFloat(shop.lat),
|
||||
longitude: parseFloat(shop.lng),
|
||||
name:shop.name,
|
||||
address: shop.addressMap + shop.address,
|
||||
fail: (res) => {
|
||||
console.log(res);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 打电话
|
||||
const call = (mobile) => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber:mobile
|
||||
})
|
||||
}
|
||||
// 搜索按钮
|
||||
const search = (keywork) => {
|
||||
page.value = 1;
|
||||
getShop(keywork);
|
||||
}
|
||||
// 选中店铺
|
||||
const choice = (shop) => {
|
||||
main.SET_STORE(shop);
|
||||
uni.$emit('refreshMenu')
|
||||
uni.switchTab({
|
||||
url:'/pages/menu/menu',
|
||||
success(res) {
|
||||
},
|
||||
fail(res) {
|
||||
console.log(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.body {
|
||||
|
||||
.body-left {
|
||||
display: inline-block;
|
||||
width: 77%;
|
||||
padding-left: 6rpx;
|
||||
}
|
||||
.body-right {
|
||||
display: inline-block;
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
.u-border {
|
||||
border: 1rpx solid #1296db;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,314 @@
|
||||
<template>
|
||||
<layout>
|
||||
<uv-sticky
|
||||
bg-color="#F5F5F5"
|
||||
offset-top="0"
|
||||
customNavHeight="0"
|
||||
>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:safeAreaInsetTop="true"
|
||||
height="0"
|
||||
bgColor="transparent"
|
||||
leftIcon=""
|
||||
/>
|
||||
<!-- #ifndef MP -->
|
||||
<blank size="10"></blank>
|
||||
<!-- #endif -->
|
||||
|
||||
<blank size="5"></blank>
|
||||
</uv-sticky>
|
||||
|
||||
<blank size="10"></blank>
|
||||
<view class="container">
|
||||
<view class="banner">
|
||||
<uv-swiper class="bg" height="300" imgMode="aspectFill" keyName="image" :list="listAds" indicatorMode="dot" indicatorStyle="bottom"></uv-swiper>
|
||||
<view class="intro">
|
||||
<view class="greet">您好,{{ isLogin ? member.nickname : '游客' }}</view>
|
||||
<view class="note">java-springboot-意向点餐外卖系统</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="entrance">
|
||||
<view class="item " @tap="takein">
|
||||
<view>
|
||||
<view class="font-md">自取</view>
|
||||
<view class="font-small text-light-black flex-1">下单免排队</view>
|
||||
</view>
|
||||
<view class="index-img">
|
||||
<image src="/static/images/index002.png" mode="aspectFit" class="img-01"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item" @tap="takeout">
|
||||
<view>
|
||||
<view class="font-md">外卖</view>
|
||||
<view class="font-small text-light-black">美食送到家</view>
|
||||
</view>
|
||||
<view class="index-img"><image src="/static/images/index003.png" mode="aspectFit" class="img-02"></image></view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="integral_section">
|
||||
<view class="top">
|
||||
<text class="title">我的卡券</text>
|
||||
<text class="value">{{member.couponCount}}</text>
|
||||
</view>
|
||||
<view class="bottom">
|
||||
可抵扣商品价格哦
|
||||
</view>
|
||||
</view>
|
||||
<view class="qrcode_section" @tap="coupons">
|
||||
去领个券
|
||||
<view class="iconfont iconarrow-right"></view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import {
|
||||
menuAds
|
||||
} from '@/api/market'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useMainStore } from '@/store/store'
|
||||
//
|
||||
const main = useMainStore()
|
||||
const { member,store, isLogin} = storeToRefs(main)
|
||||
//const store = ref(main.store)
|
||||
const listAds = ref([])
|
||||
// const isLogin = ref(main.isLogin)
|
||||
|
||||
const handGetListAds = async () => {
|
||||
let shop_id = store.id ? store.id : 0;
|
||||
let data = await menuAds({
|
||||
shop_id: shop_id
|
||||
});
|
||||
if (data) {
|
||||
listAds.value = data.list;
|
||||
console.log('listAds:',listAds.value)
|
||||
uni.setStorage({
|
||||
key: 'isActive',
|
||||
data: data.isActive
|
||||
});
|
||||
if(data.list.length > 0){
|
||||
uni.setStorage({
|
||||
key: 'shopAd',
|
||||
data: data.list[0].image
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const takein = () => {
|
||||
main.SET_ORDER_TYPE('takein')
|
||||
uni.switchTab({
|
||||
url: '/pages/menu/menu'
|
||||
})
|
||||
}
|
||||
|
||||
const takeout = () => {
|
||||
main.SET_ORDER_TYPE('takeout')
|
||||
uni.switchTab({
|
||||
url: '/pages/menu/menu'
|
||||
})
|
||||
}
|
||||
|
||||
const coupons = () => {
|
||||
console.log("--> % orderType:\n", main.orderType)
|
||||
console.log("--> % isLogin:\n", main.isLogin)
|
||||
if(!main.isLogin) {
|
||||
uni.navigateTo({url: '/pages/components/pages/login/login'})
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/coupons/coupons'
|
||||
})
|
||||
}
|
||||
|
||||
const goScore = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/scoreproduct/list'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
onLoad(() => {
|
||||
// main.init()
|
||||
handGetListAds()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.index-img {
|
||||
width: 120px;
|
||||
height: 120rpx;
|
||||
position: relative;
|
||||
left:-20rpx
|
||||
}
|
||||
.img-01 {
|
||||
width: 100px;
|
||||
height: 100rpx;
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
.img-02 {
|
||||
width: 110px;
|
||||
height: 110rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
|
||||
/* #ifdef H5 */
|
||||
page {
|
||||
height: auto;
|
||||
min-height: 100%;
|
||||
}
|
||||
/* #endif */
|
||||
page {
|
||||
background-color: #ffffff!important;
|
||||
}
|
||||
.banner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
//height: 300rpx;
|
||||
|
||||
.bg {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
}
|
||||
|
||||
.intro {
|
||||
position: absolute;
|
||||
top: calc(50rpx + var(--status-bar-height));
|
||||
left: 40rpx;
|
||||
color: #FFFFFF;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.greet {
|
||||
font-size: $font-size-lg;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.note {
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 50rpx;
|
||||
}
|
||||
|
||||
.entrance {
|
||||
position: relative;
|
||||
//top:0;
|
||||
margin-top: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #ffffff;
|
||||
box-shadow: $box-shadow;
|
||||
padding: 30rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50rpx;
|
||||
.item {
|
||||
//flex: 1;
|
||||
display: flex;
|
||||
//flex-direction: column;
|
||||
justify-content: center;
|
||||
//align-items: center;
|
||||
position: relative;
|
||||
|
||||
&:nth-child(1):after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 1rpx;
|
||||
background-color: #ddd;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
transform: scaleX(0.5) scaleY(0.8);
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 90rpx;
|
||||
// color: #5A5B5C;
|
||||
color: #dd524d;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
color: $text-color-base;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
position: relative;
|
||||
margin-bottom: 30rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #ffffff;
|
||||
box-shadow: $box-shadow;
|
||||
//padding: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.integral_section {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
color: $text-color-base;
|
||||
font-size: $font-size-base;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.value {
|
||||
font-size: 44rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-color-assist;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.qrcode_section {
|
||||
color: $color-primary;
|
||||
display: flex;
|
||||
//flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: $font-size-sm;
|
||||
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,373 @@
|
||||
<template>
|
||||
<layout>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container">
|
||||
<view style="padding: 0 30rpx;">
|
||||
<!-- user box begin -->
|
||||
<view class="d-flex flex-column bg-white user-box">
|
||||
|
||||
<view class="d-flex align-items-center">
|
||||
<view class="avatar rounded-circle">
|
||||
<image :src="isLogin ? member.avatar ? member.avatar : '/static/images/mine/default.png' : '/static/images/mine/default.png'"></image>
|
||||
</view>
|
||||
<view class="d-flex flex-column flex-fill overflow-hidden" style="margin-top: 20rpx;">
|
||||
<view v-if="isLogin"
|
||||
class="font-size-lg font-weight-bold d-flex justify-content-start align-items-center"
|
||||
@tap="serv({type:'pages',pages:'/pages/components/pages/mine/userinfo'})">
|
||||
<view class="text-truncate">{{ member.nickname }}</view>
|
||||
<view class="iconfont iconarrow-right line-height-100"></view>
|
||||
</view>
|
||||
<view v-else class="font-size-lg font-weight-bold" @tap="login">游客</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- user grid begin -->
|
||||
<view class="w-100 d-flex align-items-center just-content-center">
|
||||
<view class="user-grid" @tap="serv({type:'pages',pages:'/pages/components/pages/coupons/coupons'})">
|
||||
<view class="value font-size-extra-lg font-weight-bold text-color-base">
|
||||
{{ isLogin ? member.couponCount : 0}}
|
||||
</view>
|
||||
<view class="font-size-sm text-color-assist">优惠券</view>
|
||||
</view>
|
||||
<view class="user-grid" @tap="serv({type:'pages', pages: '/pages/components/pages/balance/bill?cate=1'})">
|
||||
<view class="value font-size-extra-lg font-weight-bold text-color-base">
|
||||
{{ isLogin ? member.integral : 0 }}
|
||||
</view>
|
||||
<view class="font-size-sm text-color-assist">积分</view>
|
||||
</view>
|
||||
<view class="user-grid">
|
||||
<view class="value font-size-extra-lg font-weight-bold text-color-base">
|
||||
{{ isLogin ? member.nowMoney : 0 }}
|
||||
</view>
|
||||
<view class="font-size-sm text-color-assist">余额</view>
|
||||
</view>
|
||||
<view class="user-grid" @tap="serv({type:'pages', pages: '/pages/components/pages/balance/bill?cate=0'})">
|
||||
<view class="value font-size-extra-lg font-weight-bold text-color-base">
|
||||
{{ isLogin ? member.sumMoney : 0 }}
|
||||
</view>
|
||||
<view class="font-size-sm text-color-assist">历史消费</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- user grid end -->
|
||||
</view>
|
||||
<!-- user box end -->
|
||||
|
||||
</view>
|
||||
<!-- service box begin -->
|
||||
<view class="service-box">
|
||||
<view class="font-size-lg text-color-base font-weight-bold" style="margin-bottom: 20rpx;">我的服务</view>
|
||||
<view class="u-m-t-20">
|
||||
<uv-cell-group>
|
||||
<block v-for="(item, index) in services" :key='index'>
|
||||
<uv-cell :title="item.name" v-if="item.type == 'contact'" :isLink="true">
|
||||
<template #icon>
|
||||
<image :src="item.image" style="width: 40rpx;height: 40rpx;" class="mr-1"></image>
|
||||
</template>
|
||||
</uv-cell>
|
||||
<uv-cell :isLink="true" :title="item.name" v-else-if="item.type == 'call'" v-on:click="makePhoneCall(item.phone)">
|
||||
<template #icon>
|
||||
<image :src="item.image" style="width: 40rpx;height: 40rpx;" class="mr-1"></image>
|
||||
</template>
|
||||
</uv-cell>
|
||||
<uv-cell :isLink="true" :title="item.name" v-else @tap="serv(item)">
|
||||
<template #icon>
|
||||
<image :src="item.image" style="width: 40rpx;height: 40rpx;" class="mr-1"></image>
|
||||
</template>
|
||||
</uv-cell>
|
||||
</block>
|
||||
</uv-cell-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow} from '@dcloudio/uni-app'
|
||||
import { formatDateTime,kmUnit } from '@/utils/util'
|
||||
import {
|
||||
userGetUserInfo,
|
||||
mineService
|
||||
} from '@/api/user'
|
||||
const main = useMainStore()
|
||||
const { member,isLogin } = storeToRefs(main)
|
||||
|
||||
const title = ref('个人中心')
|
||||
const services = ref([])
|
||||
|
||||
const growthValue = computed(() => {
|
||||
if (!isLogin.value) return 0
|
||||
const {
|
||||
currentValue,
|
||||
needValue
|
||||
} = member.value
|
||||
return currentValue / (currentValue + needValue) * 100
|
||||
})
|
||||
|
||||
onLoad(() => {
|
||||
getServices();
|
||||
})
|
||||
onShow(() => {
|
||||
getUserInfo();
|
||||
})
|
||||
|
||||
|
||||
const getUserInfo = async() => {
|
||||
if (isLogin.value) {
|
||||
let data = await userGetUserInfo();
|
||||
if (data) {
|
||||
main.SET_MEMBER(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
const getServices = async() => {
|
||||
let data = await mineService();
|
||||
if (data) {
|
||||
services.value = data;
|
||||
}
|
||||
}
|
||||
const makePhoneCall = (phoneNumber) => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: phoneNumber,
|
||||
})
|
||||
}
|
||||
const login = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/login/login'
|
||||
})
|
||||
}
|
||||
const packages = () => {
|
||||
if (!isLogin.value) {
|
||||
login()
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/packages/index'
|
||||
})
|
||||
}
|
||||
const serv = (item) => {
|
||||
switch (item.type) {
|
||||
case 'pages':
|
||||
if (!isLogin.value) {
|
||||
login()
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: item.pages
|
||||
})
|
||||
break;
|
||||
case 'miniprogram':
|
||||
uni.navigateToMiniProgram({
|
||||
appId: item.app_id
|
||||
})
|
||||
break;
|
||||
case 'menu':
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/mine/service?id=' + item.id + '&name=' + item.name
|
||||
})
|
||||
break;
|
||||
case 'content':
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/mine/content?id=' + item.id + '&name=' + item.name
|
||||
})
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
height: auto;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.bg {
|
||||
width: 100%;
|
||||
height: calc(410 / 594 * 750rpx);
|
||||
}
|
||||
|
||||
.hym-btn {
|
||||
position: absolute;
|
||||
top: 40rpx;
|
||||
right: 40rpx;
|
||||
color: $color-primary;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50rem;
|
||||
font-size: $font-size-sm;
|
||||
box-shadow: 0 0 20rpx rgba(66, 66, 66, 0.1);
|
||||
|
||||
&::after {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.user-box {
|
||||
position: relative;
|
||||
border-radius: 8rpx;
|
||||
margin-bottom: 30rpx;
|
||||
margin-top: 70rpx;
|
||||
box-shadow: $box-shadow;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
position: relative;
|
||||
margin-top: -35rpx;
|
||||
margin-left: 35rpx;
|
||||
margin-right: 35rpx;
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #FFFFFF;
|
||||
box-shadow: 0 0 20rpx rgba($color: #000000, $alpha: 0.2);
|
||||
|
||||
image {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
right: -10rpx;
|
||||
bottom: -10rpx;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 50rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: $color-warning;
|
||||
font-size: 24rpx;
|
||||
padding: 8rpx 16rpx;
|
||||
box-shadow: 0 0 20rpx rgba($color: #000000, $alpha: 0.2);
|
||||
|
||||
image {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.level-benefit {
|
||||
margin-left: 35rpx;
|
||||
padding: 10rpx 0 10rpx 30rpx;
|
||||
border-radius: 50rem 0 0 50rem;
|
||||
}
|
||||
|
||||
.user-grid {
|
||||
width: 25%;
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.value {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.level-benefit-box {
|
||||
border-radius: 8rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 10rpx 8rpx rgba($color: #878889, $alpha: 0.1);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding: 30rpx;
|
||||
flex-direction: column;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
padding: 30rpx 0 20rpx;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
|
||||
.grid {
|
||||
width: 20%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: $font-size-sm;
|
||||
color: $text-color-assist;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.banner {
|
||||
width: 100%;
|
||||
border-radius: 8rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.service-box {
|
||||
width: 100%;
|
||||
background-color: #FFFFFF;
|
||||
padding: 32rpx 30rpx 10rpx;
|
||||
box-shadow: $box-shadow;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
color: $text-color-assist;
|
||||
font-size: $font-size-sm;
|
||||
padding-bottom: -40rpx;
|
||||
|
||||
.grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
width: 25%;
|
||||
position: relative;
|
||||
|
||||
image {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.opacity-0 {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<view class="container">
|
||||
<view class="bg-white">
|
||||
<uv-tabs :list="tabList" :current="current" @change="change" keyName="name" :scrollable="false"></uv-tabs>
|
||||
</view>
|
||||
<view class="orders-list d-flex flex-column w-100" style="padding: 20rpx; padding-bottom: 0;">
|
||||
<view class="order-item" v-for="(item, index) in orders" :key="index" style="margin-bottom: 30rpx;" >
|
||||
<list-cell :hover="false">
|
||||
<view class="w-100 d-flex align-items-center">
|
||||
<view class="flex-fill d-flex flex-column">
|
||||
<view class="font-size-lg text-color-base" style="margin-bottom: 20rpx;">
|
||||
{{ item.shop.name }}
|
||||
</view>
|
||||
<view class="font-size-sm text-color-assist">取餐号:{{ item.numberId }}</view>
|
||||
<view class="font-size-sm text-color-assist">订单编号:{{ item.orderId }}</view>
|
||||
</view>
|
||||
<view class="font-size-lg text-color-primary">
|
||||
{{ item._status._title }}
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell :hover="false" last>
|
||||
<view class="w-100 d-flex flex-column">
|
||||
<view class="w-100 text-truncate font-size-lg text-color-base" style="margin-bottom: 20rpx;">
|
||||
<!-- {{ orderGoodsName(item.cartInfo) }} -->
|
||||
<view class="flex mb-2" v-for="(good,index) in item.cartInfo" :key="index">
|
||||
<image :src="good.image" mode="aspectFill" class="image"></image>
|
||||
<view class="flex flex-column">
|
||||
<view class="font-size-medium mt-1 text-color-base">{{ good.title }}</view>
|
||||
<view class="font-size-sm mt-1">{{ good.spec }}</view>
|
||||
<view class="font-size-sm mt-2">×{{ good.number }} ¥{{ good.price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="d-flex justify-content-between align-items-center" style="margin-bottom: 30rpx;">
|
||||
<view class="font-size-sm text-color-assist">
|
||||
{{formatDateTime(item.createTime) }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base align-items-center">
|
||||
<view style="margin-right: 10rpx;">共{{ goodsNum(item.cartInfo) }}件商品,实付</view>
|
||||
<view class="font-size-lg">¥{{ item.payPrice }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="d-flex align-items-center justify-content-end">
|
||||
<view>
|
||||
<button v-if="item.paid > 0 && item.status < 2 && item.refundStatus == 0" class="left-margin" plain size="mini" @tap.stop="receive(item)">确认收到餐</button>
|
||||
<button class="left-margin" plain size="mini" @tap="detail(item.orderId)">订单详情</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
</view>
|
||||
</view>
|
||||
<uv-empty v-if="orders.length == 0" mode="order"></uv-empty>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onPullDownRefresh,onReachBottom} from '@dcloudio/uni-app'
|
||||
import { formatDateTime,kmUnit } from '@/utils/util'
|
||||
import {
|
||||
orderGetOrders,
|
||||
orderReceive
|
||||
} from '@/api/order'
|
||||
const main = useMainStore()
|
||||
const { isLogin } = storeToRefs(main)
|
||||
const title = ref('我的订单')
|
||||
|
||||
const page = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const orders = ref([])
|
||||
const tabList = ref([{
|
||||
type: -1,
|
||||
name: '全部',
|
||||
}, {
|
||||
type: 0,
|
||||
name: '待支付',
|
||||
}, {
|
||||
type: 1,
|
||||
name: '进行中'
|
||||
}, {
|
||||
type: 4,
|
||||
name: '已完成'
|
||||
}, {
|
||||
type: -3,
|
||||
name: '退款单'
|
||||
}]
|
||||
)
|
||||
const current = ref(0)
|
||||
const type = ref(-1)
|
||||
|
||||
const orderGoodsName = computed(() => { //计算单个饮品添加到购物车的数量
|
||||
return (goods) => {
|
||||
let arr = []
|
||||
goods.forEach(good => arr.push(good.title + '*' + good.number))
|
||||
return arr.join(',')
|
||||
}
|
||||
})
|
||||
const goodsNum = computed(() => { //计算单个饮品添加到购物车的数量
|
||||
return (goods) => {
|
||||
let num = 0;
|
||||
goods.forEach(good => num += parseInt(good.number))
|
||||
return num;
|
||||
}
|
||||
})
|
||||
onLoad(() => {
|
||||
if(!isLogin.value) {
|
||||
uni.navigateTo({url: '/pages/components/pages/login/login'})
|
||||
}
|
||||
getOrders(false)
|
||||
})
|
||||
onPullDownRefresh(() => {
|
||||
getOrders(false)
|
||||
})
|
||||
onReachBottom(() => {
|
||||
getOrders(false)
|
||||
})
|
||||
|
||||
// tab栏切换
|
||||
const change = (e) => {
|
||||
//console.log('e;',e.type)
|
||||
//console.log('e.index;',e.index)
|
||||
type.value = e.type
|
||||
getOrders(true)
|
||||
}
|
||||
|
||||
const getOrders = async(isRefresh = false) => {
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
})
|
||||
if(isRefresh) {
|
||||
orders.value = []
|
||||
page.value = 1
|
||||
}
|
||||
let ordersData = await orderGetOrders({page:page.value, limit:pageSize.value,type:type.value});
|
||||
|
||||
if(ordersData) {
|
||||
orders.value = orders.value.concat(ordersData)
|
||||
page.value += 1
|
||||
}
|
||||
uni.stopPullDownRefresh();
|
||||
uni.hideLoading()
|
||||
}
|
||||
const detail = (id) => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/orders/detail?id=' + id
|
||||
})
|
||||
}
|
||||
// 确认收到货
|
||||
const receive = async(order) => {
|
||||
let data = await orderReceive({uni:order.orderId});
|
||||
if (data) {
|
||||
await getOrders(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left-margin {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
.image {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
margin-right: 30rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,23 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4205200 */
|
||||
src: url('~@/static/iconfont/iconfont.woff2?t=1691643169117') format('woff2'),
|
||||
url('~@/static/iconfont/iconfont.woff?t=1691643169117') format('woff'),
|
||||
url('~@/static/iconfont/iconfont.ttf?t=1691643169117') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-waimai-:before {
|
||||
content: "\e607";
|
||||
}
|
||||
|
||||
.icon-tangshi:before {
|
||||
content: "\e645";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
|
||||
@font-face {
|
||||
font-family: 'iconfont-yshop';
|
||||
src: url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.eot');
|
||||
src: url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.eot?#iefix') format('embedded-opentype'),
|
||||
url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.woff2') format('woff2'),
|
||||
url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.woff') format('woff'),
|
||||
url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.ttf') format('truetype'),
|
||||
url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.svg#iconfont-yshop') format('svg');
|
||||
|
||||
}
|
||||
|
||||
.iconfont-yshop {
|
||||
font-family: 'iconfont-yshop' !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #5A5B5C;
|
||||
}
|
||||
.icon-alipay:before {
|
||||
content: '\e60a';
|
||||
}
|
||||
.icon-shop:before {
|
||||
content: '\e664';
|
||||
}
|
||||
.icon-takein:before {
|
||||
content: '\e666';
|
||||
}
|
||||
.icon-takeout:before {
|
||||
content: '\e667';
|
||||
}
|
||||
.icon-location:before {
|
||||
content: '\e633';
|
||||
}
|
||||
.icon-mobile:before {
|
||||
content: '\e602';
|
||||
}
|
||||
.icon-box:before {
|
||||
content: '\e665';
|
||||
}
|
||||
.icon-lamp:before {
|
||||
content: '\e668';
|
||||
}
|
||||
.icon-doorbell:before {
|
||||
content: '\e662';
|
||||
}
|
||||
.icon-daojishi:before {
|
||||
content: '\e625';
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('//at.alicdn.com/t/font_1789197_z1gzlwq7idq.ttf?t=1589441233693') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: 'iconfont' !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.iconshoucang:before {
|
||||
content: '\e667';
|
||||
}
|
||||
|
||||
.iconshoucangfill:before {
|
||||
content: '\e6c9';
|
||||
}
|
||||
|
||||
.iconjifen:before {
|
||||
content: '\e642';
|
||||
}
|
||||
|
||||
.iconradio-button-off:before {
|
||||
content: '\e688';
|
||||
}
|
||||
|
||||
.iconradio-button-on:before {
|
||||
content: '\e689';
|
||||
}
|
||||
|
||||
.iconhelp:before {
|
||||
content: '\e752';
|
||||
}
|
||||
|
||||
.iconwxpay:before {
|
||||
content: '\e611';
|
||||
}
|
||||
|
||||
.iconbalance:before {
|
||||
content: '\e619';
|
||||
}
|
||||
|
||||
.iconadd-select:before {
|
||||
content: '\e7b0';
|
||||
}
|
||||
|
||||
.iconsami-select:before {
|
||||
content: '\e7b1';
|
||||
}
|
||||
|
||||
.iconmap:before {
|
||||
content: '\e758';
|
||||
}
|
||||
|
||||
.iconsuccess:before {
|
||||
content: '\e767';
|
||||
}
|
||||
|
||||
.iconsuccess-fill:before {
|
||||
content: '\e78d';
|
||||
}
|
||||
|
||||
.iconiconset0136:before {
|
||||
content: '\e623';
|
||||
}
|
||||
|
||||
.iconzan:before {
|
||||
content: '\e640';
|
||||
}
|
||||
|
||||
.iconjifenqiandao:before {
|
||||
content: '\e6a6';
|
||||
}
|
||||
|
||||
.iconshouyeshouye:before {
|
||||
content: '\e606';
|
||||
}
|
||||
|
||||
.icondaohang:before {
|
||||
content: '\e641';
|
||||
}
|
||||
|
||||
.iconwodelianxikefu:before {
|
||||
content: '\e671';
|
||||
}
|
||||
|
||||
.iconwodexinyuan:before {
|
||||
content: '\e675';
|
||||
}
|
||||
|
||||
.iconphone:before {
|
||||
content: '\e6dd';
|
||||
}
|
||||
|
||||
.icondingdan:before {
|
||||
content: '\e645';
|
||||
}
|
||||
|
||||
.iconliwu:before {
|
||||
content: '\e61c';
|
||||
}
|
||||
|
||||
.iconyinpinyinliao:before {
|
||||
content: '\e60d';
|
||||
}
|
||||
|
||||
.iconyinpin:before {
|
||||
content: '\e70b';
|
||||
}
|
||||
|
||||
.iconwaimaixinxi:before {
|
||||
content: '\e685';
|
||||
}
|
||||
|
||||
.iconico:before {
|
||||
content: '\e646';
|
||||
}
|
||||
|
||||
.iconwode:before {
|
||||
content: '\e616';
|
||||
}
|
||||
|
||||
.icongengduofuwu:before {
|
||||
content: '\e607';
|
||||
}
|
||||
|
||||
.iconqucan:before {
|
||||
content: '\e625';
|
||||
}
|
||||
|
||||
.iconyou:before {
|
||||
content: '\e618';
|
||||
}
|
||||
|
||||
.iconshouhuodizhi:before {
|
||||
content: '\e666';
|
||||
}
|
||||
|
||||
.iconshangcheng:before {
|
||||
content: '\e63b';
|
||||
}
|
||||
|
||||
.iconadd:before {
|
||||
content: '\e742';
|
||||
}
|
||||
|
||||
.iconarrow-right:before {
|
||||
content: '\e743';
|
||||
}
|
||||
|
||||
.iconarrow-lift:before {
|
||||
content: '\e744';
|
||||
}
|
||||
|
||||
.iconarrow-up:before {
|
||||
content: '\e745';
|
||||
}
|
||||
|
||||
.iconclose:before {
|
||||
content: '\e747';
|
||||
}
|
||||
|
||||
.iconleftbutton:before {
|
||||
content: '\e755';
|
||||
}
|
||||
|
||||
.iconreduce:before {
|
||||
content: '\e75e';
|
||||
}
|
||||
|
||||
.iconseleted:before {
|
||||
content: '\e763';
|
||||
}
|
||||
|
||||
.iconRightbutton:before {
|
||||
content: '\e765';
|
||||
}
|
||||
|
||||
.iconleftbutton-fill:before {
|
||||
content: '\e782';
|
||||
}
|
||||
|
||||
.iconRightbutton-fill:before {
|
||||
content: '\e78a';
|
||||
}
|
||||
|
||||
.iconarrow-down:before {
|
||||
content: '\e7b2';
|
||||
}
|
||||
|
||||
.iconaixin1:before {
|
||||
content: '\e63c';
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4205200 */
|
||||
src: url('~@/static/iconfont/iconfont.woff2') format('woff2'),
|
||||
url('~@/static/iconfont/iconfont.woff') format('woff'),
|
||||
url('~@/static/iconfont/iconfont.ttf') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-waimai-:before {
|
||||
content: "\e607";
|
||||
}
|
||||
|
||||
.icon-tangshi:before {
|
||||
content: "\e645";
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 252 B |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 906 B |
|
After Width: | Height: | Size: 937 B |
|
After Width: | Height: | Size: 706 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 494 B |
|
After Width: | Height: | Size: 1017 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1010 B |
|
After Width: | Height: | Size: 934 B |
|
After Width: | Height: | Size: 493 B |
|
After Width: | Height: | Size: 579 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 767 B |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,435 @@
|
||||
@import '~@/uni.scss';
|
||||
|
||||
page,
|
||||
view,
|
||||
scroll-view,
|
||||
text,
|
||||
image,
|
||||
textarea,
|
||||
button,
|
||||
input {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
page {
|
||||
background-color: #F1F8FA;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 0;
|
||||
|
||||
&[type='primary'] {
|
||||
background-color: $color-primary;
|
||||
//background-color: #5A5B5C;
|
||||
color: #ffffff;
|
||||
font-size: $font-size-base;
|
||||
|
||||
&[disabled] {
|
||||
background-color: #D1D78C;
|
||||
}
|
||||
|
||||
&[plain] {
|
||||
color: $color-primary;
|
||||
border: 1rpx solid $color-primary;
|
||||
}
|
||||
&.button-hover {
|
||||
background-color: #d5da91;
|
||||
}
|
||||
&::after {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[type='default'] {
|
||||
&[plain] {
|
||||
color: $text-color-assist;
|
||||
border: 1rpx solid $text-color-assist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bg-base {
|
||||
background-color: $bg-color;
|
||||
}
|
||||
|
||||
.bg-white {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.bg-transparent {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
background-color: $color-primary;
|
||||
}
|
||||
|
||||
.bg-warning {
|
||||
background-color: $color-warning;
|
||||
}
|
||||
|
||||
.d-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.d-none {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.d-inline {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
.d-inline-block {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.d-block {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
-ms-flex-direction: column !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.justify-content-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.justify-content-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.justify-content-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.just-content-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-content-evenly {
|
||||
justify-content: space-evenly !important;
|
||||
}
|
||||
|
||||
.just-content-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.align-items-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.align-items-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.align-items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.align-items-between {
|
||||
align-items: space-between;
|
||||
}
|
||||
|
||||
.align-items-around {
|
||||
align-items: space-around;
|
||||
}
|
||||
|
||||
.align-items-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.align-items-baseline {
|
||||
-ms-flex-align: baseline !important;
|
||||
align-items: baseline !important;
|
||||
}
|
||||
|
||||
.flex-fill {
|
||||
-ms-flex: 1 1 auto !important;
|
||||
flex: 1 1 auto !important;
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
-ms-flex-wrap: wrap !important;
|
||||
flex-wrap: wrap !important;
|
||||
}
|
||||
|
||||
.flex-nowrap {
|
||||
-ms-flex-wrap: nowrap !important;
|
||||
flex-wrap: nowrap !important;
|
||||
}
|
||||
|
||||
.flex-shrink-0 {
|
||||
-ms-flex-negative: 0 !important;
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
|
||||
.font-size-base {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.font-size-sm {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.font-size-medium {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.font-size-lg {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.font-size-extra-lg {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.text-color-base {
|
||||
color: $text-color-base;
|
||||
}
|
||||
|
||||
.text-color-assist {
|
||||
color: $text-color-assist;
|
||||
}
|
||||
|
||||
.text-color-primary {
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
.text-color-danger {
|
||||
color: $color-error;
|
||||
}
|
||||
|
||||
.text-color-white {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.text-color-warning {
|
||||
color: $color-warning;
|
||||
}
|
||||
|
||||
.text-truncate {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.font-weight-bold {
|
||||
font-weight: 700 !important;
|
||||
}
|
||||
|
||||
.font-weight-light {
|
||||
font-weight: 300 !important;
|
||||
}
|
||||
|
||||
.font-weight-lighter {
|
||||
font-weight: lighter !important;
|
||||
}
|
||||
|
||||
.font-weight-normal {
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
.overflow-auto {
|
||||
overflow: auto !important;
|
||||
}
|
||||
|
||||
.overflow-hidden {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.position-relative {
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.position-absolute {
|
||||
position: absolute !important;
|
||||
}
|
||||
|
||||
.position-fixed {
|
||||
position: fixed !important;
|
||||
}
|
||||
|
||||
.fixed-top {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 1030;
|
||||
}
|
||||
|
||||
.fixed-bottom {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1030;
|
||||
}
|
||||
|
||||
.line-height-100 {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.line-height-2 {
|
||||
line-height: 2rem !important;
|
||||
}
|
||||
|
||||
.line-height-50 {
|
||||
line-height: 50rem !important;
|
||||
}
|
||||
|
||||
.w-25 {
|
||||
width: 25% !important;
|
||||
}
|
||||
|
||||
.w-50 {
|
||||
width: 50% !important;
|
||||
}
|
||||
|
||||
.w-75 {
|
||||
width: 75% !important;
|
||||
}
|
||||
|
||||
.w-80 {
|
||||
width: 80% !important;
|
||||
}
|
||||
|
||||
.w-90 {
|
||||
width: 90% !important;
|
||||
}
|
||||
|
||||
.w-100 {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.h-100 {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.border-box {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.rounded-circle {
|
||||
border-radius: 50% !important;
|
||||
}
|
||||
|
||||
.rounded-pill {
|
||||
border-radius: 50rem !important;
|
||||
}
|
||||
|
||||
.border-radius-base {
|
||||
border-radius: $border-radius-base;
|
||||
}
|
||||
|
||||
.pre-line {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.align-top {
|
||||
vertical-align: top !important;
|
||||
}
|
||||
|
||||
.align-middle {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
|
||||
.align-bottom {
|
||||
vertical-align: bottom !important;
|
||||
}
|
||||
|
||||
.align-text-bottom {
|
||||
vertical-align: text-bottom !important;
|
||||
}
|
||||
|
||||
.align-text-top {
|
||||
vertical-align: text-top !important;
|
||||
}
|
||||
|
||||
.w-60 {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.w-40 {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.mb-10 {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.mb-20 {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.mb-30 {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.mb-40 {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.mb-50 {
|
||||
margin-bottom: 50rpx;
|
||||
}
|
||||
|
||||
.mt-30 {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.ml-10 {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.ml-20 {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.ml-30 {
|
||||
margin-left: 30rpx;
|
||||
}
|
||||
|
||||
.mr-10 {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.mr-20 {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.mr-30 {
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.mr-40 {
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
|
||||
.pl-30 {
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 6.0 KiB |