This commit is contained in:
2023-09-06 03:49:21 +08:00
parent 8b5de95140
commit b6ca53f70e
39 changed files with 2146 additions and 679 deletions

3
components.d.ts vendored
View File

@@ -23,6 +23,7 @@ declare module '@vue/runtime-core' {
NutInput: typeof import('@nutui/nutui-taro')['Input'] NutInput: typeof import('@nutui/nutui-taro')['Input']
NutInputNumber: typeof import('@nutui/nutui-taro')['InputNumber'] NutInputNumber: typeof import('@nutui/nutui-taro')['InputNumber']
NutOverlay: typeof import('@nutui/nutui-taro')['Overlay'] NutOverlay: typeof import('@nutui/nutui-taro')['Overlay']
NutPagination: typeof import('@nutui/nutui-taro')['Pagination']
NutPicker: typeof import('@nutui/nutui-taro')['Picker'] NutPicker: typeof import('@nutui/nutui-taro')['Picker']
NutPopup: typeof import('@nutui/nutui-taro')['Popup'] NutPopup: typeof import('@nutui/nutui-taro')['Popup']
NutPrice: typeof import('@nutui/nutui-taro')['Price'] NutPrice: typeof import('@nutui/nutui-taro')['Price']
@@ -33,6 +34,8 @@ declare module '@vue/runtime-core' {
NutTabPane: typeof import('@nutui/nutui-taro')['TabPane'] NutTabPane: typeof import('@nutui/nutui-taro')['TabPane']
NutTabs: typeof import('@nutui/nutui-taro')['Tabs'] NutTabs: typeof import('@nutui/nutui-taro')['Tabs']
NutTextarea: typeof import('@nutui/nutui-taro')['Textarea'] NutTextarea: typeof import('@nutui/nutui-taro')['Textarea']
NutUploader: typeof import('@nutui/nutui-taro')['Uploader']
Pay: typeof import('./src/components/Pay.vue')['default'] Pay: typeof import('./src/components/Pay.vue')['default']
Upload: typeof import('./src/components/Upload.vue')['default']
} }
} }

View File

@@ -52,6 +52,7 @@
"@tarojs/runtime": "3.6.11", "@tarojs/runtime": "3.6.11",
"@tarojs/shared": "3.6.11", "@tarojs/shared": "3.6.11",
"@tarojs/taro": "3.6.11", "@tarojs/taro": "3.6.11",
"dayjs": "^1.11.9",
"pinia": "^2.1.6", "pinia": "^2.1.6",
"vue": "^3.2.40" "vue": "^3.2.40"
}, },

14
pnpm-lock.yaml generated
View File

@@ -56,12 +56,12 @@ dependencies:
'@tarojs/taro': '@tarojs/taro':
specifier: 3.6.11 specifier: 3.6.11
version: 3.6.11(postcss@8.4.27)(vue@3.2.40) version: 3.6.11(postcss@8.4.27)(vue@3.2.40)
dayjs:
specifier: ^1.11.9
version: 1.11.9
pinia: pinia:
specifier: ^2.1.6 specifier: ^2.1.6
version: 2.1.6(typescript@4.1.2)(vue@3.2.40) version: 2.1.6(typescript@4.1.2)(vue@3.2.40)
uqrcodejs:
specifier: ^4.0.7
version: 4.0.7
vue: vue:
specifier: ^3.2.40 specifier: ^3.2.40
version: 3.2.40 version: 3.2.40
@@ -6423,6 +6423,10 @@ packages:
whatwg-url: 12.0.1 whatwg-url: 12.0.1
dev: true dev: true
/dayjs@1.11.9:
resolution: {integrity: sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==}
dev: false
/debug@2.6.9: /debug@2.6.9:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
peerDependencies: peerDependencies:
@@ -13809,10 +13813,6 @@ packages:
tslib: 2.6.1 tslib: 2.6.1
dev: false dev: false
/uqrcodejs@4.0.7:
resolution: {integrity: sha512-84+aZmD2godCVI+93lxE3YUAPNY8zAJvNA7xRS7R7U+q57KzMDepBSfNCwoRUhWOfR6eHFoAOcHRPwsP6ka1cA==}
dev: false
/uri-js@4.4.1: /uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
dependencies: dependencies:

View File

@@ -26,3 +26,17 @@ export const getActiveGoodsDetail = (data: object) => request('/goods/details',
// 活动商品下单 // 活动商品下单
export const createActiveOrder = (data: object) => request('/order/place', data, 'POST') export const createActiveOrder = (data: object) => request('/order/place', data, 'POST')
// 活动订单列表
export const getActiveOrderList = (data: object) => request('/user/order', data, 'POST')
// 获取分类列表
export const getCategoryList = () => request('/goods/class', {}, 'POST')
// 活动订单删除
export const deleteActiveOrder = (data: object) => request('/user/order/remove', data, 'POST')
// 积分订单删除
export const deleteJfOrder = (data: object) => request('/user/point/remove', data, 'POST')

View File

@@ -2,3 +2,7 @@ import request from '@/utils/request'
// 订单支付 // 订单支付
export const payOrder = (data: object) => request('/order/confirmOrder', data, 'POST') export const payOrder = (data: object) => request('/order/confirmOrder', data, 'POST')
// 获取订单统计
export const getOrderStatistics = (data: object) => request('/user/order/count', data, 'POST')

View File

@@ -4,13 +4,15 @@ import request from "@/utils/request";
export const login = (data: object) => request("/login", data, "POST"); export const login = (data: object) => request("/login", data, "POST");
// 获取用户信息 // 获取用户信息
export const getUserInfo = () => request("/user/detail", {}, "GET"); // export const getUserInfo = () => request("/user/detail", {}, "GET");
// 获取短信验证码 // 获取短信验证码
export const getVerifyCode = (data: object) => request("/getSmsCode", data, "POST"); export const getVerifyCode = (data: object) =>
request("/getSmsCode", data, "POST");
// 商家入驻申请 // 商家入驻申请
export const applyMer = (data: object) => request("/store/settle", data, "POST"); export const applyMer = (data: object) =>
request("/store/settle", data, "POST");
// 获取商家类型列表 // 获取商家类型列表
export const getMerTypeList = () => request("/store/getOther", {}, "POST"); export const getMerTypeList = () => request("/store/getOther", {}, "POST");
@@ -22,4 +24,32 @@ export const getPersonalInfo = () => request("/user/info", {}, "POST");
export const getBanner = () => request("/rotation", {}, "POST"); export const getBanner = () => request("/rotation", {}, "POST");
// 获取积分订单列表 // 获取积分订单列表
export const getIntegralOrderList = (data: object) => request("/user/pointOrder", data, "POST"); export const getIntegralOrderList = (data: object) =>
request("/user/pointOrder", data, "POST");
// 修改个人信息
export const editPersonalInfo = (data: object) =>
request("/user/editInfo", data, "POST");
// 积分明细
export const getIntegralDetail = (data: object) =>
request("/user/pulseRecord", data, "POST");
// 豆子明细
export const getBeanDetail = (data: object) =>
request("/user/pointRecord", data, "POST");
// 授权手机号
export const getPhone = (data: object) =>
request("/user/getPhone", data, "POST");
// 获取推广积分明细
export const getTGIntegralDetail = (data: object) =>
request("/user/referee/point", data, "POST");
// 获取推广用户列表
export const getTGUserList = (data: object) =>
request("/user/referee/list", data, "POST");
// 绑定上级
export const bindParent = (data: object) => request("/user/bindCode", data, "POST");

View File

@@ -15,6 +15,9 @@ export default defineAppConfig({
"settled_mer/index", "settled_mer/index",
"order_list_detail/index", "order_list_detail/index",
"account/index", "account/index",
"distribution/index",
"distribution/integral/index",
"distribution/userlist/index",
], ],
}, },
{ {
@@ -35,7 +38,7 @@ export default defineAppConfig({
}, },
{ {
root: "pages/hotGoods", root: "pages/hotGoods",
pages: ["index/index"], pages: ["index/index", "hot_list/index"],
}, },
], ],
window: { window: {
@@ -56,18 +59,18 @@ export default defineAppConfig({
selectedIconPath: "static/tabbar/1-002.png", selectedIconPath: "static/tabbar/1-002.png",
text: "首页", text: "首页",
}, },
{ // {
pagePath: "pages/category/index", // pagePath: "pages/category/index",
iconPath: "static/tabbar/2-001.png", // iconPath: "static/tabbar/2-001.png",
selectedIconPath: "static/tabbar/2-002.png", // selectedIconPath: "static/tabbar/2-002.png",
text: "分类", // text: "分类",
}, // },
{ // {
pagePath: "pages/cart/index", // pagePath: "pages/cart/index",
iconPath: "static/tabbar/3-001.png", // iconPath: "static/tabbar/3-001.png",
selectedIconPath: "static/tabbar/3-002.png", // selectedIconPath: "static/tabbar/3-002.png",
text: "购物车", // text: "购物车",
}, // },
{ {
pagePath: "pages/user/index", pagePath: "pages/user/index",
iconPath: "static/tabbar/4-001.png", iconPath: "static/tabbar/4-001.png",
@@ -84,4 +87,5 @@ export default defineAppConfig({
requiredBackgroundModes: ["audio", "location"], requiredBackgroundModes: ["audio", "location"],
// @ts-ignore // @ts-ignore
requiredPrivateInfos: ["getLocation"], requiredPrivateInfos: ["getLocation"],
lazyCodeLoading: "requiredComponents",
}); });

View File

@@ -29,7 +29,7 @@
<nut-cell <nut-cell
v-if="payType === 'jf'" v-if="payType === 'jf'"
title="积分支付" title="积分支付"
desc="剩余积分:18888" :desc="`剩余积分:${info.integral || 0}`"
is-link is-link
@click="goPay()" @click="goPay()"
> >
@@ -46,10 +46,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from "vue";
import { IconFont } from "@nutui/icons-vue-taro"; import { IconFont } from "@nutui/icons-vue-taro";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import { payOrder } from "@/api/order"; import { payOrder } from "@/api/order";
import { payJfOrder } from "@/api/goods"; import { payJfOrder } from "@/api/goods";
import { getPersonalInfo } from "@/api/user";
const prop = defineProps({ const prop = defineProps({
isShowPay: { isShowPay: {
@@ -70,7 +72,28 @@ const prop = defineProps({
}, },
}); });
const emit = defineEmits(["closePay"]); const emit = defineEmits(["closePay", "successPay"]);
const info = ref<any>({});
watch(
() => prop.isShowPay,
() => {
getInfo();
}
);
const getInfo = async () => {
try {
const res = await getPersonalInfo();
info.value = res.data.data;
} catch (error) {
Taro.showToast({
title: error.msg,
icon: "none",
});
}
};
const goPay = async () => { const goPay = async () => {
if (!prop.jfInfo) if (!prop.jfInfo)
@@ -80,7 +103,6 @@ const goPay = async () => {
}); });
if (prop.payType === "wx") { if (prop.payType === "wx") {
try { try {
console.log(prop.jfInfo);
const { data } = await payOrder({ const { data } = await payOrder({
oid: prop.jfInfo.oid, oid: prop.jfInfo.oid,
}); });
@@ -90,16 +112,17 @@ const goPay = async () => {
package: data.data.package, package: data.data.package,
signType: data.data.signType, signType: data.data.signType,
paySign: data.data.paySign, paySign: data.data.paySign,
success: function (res) { success: function () {
console.log(res);
Taro.showToast({ Taro.showToast({
title: "支付成功", title: "支付成功",
icon: "success", icon: "success",
duration: 2000, duration: 2000,
}); });
Taro.navigateTo({
url: "/pages/hotGoods/hot_list/index",
});
}, },
fail: function (res) { fail: function () {
console.log(res);
Taro.showToast({ Taro.showToast({
title: "支付失败", title: "支付失败",
icon: "none", icon: "none",
@@ -107,6 +130,7 @@ const goPay = async () => {
}); });
}, },
}); });
emit("closePay", false);
} catch (e) { } catch (e) {
Taro.showToast({ Taro.showToast({
title: e.msg, title: e.msg,
@@ -120,8 +144,11 @@ const goPay = async () => {
icon: "success", icon: "success",
duration: 2000, duration: 2000,
}); });
} Taro.navigateTo({
url: "/pages/users/order_list/index",
});
emit("closePay", false); emit("closePay", false);
}
}; };
const closePay = () => { const closePay = () => {

62
src/components/Upload.vue Normal file
View File

@@ -0,0 +1,62 @@
<template>
<view>
<nut-uploader
v-model:file-list="fileList"
:url="config.url"
:maximum="max"
:headers="config.headers"
@success="success"
@failure="failure"
:multiple="false"
></nut-uploader>
</view>
</template>
<script setup lang="ts">
import { BASE_URL } from "@/utils/request";
import { computed, ref } from "vue";
import Taro from "@tarojs/taro";
const props = defineProps({
list: {
type: Array,
default: () => [],
},
max: {
type: Number,
default: 1,
},
});
const emits = defineEmits(["update:list"]);
const fileList = computed({
get: () => props.list,
set: (val) => emits("update:list", val),
});
const config = ref({
url: `${BASE_URL}/upload`,
headers: {
token: Taro.getStorageSync("token"),
},
});
const success = (res: any) => {
const data = JSON.parse(res.responseText.data);
res.fileItem.url = data.data.data;
Taro.showToast({
title: "上传成功",
icon: "success",
});
};
const failure = () => {
Taro.showToast({
title: "上传失败",
icon: "error",
});
};
</script>
<style lang="scss"></style>

View File

@@ -34,9 +34,9 @@ const scanCode = () => {
scanType: ["qrCode"], scanType: ["qrCode"],
success: async (res) => { success: async (res) => {
try { try {
const user = JSON.parse(Taro.getStorageSync("userInfo")); const mer_type = JSON.parse(Taro.getStorageSync("mer_type"));
let data; let data;
if (user.mer_type === 1) { if (mer_type === 1) {
data = await activeOrderVerify({ data = await activeOrderVerify({
oid: res.result, oid: res.result,
}); });
@@ -44,6 +44,7 @@ const scanCode = () => {
data = await orderVerify({ data = await orderVerify({
oid: res.result, oid: res.result,
}); });
} }
Taro.showToast({ Taro.showToast({
title: data.msg, title: data.msg,

View File

@@ -1,39 +1,43 @@
<template> <template>
<nut-tabs style="height:100vh" v-model="val" title-scroll name="tab4value" direction="vertical"> <nut-tabs
<nut-tab-pane v-for="item in list" :title="(item.name as string)"> Tab {{ item.name }}</nut-tab-pane> style="height: 100vh"
v-model="val"
title-scroll
name="tab4value"
direction="vertical"
>
<nut-tab-pane v-for="item in list" :title="(item.name as string)">
Tab {{ item.name }}</nut-tab-pane
>
</nut-tabs> </nut-tabs>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import Taro from '@tarojs/taro' import Taro from "@tarojs/taro";
import {ref} from 'vue' import { ref } from "vue";
import {getMerTypeList} from '@/api/user' import { getCategoryList } from "@/api/goods";
const val = ref('0') const val = ref("0");
interface List { interface List {
ID?: number ID?: number;
name?: string name?: string;
} }
const list = ref<Array<List>>([]) const list = ref<Array<List>>([]);
Taro.useLoad(() => { Taro.useLoad(() => {
getGoodsType() getGoodsType();
console.log('load') console.log("load");
}) });
Taro.useDidShow(() => { Taro.useDidShow(() => {});
})
// 获取商品分类 // 获取商品分类
const getGoodsType = async () => { const getGoodsType = async () => {
const res = await getMerTypeList() const res = await getCategoryList();
list.value = res.data.class list.value = res.data.data;
} };
</script> </script>
<style lang="scss"> <style lang="scss"></style>
</style>

View File

@@ -1,6 +1,11 @@
<template> <template>
<view> <view>
<view class="head-wrapper" :style="'top:' + statusHeight + 'px'"> <view
class="head-wrapper"
:style="{
top: statusHeight + 'px',
}"
>
<view class="head-menu"> <view class="head-menu">
<Left class="iconfont" @click="returns" /> <Left class="iconfont" @click="returns" />
<Home class="iconfont" @click="goHome" /> <Home class="iconfont" @click="goHome" />
@@ -57,13 +62,13 @@ import {
navigateTo, navigateTo,
} from "@tarojs/taro"; } from "@tarojs/taro";
import { Left, Home } from "@nutui/icons-vue-taro"; import { Left, Home } from "@nutui/icons-vue-taro";
var statusBarHeight = (getSystemInfoSync().statusBarHeight as number); var statusBarHeight = getSystemInfoSync().statusBarHeight as number;
console.log(statusBarHeight); console.log(statusBarHeight);
const statusHeight = ref<number>(statusBarHeight); const statusHeight = ref<number>(statusBarHeight);
const swiperList = ref([]); // const swiperList = ref([]);
useLoad((options) => { useLoad((options) => {
console.log(options); console.log(options);
@@ -81,7 +86,7 @@ const goHome = () => {
const toGame = () => { const toGame = () => {
navigateTo({ navigateTo({
url: "/pages/game/gamehome/index", url: "/pages/game/gameview/index",
}); });
}; };
</script> </script>

View File

@@ -1,43 +1,40 @@
<template> <template>
<view> <view>
<view <web-view :src="url"></web-view>
v-for="item in listVal"
:key="item.id"
class="list-box"
:class="{ listBoxAnim: item.status }"
@click="toDetails(item.id)"
>
<view>摇骰子</view>
</view>
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref } from "vue";
import { useLoad, navigateTo } from "@tarojs/taro"; import { useLoad } from "@tarojs/taro";
const listVal = ref<any>([]); // const listVal = ref<any>([]);
useLoad(() => { const url = ref("");
getList();
useLoad((options) => {
console.log(options);
// getList();
url.value = `https://www.jdt168.com/public/#/pages/index/index?uid=${options.uid}`;
console.log(url.value);
}); });
const getList = () => { // const getList = () => {
for (let i = 0; i < 1; i++) { // for (let i = 0; i < 1; i++) {
setTimeout(() => { // setTimeout(() => {
listVal.value.push({ // listVal.value.push({
id: i, // id: i,
status: true, // status: true,
}); // });
}, 50 * i); // }, 50 * i);
} // }
}; // };
const toDetails = (id: string) => { // const toDetails = (id: string) => {
navigateTo({ // navigateTo({
url: "/pages/game/gamedetail/index?id=" + id, // url: "/pages/game/gamedetail/index?id=" + id,
}); // });
}; // };
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@@ -0,0 +1,3 @@
export default definePageConfig({
navigationBarTitleText: "GameView",
});

View File

@@ -1,13 +1,22 @@
<template> <template>
<view> <web-view
style="height: 100vh; width: 100vw"
</view> :src="`https://www.jdt168.com/public/?uid=${user.uid}`"
></web-view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue";
import { getStorageSync, useLoad } from "@tarojs/taro";
import { WebView } from "@tarojs/components";
const gameUrl = ref("");
const user = getStorageSync("userInfo");
useLoad(() => {
console.log(user);
});
</script> </script>
<style lang="scss"> <style lang="scss"></style>
</style>

View File

@@ -1,6 +1,6 @@
<template> <template>
<view class="app"> <view class="app">
<view class="head-wrapper" :style="`top:${BarHeight}px`"> <view class="head-wrapper" :style="{ top: BarHeight + 'px' }">
<view class="head-menu"> <view class="head-menu">
<Left class="iconfont" @click="returns" /> <Left class="iconfont" @click="returns" />
<Home class="iconfont" @click="goHome" /> <Home class="iconfont" @click="goHome" />
@@ -14,7 +14,7 @@
auto-play="3000" auto-play="3000"
> >
<nut-swiper-item v-for="(itm, idx) in swiperList" :key="idx"> <nut-swiper-item v-for="(itm, idx) in swiperList" :key="idx">
<img :src="itm.url" :alt="itm.id.toString()" /> <img :src="itm" :alt="idx.toString()" />
</nut-swiper-item> </nut-swiper-item>
</nut-swiper> </nut-swiper>
<!-- 标题价格 --> <!-- 标题价格 -->
@@ -28,14 +28,21 @@
/> />
</view> </view>
<view class="title">{{ goodInfo.name }} </view> <view class="title">{{ goodInfo.name }} </view>
<view class="sub">{{ goodInfo.profile }} </view>
</view> </view>
<nut-cell title="请选择规格: " is-link @click="openSku"></nut-cell> <nut-cell title="请选择规格: " is-link @click="openSku"></nut-cell>
<!-- 产品介绍 --> <!-- 产品介绍 -->
<view class="rich-box"> <view class="rich-box">
<view class="title">产品介绍</view> <view class="title">产品介绍</view>
<view v-if="goodInfo.details" v-html="goodInfo.details"></view> <rich-text
v-if="goodInfo.details"
class="rich"
:nodes="goodInfo.details"
></rich-text>
<nut-empty v-else description="暂无产品介绍"></nut-empty> <nut-empty v-else description="暂无产品介绍"></nut-empty>
</view> </view>
<view style="height: 9vh"></view>
<!-- 底部 --> <!-- 底部 -->
<view class="bottom-box"> <view class="bottom-box">
<view class="left"> <view class="left">
@@ -43,7 +50,11 @@
<Home /> <Home />
<view>首页</view> <view>首页</view>
</view> </view>
<view class="icon" v-if="payType === 'jf'" @click="toPage('/pages/cart/index')"> <view
class="icon"
v-if="payType === 'jf'"
@click="toPage('/pages/cart/index')"
>
<Cart /> <Cart />
<view>购物车</view> <view>购物车</view>
</view> </view>
@@ -53,7 +64,7 @@
</view> </view>
</view> </view>
<!-- 占位 --> <!-- 占位 -->
<view style="height: 155px"></view>
<view> <view>
<nut-button <nut-button
v-if="payType === 'jf'" v-if="payType === 'jf'"
@@ -62,7 +73,10 @@
@click="add_cart()" @click="add_cart()"
>加入购物车 >加入购物车
</nut-button> </nut-button>
<nut-button :style="payType === 'wx' ? 'width: 200px':''" type="primary" @click="toOrderDetail()" <nut-button
:style="payType === 'wx' ? 'width: 200px' : ''"
type="primary"
@click="toOrderDetail()"
>{{ payType === "jf" ? "立即兑换" : "立即购买" }} >{{ payType === "jf" ? "立即兑换" : "立即购买" }}
</nut-button> </nut-button>
</view> </view>
@@ -118,37 +132,19 @@ import {
getActiveGoodsDetail, getActiveGoodsDetail,
addCart, addCart,
createOrder, createOrder,
payOrder,
createActiveOrder, createActiveOrder,
} from "@/api/goods"; } from "@/api/goods";
import Pay from "@/components/Pay.vue"; import Pay from "@/components/Pay.vue";
const BarHeight = ref((statusBarHeight as number) + 7); const BarHeight = ref((statusBarHeight as number) + 7);
const swiperList = ref([ 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 isSkuShow = ref(false);
const isShowPay = ref(false); const isShowPay = ref(false);
const sku = ref([]); // const sku = ref([]);
const payType = ref(""); const payType = ref("");
@@ -164,6 +160,7 @@ interface GoodInfo {
details?: string; details?: string;
sku?: any[]; sku?: any[];
stock?: number; stock?: number;
profile?: string;
} }
const goodInfo = ref<GoodInfo>({}); const goodInfo = ref<GoodInfo>({});
@@ -177,11 +174,15 @@ const get_good_detail = async (gid: string) => {
try { try {
let res: any; let res: any;
if (payType.value === "jf") { if (payType.value === "jf") {
res = await getGoodsDetail({ gid: Number(gid) }); res = await getGoodsDetail({ gid: gid });
} else { } else {
res = await getActiveGoodsDetail({ gid: gid }); res = await getActiveGoodsDetail({ gid: gid });
} }
goodInfo.value = res.data.data; goodInfo.value = res.data.data;
swiperList.value = res.data.data.rotation.split(",");
console.log(goodInfo.value);
} catch (e) { } catch (e) {
Taro.showToast({ Taro.showToast({
title: e.msg, title: e.msg,
@@ -217,13 +218,13 @@ const openSku = () => {
isSkuShow.value = true; isSkuShow.value = true;
}; };
const selectSku = () => {}; // const selectSku = () => {};
const clickBtnOperate = () => {}; // const clickBtnOperate = () => {};
const close = () => {}; // const close = () => {};
const add_cart = async () => { const add_cart = async () => {
if (isSkuShow.value === false) return openSku(); if (isSkuShow.value === false) return openSku();
try { try {
await addCart({ gid: Number(goodInfo.value.gid) }); await addCart({ gid: goodInfo.value.gid });
Taro.showToast({ Taro.showToast({
title: "加入购物车成功", title: "加入购物车成功",
icon: "success", icon: "success",
@@ -248,20 +249,22 @@ const toOrderDetail = async () => {
if (payType.value === "jf") { if (payType.value === "jf") {
res = await createOrder([ res = await createOrder([
{ {
gid: Number(goodInfo.value.gid), gid: goodInfo.value.gid,
count: Number(count.value), count: Number(count.value),
}, },
]); ]);
} else { } else {
res = await createActiveOrder({ res = await createActiveOrder({
gid: goodInfo.value.gid, gid: goodInfo.value.gid,
stock: count.value, stock: Number(count.value),
}); });
} }
orderData.value = res.data.data; orderData.value = res.data.data;
isShowPay.value = true; isShowPay.value = true;
count.value = 1;
} catch (e) { } catch (e) {
Taro.showToast({ Taro.showToast({
title: e.msg, title: e.msg,
@@ -334,7 +337,7 @@ const toPage = (url: string, type: number = 1) => {
.nut-swiper-item img { .nut-swiper-item img {
width: 100%; width: 100%;
height: 450px; height: 550px;
} }
.card { .card {
@@ -346,6 +349,11 @@ const toPage = (url: string, type: number = 1) => {
font-weight: bold; font-weight: bold;
color: #333; color: #333;
} }
.sub {
font-size: 24px;
color: #999;
}
} }
.rich-box { .rich-box {
@@ -361,6 +369,17 @@ const toPage = (url: string, type: number = 1) => {
font-weight: bold; font-weight: bold;
color: #333; color: #333;
} }
.rich {
box-sizing: border-box;
// &[img] {
// max-width: 100%;
// }
// &[alt] {
// max-width: 100%;
// }
}
} }
.nut-sku { .nut-sku {

View File

@@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: '活动订单',
})

View File

@@ -0,0 +1,376 @@
<script lang="ts" setup>
import { ref } from "vue";
import {
useLoad,
useReachBottom,
showToast,
navigateTo,
setStorageSync,
} from "@tarojs/taro";
import Pay from "@/components/Pay.vue";
import { getActiveOrderList, deleteActiveOrder } from "@/api/goods";
import { getOrderStatistics } from "@/api/order";
const tabValue = ref(0);
const isShowPay = ref(false);
const tabsList = ref([
{
title: "全部",
value: 0,
num: 0,
},
{
title: "待付款",
value: 1,
num: 0,
},
{
title: "待使用",
value: 2,
num: 0,
},
{
title: "已使用",
value: 3,
num: 0,
},
{
title: "已失效",
value: 4,
num: 0,
},
]);
const jfInfo = ref({});
interface OrderList {
add_time: string;
status: number;
BindGoods: {
cover: string;
name: string;
number: number;
};
count: number;
number: number;
}
const orderList = ref<OrderList[]>([]);
useLoad((options) => {
console.log(options);
// tabValue.value = Number(options.type);
getList();
});
const countInfo = ref<any>({});
const getTj = async () => {
try {
const res = await getOrderStatistics({
type: 1,
});
countInfo.value = res.data.data;
console.log(res);
tabsList.value[0].num = countInfo.value.A;
tabsList.value[1].num = countInfo.value.B;
tabsList.value[2].num = countInfo.value.C;
tabsList.value[3].num = countInfo.value.D;
tabsList.value[4].num = countInfo.value.F;
} catch (error) {
showToast({
title: error.msg,
icon: "none",
});
}
};
const getList = async () => {
try {
const res = await getActiveOrderList({
status: tabValue.value,
});
console.log(res);
orderList.value = res.data.data;
} catch (error) {
showToast({
title: error.msg,
icon: "none",
});
}
getTj();
};
const tabChange = (index: number) => {
tabValue.value = index;
getList();
};
useReachBottom(() => {
console.log("useReachBottom");
});
const openPay = (item: OrderList) => {
isShowPay.value = true;
jfInfo.value = item;
};
const errPay = () => {
isShowPay.value = false;
showToast({
title: "支付失败",
icon: "none",
});
jfInfo.value = {};
getList();
};
// const successPay = (val: boolean) => {
// isShowPay.value = val;
// showToast({
// title: "支付成功",
// icon: "none",
// });
// jfInfo.value = {};
// getList();
// };
const closePay = () => {
isShowPay.value = false;
showToast({
title: "支付取消",
icon: "none",
});
jfInfo.value = {};
getList();
};
const toDetail = (item: any) => {
setStorageSync("item", item);
navigateTo({
url: `/pages/users/order_list_detail/index?Id=${item.oid}&type=1`,
});
};
const delOrder = async (oid: string) => {
try {
const res = await deleteActiveOrder({
oid,
});
console.log(res);
getList();
} catch (error) {
showToast({
title: error.msg,
icon: "none",
});
}
};
</script>
<template>
<view>
<view class="topTips">
<view>
<view style="font-weight: bold">订单信息</view>
<view style="font-size: 15px"
>总消费(){{ countInfo.Total || 0 }}
</view>
</view>
<image src="../static/user/order_list_top.png" />
</view>
<view class="tabs-box">
<view
v-for="item in tabsList"
:key="item.value"
@click="tabChange(item.value)"
>
<view class="text">{{ item.title }}</view>
<view>{{ item.num }}</view>
<view
class="line"
:class="{ lineColor: item.value === tabValue }"
></view>
</view>
</view>
<view v-if="orderList.length > 0">
<view
class="order-card"
v-for="(item, index) in orderList"
:key="index"
>
<view class="top">
<view>{{
item.add_time.slice(0, 19).replace("T", " ")
}}</view>
<view style="color: red">{{
item.status === 0
? "待付款"
: item.status === 1
? "待使用"
: item.status === 2
? "已使用"
: "已失效"
}}</view>
</view>
<view class="line"></view>
<view class="center">
<view class="top">
<image :src="item.BindGoods.cover" />
<view class="title">{{ item.BindGoods.name }} </view>
<view class="right">
<view>{{ item.number }}</view>
<view>x{{ item.count }}</view>
</view>
</view>
<!-- <view
class="bom"
style="text-align: right; font-size: 13px"
>
{{ item.count }}件商品,实付():
<text style="color: red">{{ item.number }}</text>
</view> -->
</view>
<view class="line"></view>
<view class="btn">
<nut-button
v-if="item.status === 0"
plain
size="small"
type="primary"
@click="delOrder(item.oid)"
>删除订单
</nut-button>
<nut-button
style="margin-left: 5px"
size="small"
type="primary"
@click="toDetail(item)"
>查看详情
</nut-button>
<nut-button
style="margin-left: 5px"
size="small"
type="primary"
v-if="item.status === 0"
@click="openPay(item)"
>立即付款
</nut-button>
</view>
</view>
</view>
<nut-empty v-else description="暂无订单"></nut-empty>
<pay
:isShowPay="isShowPay"
payType="wx"
@errPay="errPay"
@closePay="closePay"
:jfInfo="jfInfo"
/>
</view>
</template>
<style lang="scss">
.topTips {
box-sizing: border-box;
width: 100%;
background-color: #ff0000;
color: #ffffff;
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
image {
width: 150px;
height: 150px;
}
}
.tabs-box {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: auto;
background-color: #fff;
padding: 0 20px;
text-align: center;
.text {
margin: 10px 20px;
align-items: center;
}
.line {
margin: 0 auto;
width: 50px;
height: 5px;
border-radius: 30px;
transition: all 0.3s ease-in-out;
}
.lineColor {
background-color: #ff0000;
}
}
.order-card {
width: 95%;
box-sizing: border-box;
margin: 15px auto;
background-color: #fff;
border-radius: 10px;
padding: 20px;
.line {
width: 100%;
height: 1px;
background-color: #f5f5f5;
margin: 10px;
}
.top {
display: flex;
justify-content: space-between;
align-items: center;
}
.btn {
display: flex;
justify-content: flex-end;
align-items: center;
}
.center {
.top {
display: flex;
justify-content: space-between;
// align-items: flex-start;
image {
width: 150px;
height: 150px;
}
.title {
margin-left: 10px;
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
width: 350px;
}
.right {
margin-left: 10px;
font-size: 28px;
text-align: right;
}
}
}
}
</style>

View File

@@ -3,14 +3,18 @@
<!-- 金刚区 --> <!-- 金刚区 -->
<view class="top-box"> <view class="top-box">
<view class="item"> <view class="item">
<view @click="hotGoodsDetail">
<IconFont
name="http://article.biliimg.com/bfs/article/131eda0add8662808d97ffb1191d19bf3e420647.png"
size="40"
/>
<view>我的订单</view> <view>我的订单</view>
</view> </view>
</view>
<view class="item"> <view class="item">
<view></view> <view></view>
</view> </view>
<view class="item"> <view class="item"> </view>
</view>
<view class="item"> <view class="item">
<view></view> <view></view>
</view> </view>
@@ -45,6 +49,7 @@
import { ref } from "vue"; import { ref } from "vue";
import { useLoad, navigateTo } from "@tarojs/taro"; import { useLoad, navigateTo } from "@tarojs/taro";
import { getActiveGoods } from "../../../api/goods"; import { getActiveGoods } from "../../../api/goods";
import { IconFont } from "@nutui/icons-vue-taro";
const list = ref<any>([]); const list = ref<any>([]);
@@ -63,6 +68,12 @@ const toGoodDetails = (id: number) => {
url: `/pages/goods/goods_detail/index?gid=${id}&type=1`, url: `/pages/goods/goods_detail/index?gid=${id}&type=1`,
}); });
}; };
const hotGoodsDetail = () => {
navigateTo({
url: `/pages/hotGoods/hot_list/index`,
});
};
</script> </script>
<style lang="scss"> <style lang="scss">
@@ -70,14 +81,14 @@ const toGoodDetails = (id: number) => {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin: 10px 20px 0 20px; margin: 10px 20px 0 20px;
background-color: #fff;
border-radius: 10px;
.item { .item {
width: 150px; width: 150px;
height: 150px; padding: 10px;
background-color: #fff; background-color: #fff;
border-radius: 10px;
text-align: center; text-align: center;
line-height: 150px;
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -13,7 +13,7 @@
auto-play="3000" auto-play="3000"
> >
<nut-swiper-item v-for="(itm, idx) in swiperList" :key="idx"> <nut-swiper-item v-for="(itm, idx) in swiperList" :key="idx">
<img :src="itm.url" :alt="itm.id.toString()"/> <img :src="itm.url" :alt="itm.ID.toString()" />
</nut-swiper-item> </nut-swiper-item>
</nut-swiper> </nut-swiper>
<!-- 金刚区 --> <!-- 金刚区 -->
@@ -39,20 +39,21 @@
:key="item.gid" :key="item.gid"
@click.stop="toGoodDetails(item.gid as number)" @click.stop="toGoodDetails(item.gid as number)"
> >
<image <image :src="(item.cover as string)" />
:src="(item.cover as string)"
/>
<view class="good-text-box"> <view class="good-text-box">
<text class="good-text" <text class="good-text">{{ item.name }} </text>
>{{ item.name }}
</text
>
<view class="good-price-box"> <view class="good-price-box">
<text class="good-text-price"> <text class="good-text-price">
<text style="font-size: 20px">{{ item.number }}</text> <text style="font-size: 20px">{{
item.number
}}</text>
积分 积分
</text> </text>
<Cart size="20" color="#ff0000" @click.stop="add_cart(item.gid as number)"/> <!-- <Cart
size="20"
color="#ff0000"
@click.stop="add_cart(item.gid as number)"
/> -->
</view> </view>
</view> </view>
</view> </view>
@@ -61,113 +62,95 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {ref} from 'vue' import { ref } from "vue";
import {Cart} from '@nutui/icons-vue-taro' // import { Cart } from "@nutui/icons-vue-taro";
import Taro from '@tarojs/taro' import Taro from "@tarojs/taro";
import {getBanner} from '@/api/user' import { getBanner } from "@/api/user";
import {getGoodsList, addCart} from '@/api/goods' import { getGoodsList, addCart } from "@/api/goods";
const searchValue = ref('') const searchValue = ref("");
// const tabvalue = ref("0"); // const tabvalue = ref("0");
const swiperList = ref([ const swiperList = ref<any>([]);
{
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 userMenuList = ref([ const userMenuList = ref([
{ {
id: 1, id: 1,
label: '活动游戏', label: "活动游戏",
url: '/pages/game/gamehome/index', url: `/pages/game/gamehome/index?uid=${Taro.getStorageSync("token")}`,
icon: 'http://jdt168.com/uploads/merchant/20220829/caad6be8983e88c41d28da7d124bc37b.png' icon: "http://jdt168.com/uploads/merchant/20220829/caad6be8983e88c41d28da7d124bc37b.png",
}, },
{ {
id: 2, id: 2,
label: '活动商品', label: "活动商品",
url: '/pages/hotGoods/index/index', url: "/pages/hotGoods/index/index",
icon: 'http://jdt168.com/uploads/def/20230509/d59e7fcb65a88bc56694dae4f9d21b51.png' icon: "http://jdt168.com/uploads/def/20230509/d59e7fcb65a88bc56694dae4f9d21b51.png",
}, },
{ {
id: 3, id: 3,
label: '商户入驻', label: "商户入驻",
url: '/pages/users/settled_mer/index', url: "/pages/users/settled_mer/index",
icon: 'http://jdt168.com/uploads/merchant/20220829/6fe67b93721a42aedc842c4f19d6f2d3.png' icon: "http://jdt168.com/uploads/merchant/20220829/6fe67b93721a42aedc842c4f19d6f2d3.png",
}, },
{ {
id: 4, id: 4,
label: '最新资讯', label: "最新资讯",
url: '', url: "",
icon: 'http://jdt168.com/uploads/merchant/20220829/b975136a9b64aab69bf11d75a194f1ea.png' icon: "http://jdt168.com/uploads/merchant/20220829/b975136a9b64aab69bf11d75a194f1ea.png",
} },
]) ]);
interface List { interface List {
gid?: number gid?: number;
name?: string name?: string;
number?: number number?: number;
cover?: string cover?: string;
} }
const list = ref<Array<List>>([]) const list = ref<Array<List>>([]);
Taro.useLoad(() => { Taro.useLoad(() => {
getBannerList() getBannerList();
get_goods_list() get_goods_list();
}) });
const get_goods_list = async () => { const get_goods_list = async () => {
const {data} = await getGoodsList() const { data } = await getGoodsList();
list.value = data.data list.value = data.data;
} };
const getBannerList = async () => { const getBannerList = async () => {
const {data}: any = await getBanner() const { data }: any = await getBanner();
console.log(data) swiperList.value = data.data;
} };
const add_cart = async (gid: number) => { // const add_cart = async (gid: number) => {
try { // try {
await addCart({gid: Number(gid)}) // await addCart({ gid });
Taro.showToast({ // Taro.showToast({
title: '加入购物车成功', // title: "加入购物车成功",
icon: 'success', // icon: "success",
duration: 2000 // duration: 2000,
}) // });
} catch (e) { // } catch (e) {
Taro.showToast({ // Taro.showToast({
title: e.msg, // title: e.msg,
icon: 'none' // icon: "none",
}) // });
} // }
// };
}
const toPage = (url: string) => { const toPage = (url: string) => {
Taro.navigateTo({ Taro.navigateTo({
url: url url: url,
}) });
} };
const toGoodDetails = (gid: number) => { const toGoodDetails = (gid: number) => {
Taro.navigateTo({ Taro.navigateTo({
url: `/pages/goods/goods_detail/index?gid=${gid}` url: `/pages/goods/goods_detail/index?gid=${gid}`,
}) });
} };
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@@ -7,20 +7,29 @@
> >
<view class="user-center-card__header__avatar"> <view class="user-center-card__header__avatar">
<nut-avatar size="large"> <nut-avatar size="large">
<img <img :src="userInfo.avatarUrl" />
:src="userInfo.avatarUrl"
/>
</nut-avatar> </nut-avatar>
</view> </view>
<view class="user-center-card__header__info"> <view class="user-center-card__header__info">
<view class="user-center-card__header__info__name">{{ userInfo.nickName }}</view> <view class="user-center-card__header__info__name">{{
<view class="user-center-card__header__info__desc" userInfo.nickName
>ID:{{ userInfo.ID }} }}</view>
</view <view v-if="!userInfo.phone">
> <nut-button
size="mini"
open-type="getPhoneNumber"
@getphonenumber="getphonenumber"
>点击绑定手机号
</nut-button>
</view>
</view> </view>
<view class="rightIcon"> <view class="rightIcon">
<Setting @click="toSetting" size="22"/> <Scan style="margin-right: 20px" @click="scanCode" size="22" />
<Setting
style="margin-right: 20px"
@click="toSetting"
size="22"
/>
</view> </view>
</view> </view>
<view v-else class="user-center-card__header__transparent"> <view v-else class="user-center-card__header__transparent">
@@ -36,8 +45,7 @@
class="user-center-card__header__info__name" class="user-center-card__header__info__name"
@tap="clickLogin" @tap="clickLogin"
>点击立即授权 >点击立即授权
</view </view>
>
</view> </view>
</view> </view>
<view class="container"> <view class="container">
@@ -52,19 +60,35 @@
</view> </view>
<view class="center"> <view class="center">
<view class="center-t" @click="toOrderList(1)"> <view class="center-t" @click="toOrderList(1)">
<Order size="25px"/> <!-- <Order size="25px"/> -->
<IconFont
name="http://article.biliimg.com/bfs/article/131eda0add8662808d97ffb1191d19bf3e420647.png"
size="40"
/>
<view class="center-text">待付款</view> <view class="center-text">待付款</view>
</view> </view>
<view class="center-t" @click="toOrderList(2)"> <view class="center-t" @click="toOrderList(2)">
<Clock size="25px"/> <!-- <Clock size="25px"/> -->
<IconFont
name="http://article.biliimg.com/bfs/article/002434c9ed4774cb732517eb27e0ff547a41c606.png"
size="40"
/>
<view class="center-text">待使用</view> <view class="center-text">待使用</view>
</view> </view>
<view class="center-t" @click="toOrderList(3)"> <view class="center-t" @click="toOrderList(3)">
<Shop size="25px"/> <!-- <Shop size="25px"/> -->
<IconFont
name="http://article.biliimg.com/bfs/article/7c2ca0228180fe5f3b1d74b0043d80e76c42eb7d.png"
size="40"
/>
<view class="center-text">已使用</view> <view class="center-text">已使用</view>
</view> </view>
<view class="center-t" @click="toOrderList(4)"> <view class="center-t" @click="toOrderList(4)">
<Del size="25px"/> <!-- <Del size="25px"/> -->
<IconFont
name="http://article.biliimg.com/bfs/article/c4f4e069dddfa7104f794a46a759a7ed478b81ea.png"
size="40"
/>
<view class="center-text">已失效</view> <view class="center-text">已失效</view>
</view> </view>
</view> </view>
@@ -89,7 +113,7 @@
</view> </view>
<!-- 商家管理 --> <!-- 商家管理 -->
<view class="mer-box" v-if="userInfo.bid !== 0"> <view class="mer-box" v-if="userInfo.bid">
<nut-grid :gutter="10" :border="false"> <nut-grid :gutter="10" :border="false">
<nut-grid-item <nut-grid-item
:border="false" :border="false"
@@ -101,12 +125,12 @@
name="https://img11.360buyimg.com/imagetools/jfs/t1/137646/13/7132/1648/5f4c748bE43da8ddd/a3f06d51dcae7b60.png" name="https://img11.360buyimg.com/imagetools/jfs/t1/137646/13/7132/1648/5f4c748bE43da8ddd/a3f06d51dcae7b60.png"
></IconFont> ></IconFont>
</nut-grid-item> </nut-grid-item>
<nut-grid-item text="订单统计"> <!-- <nut-grid-item text="订单统计">
<IconFont <IconFont
size="50" size="50"
name="https://img11.360buyimg.com/imagetools/jfs/t1/137646/13/7132/1648/5f4c748bE43da8ddd/a3f06d51dcae7b60.png" name="https://img11.360buyimg.com/imagetools/jfs/t1/137646/13/7132/1648/5f4c748bE43da8ddd/a3f06d51dcae7b60.png"
></IconFont> ></IconFont>
</nut-grid-item> </nut-grid-item> -->
</nut-grid> </nut-grid>
</view> </view>
@@ -114,73 +138,85 @@
<!--<view class="copy">© 2023 </view>--> <!--<view class="copy">© 2023 </view>-->
</view> </view>
<!-- 登录 --> <!-- 登录 -->
<Auth :visible="isShowLogin" @update:visible="cancelLogin" @ok="getUserInfo"/> <Auth
:visible="isShowLogin"
@update:visible="cancelLogin"
@ok="getUserInfo"
/>
</view> </view>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {ref} from 'vue' import { ref } from "vue";
import { import { ArrowRight, Setting, IconFont, Scan } from "@nutui/icons-vue-taro";
ArrowRight, import Taro from "@tarojs/taro";
Order, import Auth from "@/components/Auth.vue";
Del, import { getPersonalInfo, getPhone, bindParent } from "@/api/user";
Clock,
Shop,
Setting,
IconFont
} from '@nutui/icons-vue-taro'
import Taro from '@tarojs/taro'
import Auth from '@/components/Auth.vue'
import {getPersonalInfo} from '@/api/user'
const isShowLogin = ref(false) const isShowLogin = ref(false);
const isLogin = ref(false) const isLogin = ref(false);
interface UserInfo { interface UserInfo {
nickName?: string nickName?: string;
avatarUrl?: string avatarUrl?: string;
ID?: string ID?: string;
bid?: number bid?: string;
phone?: string;
uid?: string;
} }
const userInfo = ref<UserInfo>({}) const userInfo = ref<UserInfo>({});
Taro.useLoad(() => { Taro.useDidShow(() => {
const token = Taro.getStorageSync('token') const token = Taro.getStorageSync("token");
if (token) { if (token) {
getUserInfo() getUserInfo();
} }
}) });
const cancelLogin = () => { const cancelLogin = () => {
isShowLogin.value = false isShowLogin.value = false;
} };
const getUserInfo = async () => { const getUserInfo = async () => {
Taro.showLoading({ Taro.showLoading({
title: '加载中' title: "加载中",
}) });
const res = await getPersonalInfo() const res = await getPersonalInfo();
userInfo.value = res.data.data userInfo.value = res.data.data;
Taro.setStorageSync('userInfo', res.data.data) Taro.setStorageSync("userInfo", res.data.data);
isLogin.value = true Taro.setStorageSync("mer_type", res.data.store_type);
cancelLogin() isLogin.value = true;
Taro.hideLoading() cancelLogin();
} Taro.hideLoading();
};
const getphonenumber = async (e: any) => {
await getPhone({
uid: userInfo.value.uid,
code: e.detail.code,
});
getUserInfo();
};
const toOrderList = (e: number) => { const toOrderList = (e: number) => {
if (!isLogin)
return Taro.showToast({
title: "请先登录",
icon: "none",
});
Taro.navigateTo({ Taro.navigateTo({
url: `/pages/users/order_list/index?type=${e}` url: `/pages/users/order_list/index?type=${e}`,
}) });
} };
const userMenuList = ref([ const userMenuList = ref([
{ {
id: 1, id: 1,
label: '我的账户', label: "我的账户",
url: '/pages/users/account/index', url: "/pages/users/account/index",
icon: 'http://jdt168.com/uploads/default/20220829/e819815623276fdbb9a54d685292e5c7.png' icon: "http://jdt168.com/uploads/default/20220829/e819815623276fdbb9a54d685292e5c7.png",
}, },
// { // {
// id: 2, // id: 2,
@@ -190,40 +226,62 @@ const userMenuList = ref([
// }, // },
{ {
id: 3, id: 3,
label: '分销中心', label: "我的推广",
url: '', url: "/pages/users/distribution/index",
icon: 'http://jdt168.com/uploads/default/20220829/73656833c1d849c050638f9ee9903b9d.png' icon: "http://jdt168.com/uploads/default/20220829/73656833c1d849c050638f9ee9903b9d.png",
}, },
{ {
id: 4, id: 4,
label: '关注商家', label: "关注商家",
url: '', url: "",
icon: 'http://jdt168.com/uploads/default/20220829/13637589cd20785aa21fca1d4f9b26bc.png' icon: "http://jdt168.com/uploads/default/20220829/13637589cd20785aa21fca1d4f9b26bc.png",
}, },
{ {
id: 5, id: 5,
label: '问题反馈', label: "问题反馈",
url: '', url: "",
icon: 'http://jdt168.com/uploads/default/20220829/7437d90fdd0fba868084bd9cd0b59049.png' icon: "http://jdt168.com/uploads/default/20220829/7437d90fdd0fba868084bd9cd0b59049.png",
} },
]) ]);
const toSetting = () => { const toSetting = () => {
Taro.navigateTo({ Taro.navigateTo({
url: '/pages/users/setting/index' url: "/pages/users/setting/index",
}) });
} };
const clickLogin = () => { const clickLogin = () => {
isShowLogin.value = true isShowLogin.value = true;
} };
const toPage = (url: string) => { const toPage = (url: string) => {
console.log(url)
Taro.navigateTo({ Taro.navigateTo({
url: url url: url,
}) });
};
const scanCode = () => {
Taro.scanCode({
onlyFromCamera: true,
scanType: ["qrCode"],
success: async (data) => {
try {
await bindParent({
uid: data.result,
});
Taro.showToast({
title: "绑定成功",
icon: "none",
});
} catch (error) {
Taro.showToast({
title: error.msg,
icon: "none",
});
} }
},
});
};
</script> </script>
<style lang="scss"> <style lang="scss">
@@ -307,7 +365,7 @@ const toPage = (url: string) => {
align-items: center; align-items: center;
.center-text { .center-text {
margin-top: 20px; margin-top: 15px;
} }
} }
} }

View File

@@ -1,31 +1,154 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from "vue";
import { showToast, useLoad, getStorageSync } from "@tarojs/taro";
import { getIntegralDetail, getBeanDetail } from "@/api/user";
const tabValue = ref(0);
const tabsList = ref([
{
title: "积分明细",
value: 0,
},
{
title: "豆子明细",
value: 1,
},
]);
const tabChange = (index: number) => {
tabValue.value = index;
getList();
};
const data = ref([]);
const userInfo = ref<any>({});
useLoad(() => {
getList();
userInfo.value = getStorageSync("userInfo");
});
const page = ref({
PageNum: 1,
PageSize: 10,
ItemCount: 0,
});
const pageChange = (e: number) => {
page.value.PageNum = e;
getList();
};
const getList = async () => {
try {
let res: any;
if (tabValue.value === 0) {
res = await getBeanDetail({
PageNum: page.value.PageNum,
PageSize: page.value.PageSize,
});
} else {
res = await getIntegralDetail({
PageNum: page.value.PageNum,
PageSize: page.value.PageSize,
});
}
data.value = res.data.data || [];
page.value.ItemCount = res.data.count;
} catch (error) {
showToast({
title: error.msg,
icon: "none",
});
}
};
</script> </script>
<template> <template>
<view> <view>
<view class="card"> <view class="card">
<view class="greeting">Hello! YuanHuakk</view> <!-- <view class="greeting">Hello! YuanHuakk</view> -->
<view class="info"> <view class="info">
<view class="left"> <view class="left">
<view> <view>
<view class="num">豆子188888</view> <view class="num">豆子: {{ userInfo.pulse }}</view>
</view> </view>
<view> <view>
<view class="num">积分188888</view> <view class="num">积分: {{ userInfo.integral }}</view>
</view> </view>
</view> </view>
<image class="img" src="https://picdm.sunbangyan.cn/2023/08/15/ste192.png"/> <!-- <image class="img" src="https://picdm.sunbangyan.cn/2023/08/15/ste192.png"/> -->
</view> </view>
</view> </view>
<view class="tabs-box">
<view
v-for="item in tabsList"
:key="item.value"
@click="tabChange(item.value)"
>
<view class="text">{{ item.title }}</view>
<view
class="line"
:class="{ lineColor: item.value === tabValue }"
></view>
</view>
</view>
<view v-if="data.length > 0">
<view v-if="tabValue === 0">
<view
class="card-list"
v-for="(item, index) in (data as any[])"
:key="index"
>
<view class="left">
<view>购买商品{{ item.goods_name }}</view>
<view>支付时间{{ item.add_time.slice(0, 10) }}</view>
</view>
<view class="right">
<view style="color: green"
>-<text>{{ item.number }}积分</text></view
>
</view>
</view>
</view>
<view v-else>
<view
class="card-list"
v-for="(item, index) in (data as any[])"
:key="index"
>
<view class="left">
<view>购买商品{{ item.goods_name }}</view>
<view>支付金额{{ item.order_number }}</view>
<view>支付时间{{ item.add_time.slice(0, 10) }}</view>
</view>
<view class="right">
<view style="color: red"
>+<text>{{ item.number }}</text
>豆子</view
>
</view>
</view>
</view>
<nut-pagination
v-model="page.PageNum"
:total-items="page.ItemCount"
:items-per-page="page.PageSize"
@change="pageChange"
/>
</view>
<nut-empty v-else description="暂无明细"></nut-empty>
</view> </view>
</template> </template>
<style lang="scss"> <style lang="scss">
page { .nut-pagination {
//background-color: #111; position: absolute;
left: 50%;
transform: translateX(-50%);
} }
.card { .card {
width: 90%; width: 90%;
height: 300px; height: 300px;
@@ -35,7 +158,7 @@ page {
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
margin: 10px auto; margin: 10px auto;
color: #D0A568; color: #d0a568;
padding: 20px; padding: 20px;
.greeting { .greeting {
@@ -50,7 +173,8 @@ page {
.left { .left {
height: 300px; height: 300px;
width: 50%; width: 50%;
text-align: center; text-align: left;
margin-left: 50px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
@@ -67,7 +191,42 @@ page {
height: 270px; height: 270px;
} }
} }
}
.tabs-box {
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
height: auto;
background-color: #fff;
padding: 0 20px;
text-align: center;
.text {
margin: 10px 20px;
align-items: center;
}
.line {
margin: 0 auto;
width: 50px;
height: 5px;
border-radius: 30px;
transition: all 0.3s ease-in-out;
}
.lineColor {
background-color: #ff0000;
}
}
.card-list {
margin: 10px 20px;
background-color: #fff;
display: flex;
border-radius: 10px;
padding: 20px;
justify-content: space-between;
align-items: center;
} }
</style> </style>

View File

@@ -0,0 +1,3 @@
export default definePageConfig({
navigationBarTitleText: "我的推广",
});

View File

@@ -0,0 +1,105 @@
<template>
<view>
<view class="card-list">
<view
class="item"
v-for="(item, index) in list"
:key="index"
@click="clickItem(item)"
>
<view class="text">
<IconFont :name="item.icon" color="red" size="30" />
<view>{{ item.label }}</view>
</view>
</view>
<view style="width: 45%;"></view>
</view>
<!-- 二维码弹窗 -->
<nut-popup :style="{ padding: '30px 50px' }" v-model:visible="show">
<view class="popup">
<view>推荐人二维码绑定</view>
<image :src="urlCode" />
</view>
</nut-popup>
</view>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { IconFont } from "@nutui/icons-vue-taro";
import Taro from "@tarojs/taro";
const show = ref(false);
const urlCode = ref("");
const list = ref([
{
id: 1,
icon: "scan",
label: "推广名片",
},
{
id: 2,
icon: "date",
label: "积分明细",
},
{
id: 3,
icon: "my2",
label: "推广用户",
},
]);
const clickItem = (item: any) => {
if (item.id === 1) {
urlCode.value = `https://api.pwmqr.com/qrcode/create?url=${Taro.getStorageSync(
"token"
)}`;
show.value = true;
} else if (item.id === 2) {
Taro.navigateTo({
url: "/pages/users/distribution/integral/index",
});
} else {
Taro.navigateTo({
url: "/pages/users/distribution/userlist/index",
});
}
};
</script>
<style lang="scss">
.card-list {
display: flex;
justify-content: space-evenly;
flex-wrap: wrap;
.item {
width: 45%;
height: 200px;
background-color: #fff;
border-radius: 20px;
margin-top: 10px;
text-align: center;
padding: 10px;
position: relative;
.text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.popup {
text-align: center;
image {
width: 300px;
height: 300px;
}
}
</style>

View File

@@ -0,0 +1,3 @@
export default definePageConfig({
navigationBarTitleText: "积分明细",
});

View File

@@ -0,0 +1,85 @@
<template>
<view>
<view v-if="data.length > 0">
<view
class="card-list"
v-for="(item, index) in (data as any[])"
:key="index"
>
<view class="left">
<view>昵称{{ item.nick_name }}</view>
<view>购买商品{{ item.goods_name }}</view>
<view>支付时间{{ item.add_time.slice(0, 10) }}</view>
</view>
<view class="right">
<view style="color: red"
>+<text>{{ item.number }}积分</text></view
>
</view>
</view>
<nut-pagination
v-model="page.PageNum"
:total-items="page.ItemCount"
:items-per-page="page.PageSize"
@change="pageChange"
/>
</view>
<view v-else>
<nut-empty description="暂无积分明细" />
</view>
</view>
</template>
<script setup lang="ts">
import { useLoad, showToast } from "@tarojs/taro";
import { ref } from "vue";
import { getTGIntegralDetail } from "../../../../api/user";
const data = ref([]);
useLoad(() => {
getData();
});
const page = ref({
PageNum: 1,
PageSize: 10,
ItemCount: 0,
});
const pageChange = (e: number) => {
page.value.PageNum = e;
getData();
};
const getData = async () => {
try {
const res = await getTGIntegralDetail({
PageNum: page.value.PageNum,
PageSize: page.value.PageSize,
});
data.value = res.data.data || [];
page.value.ItemCount = res.data.count;
} catch (error) {
showToast({ title: error.msg, icon: "none" });
}
};
</script>
<style lang="scss">
.card-list {
margin: 10px 20px;
background-color: #fff;
display: flex;
border-radius: 10px;
padding: 20px;
justify-content: space-between;
align-items: center;
}
.nut-pagination {
position: absolute;
margin-top: 10px;
left: 50%;
transform: translateX(-50%);
}
</style>

View File

@@ -0,0 +1,3 @@
export default definePageConfig({
navigationBarTitleText: "推广人统计",
});

View File

@@ -0,0 +1,93 @@
<template>
<view>
<view v-if="data.length > 0">
<view
class="card-list"
v-for="(item, index) in (data as any[])"
:key="index"
>
<view class="left">
<image :src="item.avatarUrl" />
<view class="text">
<view>{{ item.nickName }}</view>
<view>{{ item.phone }}</view>
</view>
</view>
<view class="right"></view>
</view>
<nut-pagination
v-model="page.PageNum"
:total-items="page.ItemCount"
:items-per-page="page.PageSize"
@change="pageChange"
/>
</view>
<view v-else>
<nut-empty description="暂无明细"></nut-empty>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useLoad, showToast } from "@tarojs/taro";
import { getTGUserList } from "../../../../api/user";
useLoad(() => {
getData();
});
const data = ref([]);
const page = ref({ PageNum: 1, PageSize: 10, ItemCount: 0 });
const pageChange = (e: number) => {
page.value.PageNum = e;
getData();
};
const getData = async () => {
try {
const res = await getTGUserList({
PageNum: page.value.PageNum,
PageSize: page.value.PageSize,
});
data.value = res.data.data || [];
page.value.ItemCount = res.data.count;
} catch (error) {
showToast({ title: error.msg, icon: "none" });
}
};
</script>
<style lang="scss">
.nut-pagination {
position: absolute;
margin-top: 10px;
left: 50%;
transform: translateX(-50%);
}
.card-list {
width: 700px;
background-color: #fff;
margin: 10px auto;
border-radius: 10px;
padding: 20px;
.left {
display: flex;
align-items: center;
image {
width: 100px;
height: 100px;
border-radius: 50%;
}
.text {
margin-left: 20px;
}
}
}
</style>

View File

@@ -0,0 +1,9 @@
const obj = {
a: 1,
b: 3,
c: 10,
};
Object.keys(obj).forEach((item, index) => {
console.log(obj[item]);
});

View File

@@ -9,6 +9,8 @@ import {
} from "@tarojs/taro"; } from "@tarojs/taro";
import Pay from "@/components/Pay.vue"; import Pay from "@/components/Pay.vue";
import { getIntegralOrderList } from "@/api/user"; import { getIntegralOrderList } from "@/api/user";
import { deleteJfOrder } from "@/api/goods";
import { getOrderStatistics } from "@/api/order";
const tabValue = ref(0); const tabValue = ref(0);
@@ -18,7 +20,7 @@ const tabsList = ref([
{ {
title: "全部", title: "全部",
value: 0, value: 0,
num: 3, num: 0,
}, },
{ {
title: "待付款", title: "待付款",
@@ -28,23 +30,24 @@ const tabsList = ref([
{ {
title: "待使用", title: "待使用",
value: 2, value: 2,
num: 1, num: 0,
}, },
{ {
title: "已使用", title: "已使用",
value: 3, value: 3,
num: 1, num: 0,
}, },
{ {
title: "已失效", title: "已失效",
value: 4, value: 4,
num: 1, num: 0,
}, },
]); ]);
const jfInfo = ref({}); const jfInfo = ref({});
interface OrderList { interface OrderList {
oid: string;
add_time: string; add_time: string;
status: number; status: number;
BindGoods: { BindGoods: {
@@ -68,6 +71,7 @@ const getList = async () => {
const res = await getIntegralOrderList({ const res = await getIntegralOrderList({
status: tabValue.value, status: tabValue.value,
}); });
console.log(res); console.log(res);
orderList.value = res.data.data; orderList.value = res.data.data;
} catch (error) { } catch (error) {
@@ -76,6 +80,7 @@ const getList = async () => {
icon: "none", icon: "none",
}); });
} }
getTj();
}; };
const tabChange = (index: number) => { const tabChange = (index: number) => {
@@ -88,9 +93,8 @@ useReachBottom(() => {
}); });
const openPay = (item: OrderList) => { const openPay = (item: OrderList) => {
console.log("openPay", item);
isShowPay.value = true; isShowPay.value = true;
jfInfo.value = item; jfInfo.value = [item];
}; };
const errPay = () => { const errPay = () => {
@@ -100,6 +104,7 @@ const errPay = () => {
icon: "none", icon: "none",
}); });
jfInfo.value = {}; jfInfo.value = {};
getList();
}; };
const closePay = () => { const closePay = () => {
isShowPay.value = false; isShowPay.value = false;
@@ -108,6 +113,7 @@ const closePay = () => {
icon: "none", icon: "none",
}); });
jfInfo.value = {}; jfInfo.value = {};
getList();
}; };
const toDetail = (item: any) => { const toDetail = (item: any) => {
@@ -116,6 +122,40 @@ const toDetail = (item: any) => {
url: `/pages/users/order_list_detail/index?orderId=${item.oid}`, url: `/pages/users/order_list_detail/index?orderId=${item.oid}`,
}); });
}; };
const delOrder = async (oid: string) => {
try {
const res = await deleteJfOrder({ oid });
console.log(res);
} catch (error) {
showToast({
title: error.msg,
icon: "none",
});
}
getList();
};
const countInfo = ref<any>({});
const getTj = async () => {
try {
const res = await getOrderStatistics({
type: 2,
});
countInfo.value = res.data.data;
tabsList.value[0].num = countInfo.value.A || 0;
tabsList.value[1].num = countInfo.value.B || 0;
tabsList.value[2].num = countInfo.value.C || 0;
tabsList.value[3].num = countInfo.value.D || 0;
tabsList.value[4].num = countInfo.value.F || 0;
} catch (error) {
showToast({
title: error.msg,
icon: "none",
});
}
};
</script> </script>
<template> <template>
@@ -124,7 +164,7 @@ const toDetail = (item: any) => {
<view> <view>
<view style="font-weight: bold">订单信息</view> <view style="font-weight: bold">订单信息</view>
<view style="font-size: 15px" <view style="font-size: 15px"
>消费订单{{ 10 || 0 }} 总消费积分{{ 12312 || 0 }} >消费积分{{ countInfo.Total || 0 }}
</view> </view>
</view> </view>
<image src="../static/user/order_list_top.png" /> <image src="../static/user/order_list_top.png" />
@@ -167,17 +207,17 @@ const toDetail = (item: any) => {
<image :src="item.BindGoods.cover" /> <image :src="item.BindGoods.cover" />
<view class="title">{{ item.BindGoods.name }} </view> <view class="title">{{ item.BindGoods.name }} </view>
<view class="right"> <view class="right">
<view>{{ item.BindGoods.number }}</view> <view>{{ item.number }}</view>
<view>x{{ item.count }}</view> <view>x{{ item.count }}</view>
</view> </view>
</view> </view>
<view <!-- <view
class="bom" class="bom"
style="text-align: right; font-size: 13px" style="text-align: right; font-size: 13px"
> >
{{ item.count }}件商品,实付积分: {{ item.count }}件商品,实付积分:
<text style="color: red">{{ item.number }}</text> <text style="color: red">{{ item.number }}</text>
</view> </view> -->
</view> </view>
<view class="line"></view> <view class="line"></view>
<view class="btn"> <view class="btn">
@@ -186,6 +226,7 @@ const toDetail = (item: any) => {
plain plain
size="small" size="small"
type="primary" type="primary"
@click="delOrder(item.oid)"
>取消订单 >取消订单
</nut-button> </nut-button>
<nut-button <nut-button

View File

@@ -48,7 +48,7 @@
>{{ goodInfo.BindGoods.name }} >{{ goodInfo.BindGoods.name }}
</view> </view>
<view class="right"> <view class="right">
<view>{{ goodInfo.BindGoods.number }}</view> <view>{{ goodInfo.number }}</view>
<view>x{{ goodInfo.count }}</view> <view>x{{ goodInfo.count }}</view>
</view> </view>
</view> </view>
@@ -59,6 +59,15 @@
title="下单时间:" title="下单时间:"
:desc="goodInfo.add_time.slice(0, 19)" :desc="goodInfo.add_time.slice(0, 19)"
></nut-cell> ></nut-cell>
<nut-cell
v-if="goodInfo.expires !== 0"
title="商品过期时间:"
:desc="
dayjs
.unix(goodInfo.expires)
.format('YYYY-MM-DD HH:mm:ss')
"
></nut-cell>
<nut-cell <nut-cell
title="支付状态:" title="支付状态:"
:desc=" :desc="
@@ -72,14 +81,14 @@
" "
></nut-cell> ></nut-cell>
<nut-cell <nut-cell
title="商品总价(积分):" :title="`商品总价(${type === '1' ? '元' : '积分'}):`"
:desc="goodInfo.number" :desc="goodInfo.number"
></nut-cell> ></nut-cell>
<nut-cell> <nut-cell>
<template #default> <template #default>
<view style="text-align: right; width: 100%"> <view style="text-align: right; width: 100%">
<view <view
>实付款(积分): >实付款({{ type === "1" ? "元" : "积分" }}):
<nut-price <nut-price
:price="goodInfo.number" :price="goodInfo.number"
size="normal" size="normal"
@@ -91,13 +100,13 @@
</nut-cell> </nut-cell>
</nut-cell-group> </nut-cell-group>
<view class="btn"> <view class="btn">
<nut-button <!-- <nut-button
plain plain
v-if="goodInfo.status === 0" v-if="goodInfo.status === 0"
size="small" size="small"
type="primary" type="primary"
>取消订单 >取消订单
</nut-button> </nut-button> -->
<nut-button <nut-button
v-if="goodInfo.status === 0" v-if="goodInfo.status === 0"
style="margin-left: 5px" style="margin-left: 5px"
@@ -130,6 +139,13 @@
<image class="qrcode" :src="url"></image> <image class="qrcode" :src="url"></image>
</view> </view>
</nut-popup> </nut-popup>
<pay
:isShowPay="isShowPay"
:payType="type === '1' ? 'wx' : 'jf'"
@errPay="errPay"
@closePay="closePay"
:jfInfo="jfInfo"
/>
</view> </view>
</template> </template>
@@ -139,9 +155,11 @@ import {
getStorageSync, getStorageSync,
makePhoneCall, makePhoneCall,
openLocation, openLocation,
showToast,
} from "@tarojs/taro"; } from "@tarojs/taro";
import { Service, Find } from "@nutui/icons-vue-taro"; import { Service, Find } from "@nutui/icons-vue-taro";
import { ref } from "vue"; import { ref } from "vue";
import dayjs from "dayjs";
const goodInfo = ref<any>({}); const goodInfo = ref<any>({});
@@ -165,11 +183,15 @@ const statusList = ref([
]); ]);
const isShowCode = ref(false); const isShowCode = ref(false);
const isShowPay = ref(false);
const jfInfo = ref<any>({});
const type = ref("");
const url = ref(""); const url = ref("");
useLoad((options) => { useLoad((options) => {
console.log("options", options); type.value = options.type;
goodInfo.value = getStorageSync("item"); goodInfo.value = getStorageSync("item");
}); });
@@ -187,7 +209,27 @@ const toAdder = () => {
}); });
}; };
const openPay = () => {}; const openPay = () => {
isShowPay.value = true;
jfInfo.value = getStorageSync("item");
};
const errPay = () => {
isShowPay.value = false;
showToast({
title: "支付失败",
icon: "none",
});
jfInfo.value = {};
};
const closePay = () => {
isShowPay.value = false;
showToast({
title: "支付取消",
icon: "none",
});
jfInfo.value = {};
};
const openCode = () => { const openCode = () => {
url.value = `https://api.pwmqr.com/qrcode/create?url=${goodInfo.value.oid}`; url.value = `https://api.pwmqr.com/qrcode/create?url=${goodInfo.value.oid}`;

View File

@@ -1,213 +1,388 @@
<script lang="ts" setup> <script lang="ts" setup>
import Taro from '@tarojs/taro' import Taro from "@tarojs/taro";
import {ref} from 'vue' import { ref } from "vue";
import {getVerifyCode, applyMer, getMerTypeList} from '@/api/user' import { getVerifyCode, applyMer, getMerTypeList } from "@/api/user";
import Upload from "@/components/Upload.vue";
const visible = ref(false) const visible = ref(false);
const merType = ref(false) const merType = ref(false);
const merGooType = ref(false);
const merGooType = ref(false)
// 验证码按钮文字 // 验证码按钮文字
const smsStr = ref('获取验证码') const smsStr = ref("获取验证码");
// 验证码按钮是否禁用 // 验证码按钮是否禁用
const smsDisabled = ref(false) const smsDisabled = ref(false);
// 表单数据 // 表单数据
const formValue = ref({ const formValue = ref<any>({
name: '', name: "",
userName: '', userName: "",
phone: '', phone: "",
code: '', code: "",
bType: '', bType: "",
merTypeStr: '', merTypeStr: "",
classId: '', classId: "",
merGooTypeStr: '' merGooTypeStr: "",
}) license: [],
front: [],
back: [],
head_photo: [],
img: [],
});
const merGooList = ref([]) const merGooList = ref([]);
const merList = ref([]) const merList = ref([]);
// 表单校验 // 表单校验
const ruleForm = ref<any>(null) const ruleForm = ref<any>(null);
Taro.useLoad(() => { Taro.useLoad(() => {
getMerType() getMerType();
}) });
// 获取商户类型 // 获取商户类型
const getMerType = async () => { const getMerType = async () => {
try { try {
const res = await getMerTypeList() const res = await getMerTypeList();
console.log(res) console.log(res);
merList.value = res.data.type.map((item: any) => { merList.value = res.data.type.map((item: any) => {
return { return {
text: item.name, text: item.name,
value: item.ID value: item.ID,
} };
}) });
merGooList.value = res.data.class.map((item: any) => { merGooList.value = res.data.class.map((item: any) => {
return { return {
text: item.name, text: item.name,
value: item.ID value: item.ID,
} };
}) });
} catch (e) { } catch (e) {
Taro.showToast({ Taro.showToast({
title: e.msg, title: e.msg,
icon: 'none' icon: "none",
}) });
}
} }
};
// 关闭弹窗 // 关闭弹窗
const onOk = async () => { const onOk = async () => {
try { try {
const res = await applyMer(formValue.value) const data = {
...formValue.value,
license: formValue.value.license[0]?.url,
front: formValue.value.front[0]?.url,
back: formValue.value.back[0]?.url,
head_photo: formValue.value.head_photo[0]?.url,
img: formValue.value.img.map((item: any) => item.url),
};
const res = await applyMer(data);
Taro.showToast({ Taro.showToast({
title: res.msg, title: res.msg,
icon: 'none' icon: "none",
}) });
} catch (e) { } catch (e) {
Taro.showToast({ Taro.showToast({
title: e.msg, title: e.msg,
icon: 'none' icon: "none",
}) });
}
visible.value = false
} }
visible.value = false;
};
// 打开弹窗 // 打开弹窗
const open = () => { // const open = () => {
console.log('open') // console.log("open");
visible.value = true // visible.value = true;
} // };
// 获取验证码 // 获取验证码
const getSmsCode = () => { const getSmsCode = () => {
ruleForm.value.validate('phone').then(async ({valid}: any) => { ruleForm.value.validate("phone").then(async ({ valid }: any) => {
if (valid) { if (valid) {
try { try {
await getVerifyCode({ await getVerifyCode({
phone: formValue.value.phone.toString() phone: formValue.value.phone.toString(),
}) });
smsDisabled.value = true smsDisabled.value = true;
let time = 10 let time = 60;
const timer = setInterval(() => { const timer = setInterval(() => {
time-- time--;
smsStr.value = `${time}s` smsStr.value = `${time}s`;
if (time === 0) { if (time === 0) {
clearInterval(timer) clearInterval(timer);
smsDisabled.value = false smsDisabled.value = false;
smsStr.value = '获取验证码' smsStr.value = "获取验证码";
} }
}, 1000) }, 1000);
} catch (e) { } catch (e) {
Taro.showToast({ Taro.showToast({
title: e.message, title: e.message,
icon: 'none' icon: "none",
}) });
} }
} }
}) });
} };
// 选择商户类型 // 选择商户类型
const confirmMerType = (e: any) => { const confirmMerType = (e: any) => {
formValue.value.merTypeStr = e.selectedOptions[0].text formValue.value.merTypeStr = e.selectedOptions[0].text;
formValue.value.bType = e.selectedOptions[0].value formValue.value.bType = e.selectedOptions[0].value;
merType.value = false merType.value = false;
} };
// 选择经营类目 // 选择经营类目
const confirmGooType = (e: any) => { const confirmGooType = (e: any) => {
formValue.value.merGooTypeStr = e.selectedOptions[0].text formValue.value.merGooTypeStr = e.selectedOptions[0].text;
formValue.value.classId = e.selectedOptions[0].value formValue.value.classId = e.selectedOptions[0].value;
merGooType.value = false merGooType.value = false;
} };
// 提交 // 提交
const submit = () => { const submit = () => {
ruleForm.value.validate().then(({ valid, errors }: any) => { ruleForm.value.validate().then(({ valid, errors }: any) => {
if (valid) { if (valid) {
console.log('success', formValue.value) console.log("success", formValue.value);
visible.value = true visible.value = true;
} else { } else {
console.log('error submit!!', errors) console.log("error submit!!", errors);
}
})
} }
});
};
</script> </script>
<template> <template>
<view> <view>
<nut-form ref="ruleForm" class="form" :model-value="formValue"> <nut-form ref="ruleForm" class="form" :model-value="formValue">
<nut-form-item required label="商户名称" prop="name" :rules="[{ <nut-form-item
required
label="商户名称"
prop="name"
:rules="[
{
required: true, required: true,
message: '请输入商户名称', message: '请输入商户名称',
}]"> },
<input type="text" v-model="formValue.name" placeholder="请输入商户名称"/> ]"
>
<input
type="text"
v-model="formValue.name"
placeholder="请输入商户名称"
/>
</nut-form-item> </nut-form-item>
<nut-form-item required label="用户姓名" prop="userName" :rules="[{ <nut-form-item
required
label="用户姓名"
prop="userName"
:rules="[
{
required: true, required: true,
message: '请输入用户姓名', message: '请输入用户姓名',
}]"> },
<input type="text" v-model="formValue.userName" placeholder="请输入真实姓名"/> ]"
>
<input
type="text"
v-model="formValue.userName"
placeholder="请输入真实姓名"
/>
</nut-form-item> </nut-form-item>
<nut-form-item required label="联系电话" prop="phone" :rules="[{ <nut-form-item
required
label="联系电话"
prop="phone"
:rules="[
{
required: true, required: true,
message: '请输入正确的电话号码', message: '请输入正确的电话号码',
regex: /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/, regex: /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/,
}]"> },
<input type="text" :maxlength="11" v-model="formValue.phone" placeholder="请输入联系电话"/> ]"
>
<input
type="text"
:maxlength="11"
v-model="formValue.phone"
placeholder="请输入联系电话"
/>
</nut-form-item> </nut-form-item>
<nut-form-item required label="验证码" prop="code" :rules="[{ <nut-form-item
required
label="验证码"
prop="code"
:rules="[
{
required: true, required: true,
message: '请输入验证码', message: '请输入验证码',
}]"> },
]"
>
<view class="yanCode"> <view class="yanCode">
<input type="text" :maxlength="6" v-model="formValue.code" placeholder="请输入验证码"/> <input
<nut-button style="width: 100px; padding: 3px" plain type="primary" size="mini" type="text"
:disabled="smsDisabled" round :maxlength="6"
@click="getSmsCode"> v-model="formValue.code"
placeholder="请输入验证码"
/>
<nut-button
style="width: 100px; padding: 3px"
plain
type="primary"
size="mini"
:disabled="smsDisabled"
round
@click="getSmsCode"
>
{{ smsStr }} {{ smsStr }}
</nut-button> </nut-button>
</view> </view>
</nut-form-item> </nut-form-item>
<nut-form-item required label="商户类型" prop="merTypeStr" :rules="[{ <nut-form-item
required
label="商户类型"
prop="merTypeStr"
:rules="[
{
required: true, required: true,
message: '请选择商户类型', message: '请选择商户类型',
}]"> },
<input type="text" :disabled="true" v-model="formValue.merTypeStr" placeholder="请选择商户类型" ]"
@click="merType = true"/> >
<input
type="text"
:disabled="true"
v-model="formValue.merTypeStr"
placeholder="请选择商户类型"
@click="merType = true"
/>
<nut-popup position="bottom" v-model:visible="merType"> <nut-popup position="bottom" v-model:visible="merType">
<nut-picker :columns="merList" title="商户类型" @confirm="confirmMerType" <nut-picker
@cancel="merType = false"></nut-picker> :columns="merList"
title="商户类型"
@confirm="confirmMerType"
@cancel="merType = false"
></nut-picker>
</nut-popup> </nut-popup>
</nut-form-item> </nut-form-item>
<nut-form-item required label="经营类目" prop="merGooTypeStr" :rules="[{ <nut-form-item
required
label="经营类目"
prop="merGooTypeStr"
:rules="[
{
required: true, required: true,
message: '请选择经营类目', message: '请选择经营类目',
}]"> },
<input type="text" :disabled="true" v-model="formValue.merGooTypeStr" placeholder="请选择经营类目" ]"
@click="merGooType = true"/> >
<input
type="text"
:disabled="true"
v-model="formValue.merGooTypeStr"
placeholder="请选择经营类目"
@click="merGooType = true"
/>
<nut-popup position="bottom" v-model:visible="merGooType"> <nut-popup position="bottom" v-model:visible="merGooType">
<nut-picker :columns="merGooList" title="商户类型" @confirm="confirmGooType" <nut-picker
@cancel="merGooType = false"></nut-picker> :columns="merGooList"
title="商户类型"
@confirm="confirmGooType"
@cancel="merGooType = false"
></nut-picker>
</nut-popup> </nut-popup>
</nut-form-item> </nut-form-item>
<!-- <nut-form-item label="资质上传" prop="img">--> <nut-form-item
<!-- <nut-uploader url="www.baidu.com"></nut-uploader>--> required
<!-- </nut-form-item>--> label="营业执照"
prop="license"
:rules="[
{
required: true,
message: '请上传营业执照',
validator: (value) => {
return value.length > 0;
},
},
]"
>
<Upload v-model:list="formValue.license" />
</nut-form-item>
<nut-form-item
required
label="法人身份证(正面)"
prop="front"
:rules="[
{
required: true,
message: '法人身份证(正面)',
validator: (value) => {
return value.length > 0;
},
},
]"
>
<Upload v-model:list="formValue.front" />
</nut-form-item>
<nut-form-item
required
label="法人身份证(反面)"
prop="back"
:rules="[
{
required: true,
message: '法人身份证(反面)',
validator: (value) => {
return value.length > 0;
},
},
]"
>
<Upload v-model:list="formValue.back" />
</nut-form-item>
<nut-form-item
required
label="门头照"
prop="head_photo"
:rules="[
{
required: true,
message: '请上传门头照',
validator: (value) => {
return value.length > 0;
},
},
]"
>
<Upload v-model:list="formValue.head_photo" />
</nut-form-item>
<nut-form-item
required
label="店内照"
prop="img"
:rules="[
{
required: true,
message: '请上传店内照至少3张',
validator: (value) => {
return value.length >= 3;
},
},
]"
>
<Upload v-model:list="formValue.img" :max="5" />
</nut-form-item>
<view class="btn"> <view class="btn">
<nut-button block type="primary" round @click="submit()">提交</nut-button> <nut-button block type="primary" round @click="submit()"
>提交</nut-button
>
</view> </view>
</nut-form> </nut-form>
<!-- 入驻协议弹窗 --> <!-- 入驻协议弹窗 -->
<nut-dialog <nut-dialog
@@ -226,14 +401,15 @@ const submit = () => {
page { page {
background-image: url("~@/static/merchantBg.jpg"); background-image: url("~@/static/merchantBg.jpg");
background-size: 100%; background-size: 100%;
background-color: #E93423; background-color: #e93423;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
.form { .form {
position: relative; position: relative;
top: 300px; top: 200px;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.btn { .btn {
padding: 20px; padding: 20px;

View File

@@ -1,55 +1,155 @@
<script lang="ts" setup> <script lang="ts" setup>
import Taro from '@tarojs/taro' import Taro from "@tarojs/taro";
import { ref } from "vue";
import { getPersonalInfo, editPersonalInfo, getPhone } from "@/api/user";
import { View } from "@tarojs/components";
import { BASE_URL } from "@/utils/request";
const toPage = (e: string) => { // const toPage = (e: string) => {};
}
const userInfo = ref<any>({});
Taro.useLoad(() => {
const data = Taro.getStorageSync("userInfo");
userInfo.value = data;
});
const logOut = () => { const logOut = () => {
Taro.showModal({ Taro.showModal({
title: '提示', title: "提示",
content: '确定退出登录吗?', content: "确定退出登录吗?",
success: function (res) { success: function (res) {
if (res.confirm) { if (res.confirm) {
Taro.removeStorageSync('token') Taro.removeStorageSync("token");
Taro.removeStorageSync('userInfo') Taro.removeStorageSync("userInfo");
Taro.reLaunch({ Taro.reLaunch({
url: '/pages/index/index' url: "/pages/index/index",
}) });
} else if (res.cancel) { } else if (res.cancel) {
console.log('用户点击取消') console.log("用户点击取消");
}
}
})
} }
},
});
};
const chooseavatar = (e: any) => {
Taro.uploadFile({
url: `${BASE_URL}/app/upload`,
filePath: e.detail.avatarUrl,
name: "file",
header: {
token: Taro.getStorageSync("token"),
},
success: function (res) {
const data = JSON.parse(res.data);
userInfo.value.avatarUrl = data.data.data;
},
});
};
const subUser = async () => {
try {
const reg =
/^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/;
if (!reg.test(userInfo.value.phone))
return Taro.showToast({
title: "请输入正确的手机号码",
icon: "none",
});
const res = await editPersonalInfo(userInfo.value);
Taro.showToast({
title: res.msg,
icon: "none",
});
Taro.switchTab({
url: "/pages/user/index",
});
} catch (error) {
Taro.showToast({
title: error.msg,
icon: "none",
});
}
};
const getUserInfo = async () => {
try {
const res = await getPersonalInfo();
userInfo.value = res.data.data;
} catch (error) {
Taro.showToast({
title: error.msg,
icon: "none",
});
}
};
</script> </script>
<template> <template>
<view class="app"> <view class="app">
<view class="user-card"> <view class="user-card">
<view>管理我的账号</view> <view>管理我的账号</view>
<!-- {{ userInfo }} -->
<view class="avatar-card"> <view class="avatar-card">
<view class="left"> <view class="left">
<nut-button
open-type="chooseAvatar"
@chooseavatar="chooseavatar"
>
<nut-avatar size="large"> <nut-avatar size="large">
<img <img
src="https://img12.360buyimg.com/imagetools/jfs/t1/196430/38/8105/14329/60c806a4Ed506298a/e6de9fb7b8490f38.png" style="border-radius: 50%"
:src="userInfo.avatarUrl"
/> />
</nut-avatar> </nut-avatar>
<view class="name">微信用户</view> </nut-button>
<view class="name">{{ userInfo.nickName }}</view>
</view> </view>
</view> </view>
</view> </view>
<nut-cell-group> <nut-cell-group>
<nut-cell title="昵称" desc="微信用户" is-link></nut-cell> <!-- :desc="userInfo.nickName" -->
<nut-cell title="ID" desc="1" is-link></nut-cell> <nut-cell title="昵称">
<nut-cell title="手机号码" desc="18888888888" is-link></nut-cell> <template v-slot:link>
<nut-cell title="登录密码" desc="修改登录密码" is-link></nut-cell> <nut-input
<nut-cell title="注销账号" desc="账号注销后不能恢复" is-link></nut-cell> v-model="userInfo.nickName"
:border="false"
input-align="right"
placeholder="请输入昵称"
/> </template
></nut-cell>
<nut-cell title="手机号码">
<template v-slot:link>
<nut-input
v-model="userInfo.phone"
:border="false"
input-align="right"
disabled
/>
</template>
</nut-cell>
<nut-cell title="登录密码">
<template v-slot:link>
<nut-input
v-model="userInfo.password"
:border="false"
input-align="right"
placeholder="修改登录密码"
/>
</template>
</nut-cell>
<nut-cell title="注销账号" desc="账号注销后不能恢复" is-link>
</nut-cell>
</nut-cell-group> </nut-cell-group>
<view class="btn"> <view class="btn">
<nut-button block type="primary" @click="logOut">退出登录</nut-button> <nut-button block @click="subUser">保存信息</nut-button>
</view>
<view class="btn">
<nut-button block type="primary" @click="logOut"
>退出登录</nut-button
>
</view> </view>
</view> </view>
</template> </template>
@@ -83,12 +183,36 @@ const logOut = () => {
.name { .name {
margin-left: 10px; margin-left: 10px;
} }
.nut-button {
margin: 0 auto;
width: 125px;
height: 125px;
border-radius: 50%;
}
} }
} }
} }
.btn { .btn {
padding: 0 40px; padding: 0 40px;
margin-bottom: 20px;
} }
.nut-input {
width: 400px !important;
padding: 0 !important;
}
.nut-cell {
display: flex;
align-items: center;
}
.phoneBtn {
padding: 0 !important;
margin: 0 !important;
border-radius: 0 !important;
background-color: transparent !important;
border: none !important;
}
</style> </style>

BIN
src/static/user/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/static/user/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
src/static/user/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/static/user/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,6 +1,9 @@
import Taro from '@tarojs/taro' import Taro from "@tarojs/taro";
const BASE_URL = process.env.NODE_ENV === 'development' ? 'http://192.168.2.3:9000' : 'https://www.wanzhuanyongcheng.cn' export const BASE_URL =
process.env.NODE_ENV === "development"
? "http://192.168.2.3:9000/app"
: "https://www.wanzhuanyongcheng.cn/app";
interface Res<T> { interface Res<T> {
code: number; code: number;
@@ -8,41 +11,47 @@ interface Res<T> {
msg: string; msg: string;
} }
type Method = 'GET' | 'POST' | 'PUT' | 'DELETE'; type Method = "GET" | "POST" | "PUT" | "DELETE";
const request = ( const request = (
url: string, url: string,
data: object = {}, data: object = {},
method: Method = 'GET' method: Method = "GET"
): Promise<Res<any>> => { ): Promise<Res<any>> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Taro.showLoading({ Taro.showLoading({
title: '加载中...', title: "加载中...",
mask: true mask: true,
}) });
Taro.request({ Taro.request({
url: BASE_URL + '/app' + url, url: BASE_URL + url,
data: data, data: data,
method: method, method: method,
header: { header: {
'content-type': 'application/json', "content-type": "application/json",
token: Taro.getStorageSync('token') token: Taro.getStorageSync("token"),
}, },
success: ({ data }) => { success: ({ data }) => {
Taro.hideLoading() Taro.hideLoading();
if (data.code !== 200) if (data.code !== 200) {
return reject({code: 1, msg: data.msg}) Taro.showToast({
resolve(data) title: data.msg,
icon: "none",
});
reject(data);
return;
}
resolve(data);
}, },
fail: () => { fail: () => {
Taro.showToast({ Taro.showToast({
title: '服务器异常', title: "服务器异常",
icon: 'none' icon: "none",
}) });
reject({code: 1, msg: '服务器异常'}) reject({ code: 1, msg: "服务器异常" });
} },
}) });
}) });
} };
export default request export default request;