i
10
src/api/user.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { request } from "../utils/request";
|
||||
|
||||
// 登录
|
||||
export const login = (data: object) => request("/login", data, "POST");
|
||||
|
||||
// 获取用户信息
|
||||
export const getUserInfo = () => request("/user/detail", {}, "GET");
|
||||
|
||||
// 支付订单
|
||||
export const payOrder = (data: object) => request("/order/place", data, "POST");
|
||||
@@ -1,5 +1,4 @@
|
||||
import { createApp } from "vue";
|
||||
import { createPinia } from 'pinia'
|
||||
import "./app.scss";
|
||||
|
||||
|
||||
@@ -9,6 +8,4 @@ const App = createApp({
|
||||
// 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
|
||||
});
|
||||
|
||||
App.use(createPinia())
|
||||
|
||||
export default App;
|
||||
|
||||
91
src/components/Auth.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<nut-overlay v-model:visible="visible" :close-on-click-overlay="false">
|
||||
<view class="text">
|
||||
<view>授权提醒</view>
|
||||
<view style="margin-top: 10px"
|
||||
>请授权头像信息,以便为您提供更好的服务!</view
|
||||
>
|
||||
<view class="bom">
|
||||
<view class="btn b" @click="onCancel">随便逛逛</view>
|
||||
<view class="btn a" @tap="onOk">去授权</view>
|
||||
</view>
|
||||
</view>
|
||||
</nut-overlay>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import { computed, ref } from "vue";
|
||||
import Taro from "@tarojs/taro";
|
||||
import { login } from "../api/user";
|
||||
|
||||
defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "update:info"]);
|
||||
|
||||
const onCancel = () => {
|
||||
emit("update:visible", false);
|
||||
};
|
||||
|
||||
const onOk = () => {
|
||||
Taro.getUserProfile({
|
||||
desc: "用于完善会员资料",
|
||||
success: async (user) => {
|
||||
console.log(user);
|
||||
Taro.login({
|
||||
success: async ({ code }) => {
|
||||
const { data }: any = await login({
|
||||
code: code,
|
||||
});
|
||||
Taro.setStorageSync("token", data.token);
|
||||
emit("update:visible", false);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log(err);
|
||||
},
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log(err);
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.text {
|
||||
text-align: center;
|
||||
background-color: #fff;
|
||||
width: 500px;
|
||||
padding: 20px;
|
||||
margin: auto;
|
||||
transform: translateY(150%);
|
||||
border-radius: 10px;
|
||||
|
||||
.bom {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
.btn {
|
||||
width: 150px;
|
||||
padding: 10px;
|
||||
border-radius: 15px;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.a {
|
||||
background-color: #ff5000;
|
||||
}
|
||||
|
||||
.b {
|
||||
background-color: rgba(255, 80, 0, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
124
src/components/Pay.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<nut-popup
|
||||
position="bottom"
|
||||
closeable
|
||||
round
|
||||
safe-area-inset-bottom
|
||||
:close-on-click-overlay="false"
|
||||
:style="{ height: 'auto' }"
|
||||
v-model:visible="isShowPay"
|
||||
@click-close-icon="closePay"
|
||||
>
|
||||
<view class="div">
|
||||
<view style="text-align: center">支付方式</view>
|
||||
<nut-cell-group>
|
||||
<nut-cell
|
||||
v-if="payType === 'wx'"
|
||||
title="微信支付"
|
||||
desc="使用微信快捷支付"
|
||||
is-link
|
||||
@click="goPay()"
|
||||
>
|
||||
<template v-slot:icon>
|
||||
<IconFont
|
||||
size="30"
|
||||
name="https://img11.360buyimg.com/imagetools/jfs/t1/137646/13/7132/1648/5f4c748bE43da8ddd/a3f06d51dcae7b60.png"
|
||||
/>
|
||||
</template>
|
||||
</nut-cell>
|
||||
<nut-cell
|
||||
v-if="payType === 'jf'"
|
||||
title="积分支付"
|
||||
desc="剩余积分:18888"
|
||||
is-link
|
||||
@click="goPay()"
|
||||
>
|
||||
<template v-slot:icon>
|
||||
<IconFont
|
||||
size="30"
|
||||
name="https://img11.360buyimg.com/imagetools/jfs/t1/137646/13/7132/1648/5f4c748bE43da8ddd/a3f06d51dcae7b60.png"
|
||||
/>
|
||||
</template>
|
||||
</nut-cell>
|
||||
</nut-cell-group>
|
||||
</view>
|
||||
</nut-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {IconFont} from "@nutui/icons-vue-taro";
|
||||
import Taro from "@tarojs/taro";
|
||||
import {payOrder} from "../api/user";
|
||||
|
||||
const prop = defineProps({
|
||||
isShowPay: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
payType: {
|
||||
required: true,
|
||||
type: String,
|
||||
default: "wx",
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["errPay", "closePay"]);
|
||||
|
||||
const goPay = async () => {
|
||||
if (prop.payType === "wx") {
|
||||
const {data} = await payOrder({gid: 1, token: Taro.getStorageSync("token")});
|
||||
console.log(data);
|
||||
// Taro.request({
|
||||
// url: "http://192.168.2.3:9000/app/order/place",
|
||||
// method: "POST",
|
||||
// data: {
|
||||
// gid: 1,
|
||||
// token: Taro.getStorageSync("token"),
|
||||
// },
|
||||
// success: function ({data}) {
|
||||
// console.log(data);
|
||||
// Taro.requestPayment({
|
||||
// timeStamp: data.data.data.timeStamp,
|
||||
// nonceStr: data.data.data.nonceStr,
|
||||
// package: data.data.data.package,
|
||||
// signType: "MD5",
|
||||
// paySign: data.data.data.paySign,
|
||||
// success: function (res) {
|
||||
// console.log(res);
|
||||
// },
|
||||
// fail: function (res) {
|
||||
// console.log("1111", res);
|
||||
// emit("errPay", false);
|
||||
// },
|
||||
// });
|
||||
// },
|
||||
// fail: function (res) {
|
||||
// console.log("1111", res);
|
||||
// emit("errPay", false);
|
||||
// },
|
||||
// });
|
||||
}
|
||||
};
|
||||
|
||||
const closePay = () => {
|
||||
emit("closePay", false);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.nut-popup {
|
||||
.nut-popup__container {
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.div {
|
||||
padding: 20px;
|
||||
// text-align: center;
|
||||
|
||||
.nut-cell {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
3
src/pages/admin/verify/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "订单核销",
|
||||
});
|
||||
61
src/pages/admin/verify/index.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="card">
|
||||
<nut-button block type="primary" @click="scanCode"
|
||||
>扫码核销</nut-button
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Taro from "@tarojs/taro";
|
||||
|
||||
// url参数转对象
|
||||
const urlParse = (url: string) => {
|
||||
const obj: any = {};
|
||||
const reg = /[?&][^?&]+=[^?&]+/g;
|
||||
const arr = url.match(reg);
|
||||
if (arr) {
|
||||
arr.forEach((item) => {
|
||||
const tempArr = item.substring(1).split("=");
|
||||
const key = decodeURIComponent(tempArr[0]);
|
||||
const val = decodeURIComponent(tempArr[1]);
|
||||
obj[key] = val;
|
||||
});
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
const scanCode = () => {
|
||||
Taro.scanCode({
|
||||
onlyFromCamera: true,
|
||||
scanType: ["qrCode"],
|
||||
success: (res) => {
|
||||
console.log(urlParse(res.result));
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
background-image: url("../../../static/admin/cancellation-header.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 30%;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 80%;
|
||||
height: 300px;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
margin: 300px auto;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 100px;
|
||||
}
|
||||
</style>
|
||||
4
src/pages/goods/goods_detail/index.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '商品详情',
|
||||
navigationStyle: 'custom',
|
||||
})
|
||||
293
src/pages/goods/goods_detail/index.vue
Normal file
@@ -0,0 +1,293 @@
|
||||
<template>
|
||||
<view class="app">
|
||||
<view class="head-wrapper" :style="'top:' + BarHeight + 'px'">
|
||||
<view class="head-menu">
|
||||
<Left class="iconfont" @click="returns" />
|
||||
<Home class="iconfont" @click="goHome" />
|
||||
</view>
|
||||
</view>
|
||||
<!-- 幻灯片 -->
|
||||
<nut-swiper
|
||||
:init-page="0"
|
||||
:pagination-visible="true"
|
||||
pagination-color="#426543"
|
||||
auto-play="3000"
|
||||
>
|
||||
<nut-swiper-item v-for="(itm, idx) in swiperList" :key="idx">
|
||||
<img :src="itm.url" :alt="itm.id.toString()" />
|
||||
</nut-swiper-item>
|
||||
</nut-swiper>
|
||||
<!-- 标题价格 -->
|
||||
<view class="card">
|
||||
<view>
|
||||
<nut-price
|
||||
size="large"
|
||||
:price="8888"
|
||||
position="after"
|
||||
symbol="积分"
|
||||
/>
|
||||
</view>
|
||||
<view class="title"
|
||||
>MIUCHO可爱卡通学生通勤手提电脑包13.3寸14村女适用苹果联想小米</view
|
||||
>
|
||||
</view>
|
||||
<nut-cell title="请选择规格: " is-link @click="openSku"></nut-cell>
|
||||
<!-- 产品介绍 -->
|
||||
<view class="rich-box">
|
||||
<view class="title">产品介绍</view>
|
||||
<view></view>
|
||||
<nut-empty description="暂无产品介绍"></nut-empty>
|
||||
</view>
|
||||
<!-- 底部 -->
|
||||
<view class="bottom-box">
|
||||
<view class="left">
|
||||
<view class="icon" @click="toPage('/pages/index/index')">
|
||||
<Home />
|
||||
<view>首页</view>
|
||||
</view>
|
||||
<view class="icon" @click="toPage('/pages/cart/index')">
|
||||
<Cart />
|
||||
<view>购物车</view>
|
||||
</view>
|
||||
<view class="icon" @click="toPage('/pages/kefu/index', 2)">
|
||||
<My />
|
||||
<view>客服</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 占位 -->
|
||||
<view style="height: 155px"></view>
|
||||
<view>
|
||||
<nut-button
|
||||
style="margin-right: 10px"
|
||||
type="warning"
|
||||
@click="addCart()"
|
||||
>加入购物车</nut-button
|
||||
>
|
||||
<nut-button type="primary" @click="toOrderDetail()"
|
||||
>立即兑换</nut-button
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 规格选择 -->
|
||||
<nut-popup
|
||||
position="bottom"
|
||||
overlay-class="overlay"
|
||||
safe-area-inset-bottom
|
||||
closeable
|
||||
round
|
||||
:style="{ height: '45%', zIndex: 1 }"
|
||||
v-model:visible="isSkuShow"
|
||||
></nut-popup>
|
||||
<!-- <nut-sku
|
||||
v-model:visible="isSkuShow"
|
||||
:sku="sku"
|
||||
:goods="goods"
|
||||
@selectSku="selectSku"
|
||||
@clickBtnOperate="clickBtnOperate"
|
||||
@close="close"
|
||||
></nut-sku> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
var statusBarHeight = Taro.getSystemInfoSync().statusBarHeight;
|
||||
import { ref } from "vue";
|
||||
import Taro from "@tarojs/taro";
|
||||
import { Left, Home, Cart, My } from "@nutui/icons-vue-taro";
|
||||
|
||||
|
||||
const BarHeight = ref((statusBarHeight as number) + 7);
|
||||
|
||||
const swiperList = ref([
|
||||
{
|
||||
id: 1,
|
||||
url: "https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
url: "https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
url: "https://storage.360buyimg.com/jdc-article/welcomenutui.jpg",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
url: "https://storage.360buyimg.com/jdc-article/fristfabu.jpg",
|
||||
},
|
||||
]);
|
||||
|
||||
const isSkuShow = ref(false);
|
||||
|
||||
const sku = ref([]);
|
||||
|
||||
const goods = ref({});
|
||||
|
||||
const returns = () => {
|
||||
Taro.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
};
|
||||
|
||||
const goHome = () => {
|
||||
Taro.switchTab({
|
||||
url: "/pages/index/index",
|
||||
});
|
||||
};
|
||||
|
||||
const openSku = () => {
|
||||
isSkuShow.value = true;
|
||||
};
|
||||
|
||||
const selectSku = () => {};
|
||||
const clickBtnOperate = () => {};
|
||||
const close = () => {};
|
||||
|
||||
const addCart = () => {
|
||||
if (isSkuShow.value === false) return openSku();
|
||||
Taro.showToast({
|
||||
title: "加入购物车成功",
|
||||
icon: "none",
|
||||
});
|
||||
isSkuShow.value = false;
|
||||
};
|
||||
|
||||
const toOrderDetail = () => {
|
||||
if (isSkuShow.value === false) return openSku();
|
||||
Taro.navigateTo({
|
||||
url: "/pages/goods/order_create/index",
|
||||
});
|
||||
isSkuShow.value = false;
|
||||
};
|
||||
|
||||
const toPage = (url: string, type: number = 1) => {
|
||||
if (type === 1) {
|
||||
Taro.switchTab({
|
||||
url: url,
|
||||
});
|
||||
} else {
|
||||
// Taro.navigateTo({
|
||||
// url: url,
|
||||
// });
|
||||
Taro.showToast({
|
||||
title: "暂未开放",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
// sku遮罩
|
||||
.overlay {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1 !important;
|
||||
}
|
||||
.head-wrapper {
|
||||
z-index: 999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
left: 30rpx;
|
||||
top: 0;
|
||||
/* #ifdef MP */
|
||||
// height: 43px;
|
||||
/* #endif */
|
||||
/* #ifdef H5 */
|
||||
height: 114rpx;
|
||||
/* #endif */
|
||||
}
|
||||
.head-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 54rpx;
|
||||
width: 140rpx;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border-radius: 27rpx;
|
||||
.iconfont {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-swiper-item img {
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 30px;
|
||||
background-color: #fff;
|
||||
|
||||
.title {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.rich-box {
|
||||
background-color: #fff;
|
||||
margin-top: 20px;
|
||||
width: 100vw;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
padding: 15px 0;
|
||||
.title {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-sku {
|
||||
// 适配ios底部安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.bottom-box {
|
||||
border-top: 1px solid #e5e5e585;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
height: 5.5vh;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
// 适配ios底部安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
z-index: 999;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 300px;
|
||||
padding: 0 20px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #333;
|
||||
font-size: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #333;
|
||||
font-size: 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
3
src/pages/goods/order_create/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "提交订单"
|
||||
});
|
||||
183
src/pages/goods/order_create/index.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<view class="app">
|
||||
<view class="bg">
|
||||
<view class="card">
|
||||
<view class="left">
|
||||
<view>嘎嘎酒吧</view>
|
||||
<view>18888888888</view>
|
||||
<view>广西壮族自治区南宁市江南区</view>
|
||||
</view>
|
||||
<view class="right" @click="toLocal">
|
||||
<Find class="icon" />
|
||||
<view class="text">距离我{{ distance }}km</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="order-info">21312312</view>
|
||||
<nut-form>
|
||||
<nut-form-item body-align="right" label="用户姓名">
|
||||
<nut-input
|
||||
:border="false"
|
||||
v-model="basicData.name"
|
||||
placeholder="请输入姓名"
|
||||
type="text"
|
||||
/>
|
||||
</nut-form-item>
|
||||
<nut-form-item body-align="right" label="联系电话">
|
||||
<nut-input
|
||||
:border="false"
|
||||
v-model="basicData.phone"
|
||||
placeholder="请输入联系电话"
|
||||
type="text"
|
||||
/>
|
||||
</nut-form-item>
|
||||
<nut-form-item body-align="right" label="订单备注">
|
||||
<nut-textarea
|
||||
class="nut-input-text"
|
||||
v-model="basicData.notes"
|
||||
placeholder="请输入备注"
|
||||
type="text"
|
||||
/>
|
||||
</nut-form-item>
|
||||
</nut-form>
|
||||
<!-- 底部 -->
|
||||
<view class="bottom-box">
|
||||
<view
|
||||
>总计:<nut-price
|
||||
:price="8888.01"
|
||||
position="after"
|
||||
symbol="积分"
|
||||
/></view>
|
||||
<nut-button type="primary" @click="orderPay">提交订单</nut-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Find } from "@nutui/icons-vue-taro";
|
||||
import Taro from "@tarojs/taro";
|
||||
import { calculateDistance } from "../../../utils";
|
||||
import { ref } from "vue";
|
||||
|
||||
const distance = ref("");
|
||||
|
||||
const basicData = ref({
|
||||
name: "",
|
||||
phone: "",
|
||||
notes: "",
|
||||
});
|
||||
|
||||
Taro.useLoad(() => {
|
||||
Taro.getLocation({
|
||||
type: "wgs84",
|
||||
success: function (res) {
|
||||
const latitude = res.latitude;
|
||||
const longitude = res.longitude;
|
||||
distance.value = calculateDistance(
|
||||
108.24898,
|
||||
22.83646,
|
||||
longitude,
|
||||
latitude
|
||||
);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
const toLocal = () => {
|
||||
Taro.openLocation({
|
||||
latitude: 22.83646,
|
||||
longitude: 108.24898,
|
||||
scale: 18,
|
||||
});
|
||||
};
|
||||
|
||||
const orderPay = () => {
|
||||
Taro.showToast({
|
||||
title: "支付成功",
|
||||
icon: "success",
|
||||
success: () => {
|
||||
setTimeout(() => {
|
||||
Taro.redirectTo({
|
||||
url: "/pages/goods/order_status/index",
|
||||
});
|
||||
}, 2000);
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.bg {
|
||||
background: linear-gradient(0deg, #f5f5f5, #0396ffc7);
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
padding: 10px 0;
|
||||
|
||||
.card {
|
||||
width: 90%;
|
||||
height: 75%;
|
||||
margin: 0 auto;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
margin-top: 20px;
|
||||
position: relative;
|
||||
border-bottom: 1px dashed #ccc;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
|
||||
.left {
|
||||
width: 70%;
|
||||
color: #333;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 30%;
|
||||
text-align: center;
|
||||
|
||||
.icon {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 25px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order-info {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.nut-input-text {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.bottom-box {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
height: 9vh;
|
||||
background: #fff;
|
||||
// IOS安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
}
|
||||
</style>
|
||||
3
src/pages/goods/order_status/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "订单状态",
|
||||
});
|
||||
97
src/pages/goods/order_status/index.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="card">
|
||||
<view class="icon">
|
||||
<Check
|
||||
font-class-name="nutui-iconfont check"
|
||||
size="70"
|
||||
color="#fff"
|
||||
/>
|
||||
<!-- <CloseLittle font-class-name="nutui-iconfont check" size="70" color="#fff" /> -->
|
||||
</view>
|
||||
<view class="text-box">
|
||||
<view class="title">支付成功</view>
|
||||
<nut-button block type="primary" @click="toOrderPage"
|
||||
>查看订单</nut-button
|
||||
>
|
||||
<nut-button
|
||||
block
|
||||
plain
|
||||
style="margin-top: 10px"
|
||||
type="primary"
|
||||
@click="toHome"
|
||||
>返回首页</nut-button
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Check, CloseLittle } from "@nutui/icons-vue-taro";
|
||||
import Taro from "@tarojs/taro";
|
||||
|
||||
const toHome = () => {
|
||||
Taro.switchTab({
|
||||
url: "/pages/index/index",
|
||||
});
|
||||
};
|
||||
|
||||
const toOrderPage = () => {
|
||||
Taro.redirectTo({
|
||||
url: "/pages/users/order_list/index?type=0",
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.card {
|
||||
width: 90%;
|
||||
height: 600px;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
margin: 200px auto;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
flex-direction: column;
|
||||
|
||||
.icon {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: red;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: -100px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border: #f5f5f5 10px solid;
|
||||
text-align: center;
|
||||
|
||||
.check {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.text-box {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0 100px;
|
||||
|
||||
.title {
|
||||
font-size: 60px;
|
||||
color: #333;
|
||||
margin: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
3
src/pages/users/order_list_detail/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '订单详情'
|
||||
})
|
||||
7
src/pages/users/order_list_detail/index.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<view>这里是订单详情</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style lang="scss"></style>
|
||||
BIN
src/pages/users/static/user/order_list_top.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
src/static/admin/cancellation-header.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
src/static/index/index-title.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/static/merchantBg.jpg
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
src/static/tabbar/1-001.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/static/tabbar/1-002.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/static/tabbar/2-001.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/static/tabbar/2-002.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
src/static/tabbar/3-001.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/static/tabbar/3-002.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
src/static/tabbar/4-001.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/static/tabbar/4-002.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
29
src/utils/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
// 经纬度计算距离
|
||||
export function calculateDistance(
|
||||
lat1: number,
|
||||
lon1: number,
|
||||
lat2: number,
|
||||
lon2: number
|
||||
): string {
|
||||
const R = 6371; // 地球平均半径(单位:千米)
|
||||
|
||||
const dLat = toRadians(lat2 - lat1);
|
||||
const dLon = toRadians(lon2 - lon1);
|
||||
|
||||
const a =
|
||||
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
||||
Math.cos(toRadians(lat1)) *
|
||||
Math.cos(toRadians(lat2)) *
|
||||
Math.sin(dLon / 2) *
|
||||
Math.sin(dLon / 2);
|
||||
|
||||
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
|
||||
const distance = R * c;
|
||||
return distance.toFixed(2);
|
||||
}
|
||||
|
||||
// 将角度转换为弧度
|
||||
function toRadians(degrees: number): number {
|
||||
return (degrees * Math.PI) / 180;
|
||||
}
|
||||
46
src/utils/request.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import Taro from "@tarojs/taro";
|
||||
|
||||
const BASE_URL = () => {
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
return "http://192.168.2.3:9000";
|
||||
} else {
|
||||
return "https://api.imooc.hybrid.lgdsunday.club";
|
||||
}
|
||||
};
|
||||
|
||||
// interface Res {
|
||||
//
|
||||
// }
|
||||
|
||||
type Method = "GET" | "POST" | "PUT" | "DELETE";
|
||||
|
||||
export const request = (
|
||||
url: string,
|
||||
data: object = {},
|
||||
method: Method = "GET"
|
||||
): Promise<any> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.request({
|
||||
url: BASE_URL() + "/app" + url,
|
||||
data: data,
|
||||
method: method,
|
||||
header: {
|
||||
"content-type": "application/json",
|
||||
token: Taro.getStorageSync("token"),
|
||||
},
|
||||
success: ({data}) => {
|
||||
console.log(data);
|
||||
if (data.code !== 200)
|
||||
return reject({code: 1, msg: data.msg});
|
||||
resolve(data);
|
||||
},
|
||||
fail: () => {
|
||||
Taro.showToast({
|
||||
title: "服务器异常",
|
||||
icon: "none",
|
||||
});
|
||||
reject({code: 1, msg: "服务器异常"});
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||