i
12
.editorconfig
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# EditorConfig is awesome: https://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
insert_final_newline = false
|
||||||
15
.idea/git_toolbox_prj.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GitToolBoxProjectSettings">
|
||||||
|
<option name="commitMessageIssueKeyValidationOverride">
|
||||||
|
<BoolValueOverride>
|
||||||
|
<option name="enabled" value="true" />
|
||||||
|
</BoolValueOverride>
|
||||||
|
</option>
|
||||||
|
<option name="commitMessageValidationEnabledOverride">
|
||||||
|
<BoolValueOverride>
|
||||||
|
<option name="enabled" value="true" />
|
||||||
|
</BoolValueOverride>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
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 { createApp } from "vue";
|
||||||
import { createPinia } from 'pinia'
|
|
||||||
import "./app.scss";
|
import "./app.scss";
|
||||||
|
|
||||||
|
|
||||||
@@ -9,6 +8,4 @@ const App = createApp({
|
|||||||
// 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
|
// 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
|
||||||
});
|
});
|
||||||
|
|
||||||
App.use(createPinia())
|
|
||||||
|
|
||||||
export default App;
|
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: "服务器异常"});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||