完成确认订单页面,修改小组件目录

This commit is contained in:
TOP糯米 2023-02-12 23:14:02 +08:00
parent e2da64a9f0
commit 229c56de6a
20 changed files with 717 additions and 107 deletions

View File

@ -0,0 +1,67 @@
<template>
<view class="agreement">
<widget-check-box :checked="defaultState" @change="change" />
<view class="description">
<text class="text">我已阅读并同意</text>
<text class="link">熊熊安装服务协议</text>
<text class="link">隐私政策</text>
</view>
</view>
</template>
<script>
import WidgetCheckBox from "@/components/widgets/checkbox";
export default {
name: "auth-agreement",
data() {
return {};
},
props: {
defaultState: {
type: Boolean,
default: false,
},
},
components: {
WidgetCheckBox,
},
created() {},
mounted() {},
destroyed() {},
methods: {
change(state) {
this.$emit("agree", state);
},
},
};
</script>
<style lang="less" scoped>
.agreement {
width: 100%;
display: flex;
align-items: flex-start;
line-height: 40rpx;
.icon-box {
.iconfont {
color: #c7c7c7;
font-size: 40rpx;
}
}
.icon-box.active {
.iconfont {
color: #8194f2;
}
}
.description {
font-size: 22rpx;
margin-left: 10rpx;
.text {
color: #333333;
}
.link {
color: #8194f2;
}
}
}
</style>

View File

@ -11,7 +11,11 @@
>
<swiper-item v-for="(item, index) in list" :key="index">
<view class="swiper-item" @click="clickItem(item)">
<image class="banner-image" :src="item.image" mode="scaleToFill" />
<image
class="banner-image"
:src="item.image"
mode="scaleToFill"
/>
</view>
</swiper-item>
</swiper>
@ -20,7 +24,7 @@
class="swiper-dot-item"
v-for="(value, key) in list.length"
:key="key"
:class="{'active': key === currentIndex}"
:class="{ active: key === currentIndex }"
></view>
</view>
</view>

View File

@ -39,16 +39,14 @@
:style="{
height:
index == data.length - 1
? cateType == 'cate'
? 'calc(100vh - 70rpx)'
: '100vh'
? wrapHeight + $utils.rpx2px(110) + 'px'
: 'auto',
}"
>
<cate-tmpl
v-if="cateType === 'cate'"
:data="item"
@clickCate="clickCate"
@clickItem="clickItem"
></cate-tmpl>
<list-tmpl
v-if="cateType === 'list'"
@ -124,6 +122,7 @@ export default {
// H5tabbar
this.wrapHeight -= this.$utils.rpx2px(100);
// #endif
// this.switchCate(5);
},
destroyed() {},
methods: {
@ -255,8 +254,14 @@ export default {
}
}
},
clickCate(id) {
this.$emit("clickCate", id);
switchCate(id) {
let idx = 0;
this.data.forEach((item, index) => {
if (item.id == id) {
idx = index;
}
});
this.swichMenu(idx);
},
clickItem(id) {
this.$emit("clickItem", id);

View File

@ -8,7 +8,7 @@
class="thumb-box"
v-for="(child, index1) in data.child"
:key="index1"
@click="clickItem(child.id, child.name)"
@click="clickItem(child.id)"
>
<image
class="item-menu-image"
@ -38,8 +38,8 @@ export default {
mounted() {},
destroyed() {},
methods: {
clickItem(id, name) {
this.$emit("clickCate", id);
clickItem(id) {
this.$emit("clickItem", id);
},
},
};
@ -48,6 +48,7 @@ export default {
<style lang="less" scoped>
.item-title {
font-size: 26rpx;
line-height: 26rpx;
color: #010101;
font-weight: bold;
}

View File

@ -9,27 +9,16 @@
v-for="(child, index1) in data.child"
:key="index1"
>
<image
class="cover-image"
mode="aspectFill"
:src="child.icon"
@click="clickItem(child.id, child.name)"
></image>
<view class="item-box" @click="clickItem(child.id, child.name)">
<view class="title">{{ child.name }}</view>
<view class="text-box">
{{ "已服务113256次" }}
</view>
<view class="price">158元起</view>
</view>
<mini-add class="component-add" :initNumber="child.buyNumber" />
<service-preview-item :data="child" @clickItem="clickItem" />
<widget-count-modify class="component-add" :initNumber="child.buyNumber" />
</view>
</view>
</view>
</template>
<script>
import MiniAdd from "@/components/mini/add";
import WidgetCountModify from "@/components/widgets/count-modify";
import ServicePreviewItem from "@/components/service/preview-item";
export default {
name: "component-cate-template-list",
data() {
@ -41,12 +30,15 @@ export default {
default: [],
},
},
components: { MiniAdd },
components: {
WidgetCountModify,
ServicePreviewItem,
},
created() {},
mounted() {},
destroyed() {},
methods: {
clickItem(id, name) {
clickItem(id) {
this.$emit("clickItem", id);
},
},
@ -56,6 +48,7 @@ export default {
<style lang="less" scoped>
.item-title {
font-size: 26rpx;
line-height: 26rpx;
color: #8b8b8b;
font-weight: bold;
}
@ -66,10 +59,8 @@ export default {
.thumb-box {
position: relative;
width: 100%;
display: flex;
justify-content: space-between;
margin-top: 40rpx;
.component-add {
position: absolute;
right: 0;
@ -79,32 +70,4 @@ export default {
.thumb-box:nth-child(3n) {
margin-right: 0;
}
.cover-image {
width: 130rpx;
height: 130rpx;
box-sizing: border-box;
border-radius: 20rpx;
border: 2rpx solid #d8d8d8;
}
.item-box {
width: 300rpx;
display: flex;
justify-content: space-between;
flex-direction: column;
padding-left: 50rpx;
.title {
font-size: 26rpx;
font-weight: bold;
color: #010101;
}
.text-box {
display: inline-block;
font-size: 22rpx;
color: #333333;
}
.price {
font-size: 30rpx;
color: #ec7655;
}
}
</style>

View File

@ -1,12 +1,15 @@
<template>
<view class="page-layout" :style="{ backgroundColor: pageBackgroundColor }">
<view
class="page-layout"
:style="{ backgroundColor: backgroundColor, minHeight: minHeight }"
>
<view
class="page-header"
:class="[textColor]"
:style="{
height: header.height + 'px',
paddingTop: header.pt + 'px',
backgroundColor: backgroundColor,
backgroundColor: headerBackgroundColor,
}"
>
<!-- 首页选择地址 -->
@ -60,7 +63,15 @@ export default {
},
components: {},
props: {
pageBackgroundColor: {
minHeight: {
type: String,
default: "100vh",
},
backgroundColor: {
type: String,
default: "unset",
},
headerBackgroundColor: {
type: String,
default: "unset",
},
@ -80,10 +91,6 @@ export default {
type: String,
default: "dark",
},
backgroundColor: {
type: String,
default: "unset",
},
},
computed: {
...mapState({

View File

@ -0,0 +1,79 @@
<template>
<view>
<view class="preview-item">
<image
class="cover-image"
mode="aspectFill"
:src="data.icon"
@click="clickItem(data.id)"
></image>
<view class="item-box" @click="clickItem(data.id)">
<view class="title">{{ data.name }}</view>
<view class="text-box">
{{ "已服务113256次" }}
</view>
<view class="price">¥158元起</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "service-preview-item",
data() {
return {};
},
props: {
data: {
type: Object,
default: () => {},
},
},
components: {},
created() {},
mounted() {},
destroyed() {},
methods: {
clickItem(id) {
this.$emit("clickItem", id);
},
},
};
</script>
<style lang="less" scoped>
.preview-item {
width: 100%;
display: flex;
justify-content: flex-start;
}
.cover-image {
width: 130rpx;
height: 130rpx;
box-sizing: border-box;
border-radius: 20rpx;
border: 2rpx solid #d8d8d8;
}
.item-box {
width: 306rpx;
display: flex;
justify-content: space-between;
flex-direction: column;
padding-left: 50rpx;
.title {
font-size: 26rpx;
font-weight: bold;
color: #010101;
}
.text-box {
display: inline-block;
font-size: 22rpx;
color: #333333;
}
.price {
font-size: 30rpx;
color: #ec7655;
}
}
</style>

View File

@ -0,0 +1,57 @@
<template>
<view
class="checkbox"
:class="[state ? 'active' : '']"
:style="{ fontSize: $utils.rpx2px(size) + 'px' }"
@click="changeCheckBox"
>
<text v-if="state" class="iconfont icon-xuanzeyixuanze"></text>
<text v-if="!state" class="iconfont icon-xuanzeweixuanze"></text>
</view>
</template>
<script>
export default {
name: "widget-checkbox",
data() {
return {
state: false,
};
},
props: {
size: {
type: Number,
default: 40,
},
checked: {
type: Boolean,
default: false,
},
},
components: {},
created() {
this.state = this.checked;
},
mounted() {},
destroyed() {},
methods: {
changeCheckBox() {
this.state = !this.state;
this.$emit("change", this.state);
},
},
};
</script>
<style lang="less" scoped>
.checkbox {
.iconfont {
color: #c7c7c7;
}
}
.checkbox.active {
.iconfont {
color: #8194f2;
}
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<view class="mini-add" :class="[number > 0 ? 'between' : 'end']">
<view class="count-modify" :class="[number > 0 ? 'between' : 'end']">
<view v-if="number > 0" class="btn sub" @click="sub">
<text class="iconfont icon-jianhao"></text>
</view>
@ -12,7 +12,7 @@
<script>
export default {
name: "mini-add",
name: "widget-count-modify",
data() {
return {
number: 0,
@ -21,12 +21,12 @@ export default {
props: {
initNumber: {
type: Number,
default: 0
default: 0,
},
data: {
type: Object,
default: () => {}
}
default: () => {},
},
},
components: {},
created() {
@ -41,31 +41,31 @@ export default {
} else {
this.number = 0;
}
this.$emit('onSub', this.data, this.number);
this.$emit("onSub", this.data, this.number);
},
add() {
this.number++;
this.$emit('onAdd', this.data, this.number);
}
this.$emit("onAdd", this.data, this.number);
},
},
};
</script>
<style lang="less" scoped>
.mini-add {
.count-modify {
width: 130rpx;
height: 35rpx;
display: flex;
align-items: center;
.num {
color: #2D2D2D;
color: #2d2d2d;
font-size: 30rpx;
}
}
.mini-add.between {
.count-modify.between {
justify-content: space-between;
}
.mini-add.end {
.count-modify.end {
justify-content: flex-end;
}
.btn.sub .iconfont,

View File

@ -0,0 +1,54 @@
<template>
<view
class="switch"
:class="[state ? 'active' : '']"
:style="{ fontSize: $utils.rpx2px(size) + 'px' }"
@click="changeSwitch"
>
<text v-if="!state" class="iconfont icon-kaiguan-guan"></text>
<text v-if="state" class="iconfont icon-kaiguan-kai"></text>
</view>
</template>
<script>
export default {
name: "widget-switch",
data() {
return {
state: false,
};
},
props: {
size: {
type: Number,
default: 34,
},
open: {
type: Boolean,
default: false,
},
},
components: {},
created() {
this.state = this.open;
},
mounted() {},
destroyed() {},
methods: {
changeSwitch() {
this.state = !this.state;
this.$emit("change", this.state);
},
},
};
</script>
<style lang="less" scoped>
.switch {
font-size: 35rpx;
color: #c7c7c7;
}
.switch.active {
color: #8194f2;
}
</style>

View File

@ -145,12 +145,14 @@ function debounce(func, wait = 500, immediate = false) {
}
function px2rpx(px) {
const { windowWidth } = uni.getStorageSync('system_config');
let { windowWidth } = uni.getStorageSync('system_config');
windowWidth = (windowWidth > 750) ? 750 : windowWidth;
return 750 * (px / windowWidth);
}
function rpx2px(rpx) {
const { windowWidth } = uni.getStorageSync('system_config');
let { windowWidth } = uni.getStorageSync('system_config');
windowWidth = (windowWidth > 750) ? 750 : windowWidth;
return (rpx / 750) * windowWidth;
}

View File

@ -1,7 +1,5 @@
<template>
<app-layout backgroundColor="#00418c" textColor="light">
<view class="body">登录</view>
</app-layout>
<app-layout headerBackgroundColor="#00418c" textColor="light"> </app-layout>
</template>
<script>
@ -11,7 +9,9 @@ export default {
data() {
return {};
},
components: { AppLayout },
components: {
AppLayout,
},
onLoad() {},
onShow() {},
onReady() {},

View File

@ -1,5 +1,5 @@
<template>
<app-layout backgroundColor="#4B65ED" textColor="light" btnType="city" title="熊熊安装队">
<app-layout headerBackgroundColor="#4B65ED" textColor="light" btnType="city" title="熊熊安装队">
<view class="search">
<view class="input-box">
<view class="icon">

View File

@ -1,7 +1,5 @@
<template>
<app-layout backgroundColor="#00418c" textColor="light">
</app-layout>
<app-layout headerBackgroundColor="#00418c" textColor="light"> </app-layout>
</template>
<script>
@ -11,7 +9,9 @@ export default {
data() {
return {};
},
components: { AppLayout },
components: {
AppLayout,
},
onLoad() {},
onShow() {},
onReady() {},

View File

@ -1,5 +1,5 @@
<template>
<app-layout backgroundColor="#f00" textColor="light">个人中心</app-layout>
<app-layout headerBackgroundColor="#f00" textColor="light"> </app-layout>
</template>
<script>
@ -10,7 +10,9 @@ export default {
data() {
return {};
},
components: { AppLayout },
components: {
AppLayout,
},
computed: {
...mapState("user", {
userInfo: (state) => state.userInfo,

26
src/pages/order/cart.vue Normal file
View File

@ -0,0 +1,26 @@
<template>
<app-layout headerBackgroundColor="#00418c" textColor="light">
购物车
</app-layout>
</template>
<script>
import AppLayout from "@/components/layout/layout";
export default {
name: "order-cart",
data() {
return {};
},
components: {
AppLayout,
},
onLoad() {},
onShow() {},
onReady() {},
onReachBottom() {},
onPullDownRefresh() {},
methods: {},
};
</script>
<style lang="less" scoped></style>

View File

@ -1,27 +1,348 @@
<template>
<app-layout backgroundColor="#00418c" title="确认订单" textColor="light">
<app-layout
headerBackgroundColor="#F6F6F6"
title="确认订单"
textColor="dark"
backgroundColor="#F6F6F6"
>
<view class="tips">
<text class="iconfont icon-tixing"></text>
<text class="text-container">
保险公司承保人身财产双重保障下单无忧
</text>
</view>
<view class="form-container">
<view class="select-group">
<view class="select-item address" @click="selectAddress">
<text class="iconfont icon-dingwei"></text>
<text class="text limit-line clamp-1">{{
addressText ? addressText : "请选择上门地址"
}}</text>
<text class="iconfont icon-jinru"></text>
</view>
<view class="select-item datetime" @click="selectDateTime">
<text class="iconfont icon-shijian"></text>
<picker
mode="date"
:value="datetime"
@change="bindDateChange"
class="text"
>
<view class="uni-input">{{
datetime ? datetime : "选择期望上门时间"
}}</view>
</picker>
<text class="iconfont icon-jinru"></text>
</view>
</view>
<view class="service-view">
<service-preview-item
class="service-item"
v-for="(item, idx) in serviceList"
:key="idx"
:data="item"
/>
</view>
<view class="insurance">
<view class="title-box">
<view class="title" @click="insuranceModal">
<text class="text">意外保</text>
<text class="iconfont icon-shuoming"></text>
</view>
<text class="desc">全面保证您的人身财产安全</text>
</view>
<view class="switch-container">
<text class="price">¥ 6.00</text>
<widget-switch @change="changeInsurance" />
</view>
</view>
<view class="demand">
<text class="title">留言</text>
<textarea
class="text-area"
v-model="message"
placeholder="补充描述您的需求,或其他特殊情况"
placeholder-class="textarea-placeholder"
/>
</view>
<view class="agreement-container">
<agreement @agree="agree" />
</view>
</view>
<view
class="pay-component"
:style="{ bottom: config.safeAreaInsets.bottom + 'px' }"
>
<text class="price">¥306.00</text>
<view class="pay" @click="pay">
<div class="text">去支付</div>
</view>
</view>
</app-layout>
</template>
<script>
import AppLayout from "@/components/layout/layout";
import ServicePreviewItem from "@/components/service/preview-item";
import Agreement from "@/components/auth/agreement";
import WidgetSwitch from "@/components/widgets/switch";
import { mapState } from "vuex";
export default {
name: "order-create",
data() {
return {};
return {
addressId: 0,
addressText: "",
datetime: "",
insurance: false,
message: "",
isAgree: false,
serviceList: [
{
id: 2,
name: "空调安装",
icon: require("@/static/temp/cate/1.png"),
buyNumber: 1,
},
{
id: 3,
name: "空调拆卸",
icon: require("@/static/temp/cate/2.png"),
buyNumber: 1,
},
],
};
},
components: {
AppLayout,
ServicePreviewItem,
Agreement,
WidgetSwitch,
},
computed: {
...mapState({
config: (state) => state.system.config,
}),
},
components: { AppLayout },
onLoad() {},
onShow() {},
onReady() {},
onReachBottom() {},
onPullDownRefresh() {},
methods: {},
methods: {
bindDateChange(e) {
this.datetime = e.detail.value;
},
selectAddress() {
console.log("选择地址");
},
selectDateTime() {
console.log("选择时间");
},
insuranceModal() {
uni.showModal({
title: "什么是意外保?",
content:
"意外保是中国人寿的保险产品,全面保证您的人身财产安全。",
showCancel: false,
});
},
changeInsurance(state) {
this.insurance = state;
console.log(this.insurance);
},
agree(state) {
this.isAgree = state;
console.log(this.isAgree);
},
pay() {
if (!this.isAgree) {
uni.showToast({
title: "请先阅读并同意《熊熊安装服务协议》《隐私政策》",
icon: "none",
});
return;
}
},
},
};
</script>
<style lang="less" scoped>
.finish {
margin: 20rpx 0;
.tips {
width: 710rpx;
height: 75rpx;
margin: 0 auto;
display: flex;
align-items: center;
background-color: #ffffff;
box-sizing: border-box;
padding: 0 10rpx;
.iconfont {
font-size: 40rpx;
color: #ffa800;
margin-right: 26rpx;
}
.text-container {
color: #a0a0a0;
font-size: 22rpx;
line-height: 22rpx;
}
}
.form-container {
width: 100%;
margin-top: 16rpx;
}
.select-group {
width: 100%;
.select-item {
position: relative;
display: flex;
align-items: center;
background-color: #ffffff;
box-sizing: border-box;
margin-top: 2rpx;
padding: 0 30rpx;
.text {
width: 100%;
height: 116rpx;
line-height: 116rpx;
font-size: 30rpx;
color: #2d2d2d;
padding-left: 26rpx;
}
}
.select-item:first-child {
margin-top: 0;
}
.iconfont.icon-dingwei,
.iconfont.icon-shijian {
color: #8194f2;
}
.iconfont.icon-dingwei {
font-size: 44rpx;
}
.iconfont.icon-shijian {
font-size: 40rpx;
}
.iconfont.icon-jinru {
font-size: 37rpx;
color: #a7a7a7;
}
}
.service-view {
margin-top: 16rpx;
padding: 24rpx 40rpx;
background-color: #ffffff;
.service-item {
display: block;
margin-top: 28rpx;
}
.service-item:first-child {
margin-top: 0;
}
}
.insurance {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 38rpx 40rpx;
background-color: #ffffff;
border-top: 2rpx solid #e8e7e7;
.title-box {
.title {
font-size: 30rpx;
line-height: 30rpx;
.text {
font-weight: bold;
color: #010101;
}
.iconfont {
color: #8194f2;
margin-left: 8rpx;
}
}
.desc {
display: inline-block;
line-height: 22rpx;
font-size: 22rpx;
color: #333333;
margin-top: 16rpx;
}
}
.switch-container {
display: flex;
line-height: 100%;
.price {
font-size: 30rpx;
color: #ec7655;
margin-right: 38rpx;
}
}
}
.demand {
width: 100%;
box-sizing: border-box;
padding: 38rpx 40rpx;
.title {
font-size: 30rpx;
font-weight: bold;
color: #010101;
}
.text-area {
width: 100%;
height: 130rpx;
box-sizing: border-box;
background-color: #ffffff;
padding: 24rpx;
font-size: 26rpx;
color: #333333;
margin-top: 12rpx;
border-radius: 10rpx;
}
.textarea-placeholder {
color: #909090;
}
}
.agreement-container {
width: 100%;
box-sizing: border-box;
padding: 0 40rpx 40rpx 40rpx;
}
.pay-component {
position: fixed;
left: 0;
right: 0;
bottom: 0;
max-width: 750px;
width: 100%;
height: 100rpx;
margin: 0 auto;
background-color: #ffffff;
box-sizing: border-box;
padding: 0 40rpx;
display: flex;
align-items: center;
justify-content: space-between;
.price {
font-size: 42rpx;
font-weight: bold;
color: #ec7655;
}
.pay {
width: 223rpx;
height: 71rpx;
background: #8194f2;
border-radius: 31rpx;
text-align: center;
.text {
line-height: 71rpx;
font-size: 32rpx;
font-weight: bold;
color: #ffffff;
}
}
}
</style>

View File

@ -1,5 +1,11 @@
<template>
<app-layout btnType="unset" title="分类" pageBackgroundColor="#F6F6F6" backgroundColor="#F6F6F6">
<app-layout
minHeight="unset"
btnType="unset"
title="分类"
backgroundColor="#F6F6F6"
headerBackgroundColor="#F6F6F6"
>
<view class="search">
<view class="input-box">
<view class="icon">
@ -19,7 +25,7 @@
:offsetHeight="95"
:data="data"
cateType="cate"
@clickCate="clickCate"
@clickItem="clickItem"
/>
</view>
</app-layout>
@ -96,7 +102,7 @@ export default {
onReachBottom() {},
onPullDownRefresh() {},
methods: {
clickCate(id) {
clickItem(id) {
uni.navigateTo({
url: "/pages/service/list?id=" + id,
});

View File

@ -1,9 +1,9 @@
<template>
<app-layout
backgroundColor="#F6F6F6"
headerBackgroundColor="#F6F6F6"
:title="pageTitle"
textColor="dark"
pageBackgroundColor="#F6F6F6"
backgroundColor="#F6F6F6"
>
<view class="service-header">
<view
@ -94,7 +94,7 @@
:style="{ bottom: config.safeAreaInsets.bottom + 'px' }"
>
<view class="price">
<text class="text">306.00</text>
<text class="text">¥306.00</text>
</view>
<view class="btn-group">
<view class="cart">
@ -132,7 +132,9 @@ export default {
},
};
},
components: { AppLayout },
components: {
AppLayout,
},
computed: {
...mapState({
config: (state) => state.system.config,

View File

@ -1,5 +1,11 @@
<template>
<app-layout btnType="back" title="服务列表" backgroundColor="#FFFFFF" pageBackgroundColor="#FFFFFF">
<app-layout
minHeight="unset"
btnType="back"
title="服务列表"
headerBackgroundColor="#FFFFFF"
backgroundColor="#FFFFFF"
>
<view class="cate">
<app-cate
:offsetHeight="0"
@ -20,7 +26,7 @@
<text class="text">99</text>
</view>
</view>
<view class="order-btn">
<view class="order-btn" @click="createOrder">
<text class="text">去下单</text>
</view>
</view>
@ -96,7 +102,10 @@ export default {
bottom: 0,
};
},
components: { AppLayout, AppCate },
components: {
AppLayout,
AppCate,
},
computed: {
...mapState({
config: (state) => state.system.config,
@ -108,6 +117,11 @@ export default {
onReachBottom() {},
onPullDownRefresh() {},
methods: {
createOrder() {
uni.navigateTo({
url: "/pages/order/create",
});
},
clickItem(id) {
uni.navigateTo({
url: "/pages/service/detail?id=" + id,