源文件
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<view class="b-wrapper" :class="[buttonSize()]" :style="{ paddingBottom: bottom, marginTop: pdTop, padding: pd }">
|
||||
<view
|
||||
@tap.stop="handleTap"
|
||||
class="b-main"
|
||||
:style="{
|
||||
color: color,
|
||||
backgroundColor: bgColor,
|
||||
}"
|
||||
hover-class="u-cell-hover"
|
||||
hover-stay-time="150"
|
||||
>
|
||||
<slot>登录</slot>
|
||||
</view>
|
||||
</view>
|
||||
<view :style="{ height }" v-if="height"></view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive } from "vue"
|
||||
|
||||
const props = defineProps({
|
||||
color: {
|
||||
type: String,
|
||||
default: "#fff",
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: "$primaryColor",
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
bottom: {
|
||||
type: String,
|
||||
default: "75rpx",
|
||||
},
|
||||
pdTop: {
|
||||
type: String,
|
||||
default: "30rpx",
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
pd: {
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
const size = reactive({
|
||||
medium: "medium",
|
||||
max: "max",
|
||||
})
|
||||
const buttonSize = () => {
|
||||
return size[props.size]
|
||||
}
|
||||
const emits = defineEmits(["HandleTouch"])
|
||||
const handleTap = () => {
|
||||
emits("HandleTouch")
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.b-wrapper {
|
||||
padding: 50rpx;
|
||||
.b-main {
|
||||
position: relative;
|
||||
font-size: 33rpx;
|
||||
height: 110rpx;
|
||||
background-color: $primaryColor;
|
||||
border-radius: 20rpx;
|
||||
outline: 0;
|
||||
border: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 33rpx;
|
||||
}
|
||||
|
||||
.u-cell-hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
.max {
|
||||
padding: 50rpx;
|
||||
}
|
||||
.medium {
|
||||
padding: 0 50rpx 50rpx 50rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<JMainCard pd="30rpx" wrapPd="0 30rpx">
|
||||
<view class="card-title" @tap="confirm"> {{ title }} </view>
|
||||
<view class="card-content"> <slot /> </view>
|
||||
</JMainCard>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import JMainCard from "@/components/newComponents/JMainCard/JMainCard.vue"
|
||||
|
||||
const emits = defineEmits(["confirm"])
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: "确认退出",
|
||||
},
|
||||
})
|
||||
const confirm = () => {
|
||||
emits("confirm")
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-title {
|
||||
text-align: center;
|
||||
color: #ff4433;
|
||||
}
|
||||
.card-content {
|
||||
padding: 20rpx;
|
||||
margin-top: 30rpx;
|
||||
background-color: #f2f2f2;
|
||||
font-size: 27rpx;
|
||||
line-height: 46rpx;
|
||||
border-radius: 10rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<view class="content-wrapper" :style="{ backgroundColor: bgColor, padding: pd }"><slot /></view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: '#fff'
|
||||
},
|
||||
pd: {
|
||||
type: String,
|
||||
default: '25rpx 50rpx 0 50rpx'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content-wrapper {
|
||||
border-radius: 32rpx 32rpx 0 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<view class="content-wrapper bdR16" :style="{ backgroundColor: bgColor, margin, color }" @tap="taps">
|
||||
<view class="content-left">
|
||||
<image :src="leftImg" mode="scaleToFill" />
|
||||
<view class="content-title"><slot /></view>
|
||||
</view>
|
||||
<view class="content-right">
|
||||
<image src="/static/iconImg/right-arrow.svg" mode="scaleToFill" />
|
||||
</view>
|
||||
</view>
|
||||
<view :style="{ height }" v-if="height != ''"> </view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: '#f7f7f7'
|
||||
},
|
||||
margin: {
|
||||
type: String,
|
||||
default: '30rpx 0 0 0'
|
||||
},
|
||||
leftImg: {
|
||||
type: String,
|
||||
default: '/static/iconImg/notice-img.svg'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
rightImg: {
|
||||
type: String,
|
||||
default: '/static/iconImg/right-arrow.svg'
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#000'
|
||||
}
|
||||
})
|
||||
const emits = defineEmits(['HandleTouch'])
|
||||
const taps = () => {
|
||||
emits('HandleTouch')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content-wrapper {
|
||||
padding: 40rpx 32rpx 40rpx 38rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.content-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 33rpx;
|
||||
color: #666;
|
||||
image {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.content-title {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
.content-right {
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<JPopup ref="popup" @onClose="emits('cancel', 'mask')" @change="change">
|
||||
<JMainCard pd="0" wrapPd="30rpx">
|
||||
<view class="content bgF2 bdR10">{{ text }}</view>
|
||||
<view class="confirm" hover-class="u-cell-hover" hover-stay-time="150" @tap="confirm">确认</view>
|
||||
</JMainCard>
|
||||
<JButton pd="0 30rpx 30rpx 30rpx" pdTop="0" bgColor="#fff" color="#000" @HandleTouch="close()">取消</JButton>
|
||||
</JPopup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, ref } from "vue"
|
||||
import JPopup from "@/components/newComponents/JPopup/JPopup"
|
||||
import JMainCard from "@/components/newComponents/JMainCard/JMainCard"
|
||||
import JButton from "@/components/newComponents/JButton/JButton"
|
||||
const wrapperHidden = inject('wrapperHidden')
|
||||
const emits = defineEmits(["confirm", "cancel"])
|
||||
const text = ref("")
|
||||
const popup = ref()
|
||||
const open = (tips = "确认删除吗?一旦删除不可恢复!!!") => {
|
||||
text.value = tips
|
||||
popup.value.open()
|
||||
}
|
||||
const close = () => {
|
||||
popup.value.close()
|
||||
}
|
||||
const confirm = () => {
|
||||
emits("confirm")
|
||||
popup.value.close()
|
||||
}
|
||||
const change = (e)=>{
|
||||
if(wrapperHidden){
|
||||
wrapperHidden(e.show)
|
||||
}
|
||||
}
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
margin: 30rpx 30rpx 10rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 27rpx;
|
||||
color: #666;
|
||||
}
|
||||
.confirm {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 110rpx;
|
||||
font-size: 33rpx;
|
||||
color: #ff4343;
|
||||
}
|
||||
.u-cell-hover {
|
||||
background-color: rgba($color: #999, $alpha: 0.1);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<view class="equipment-info">
|
||||
<!-- 背景图片 -->
|
||||
<image :src="props.bgImg" class="back-img" />
|
||||
|
||||
<view class="content">
|
||||
<image :src="props.icon" class="code" />
|
||||
|
||||
<view class="name">{{ props.qrcAlias }}</view>
|
||||
<view class="no">{{ props.qrcId }}</view>
|
||||
|
||||
<view class="edit" @tap="edit" v-if="editIsShow">
|
||||
<image src="/static/equipmentImg/edit.svg" />
|
||||
编辑信息
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue"
|
||||
|
||||
const props = defineProps({
|
||||
bgImg: { type: String, default: "" }, // 背景图片
|
||||
icon: { type: String, default: "" }, // 居中的icon
|
||||
qrcAlias: { type: String, default: "" }, // 标题
|
||||
qrcId: { type: String, default: "" }, // iD
|
||||
info: { type: Object, default: () => {} },
|
||||
editIsShow: { type: Boolean, default: true }, // 是否展示编辑按钮
|
||||
})
|
||||
|
||||
const emits = defineEmits(["editInfo"])
|
||||
|
||||
const edit = () => emits("editInfo")
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.equipment-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.back-img {
|
||||
position: absolute;
|
||||
right: -30rpx;
|
||||
top: -20rpx;
|
||||
width: 100%;
|
||||
height: 650rpx;
|
||||
}
|
||||
.content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
.code {
|
||||
margin-top: 70rpx;
|
||||
margin-bottom: 20rpx;
|
||||
width: 93rpx;
|
||||
height: 93rpx;
|
||||
}
|
||||
.name {
|
||||
width: 500rpx;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
line-height: 60rpx;
|
||||
color: #ffffff;
|
||||
font-size: 33rpx;
|
||||
}
|
||||
.no {
|
||||
font-size: 25rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin-top: 12rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.edit {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
padding: 25rpx 42rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-bottom: 50rpx;
|
||||
color: #7737fe;
|
||||
font-size: 28rpx;
|
||||
|
||||
image {
|
||||
width: 26rpx;
|
||||
height: 26rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<view class="equipment-info">
|
||||
<!-- 背景图片 -->
|
||||
<image src="/static/equipmentImg/big-code.svg" class="back-img" />
|
||||
|
||||
<view class="content">
|
||||
<view class="code" @tap="down">
|
||||
<image :src="info.qrcodeUrl" />
|
||||
</view>
|
||||
|
||||
<view class="name">{{ info.qrcAlias ? info.qrcAlias : "未命名" }}</view>
|
||||
<view class="no">{{ info.qrcId }}</view>
|
||||
|
||||
<view class="edit" @tap="edit">
|
||||
<image src="/static/equipmentImg/edit.svg" />
|
||||
编辑信息
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue"
|
||||
|
||||
const vdata = defineProps({
|
||||
info: { type: Object, default: () => {} },
|
||||
})
|
||||
|
||||
const emits = defineEmits(["downUrl", "editInfo"])
|
||||
|
||||
const down = () => emits("downUrl")
|
||||
const edit = () => emits("editInfo")
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.equipment-info {
|
||||
// position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
// overflow: hidden;
|
||||
|
||||
.back-img {
|
||||
position: absolute;
|
||||
right: -30rpx;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 650rpx;
|
||||
}
|
||||
.content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
.code {
|
||||
margin-top: 70rpx;
|
||||
margin-bottom: 20rpx;
|
||||
width: 360rpx;
|
||||
height: 360rpx;
|
||||
border-radius: 20rpx;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
image {
|
||||
width: 300rpx;
|
||||
height: 300rpx;
|
||||
}
|
||||
}
|
||||
.name {
|
||||
width: 500rpx;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
line-height: 60rpx;
|
||||
color: #ffffff;
|
||||
font-size: 33rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.no {
|
||||
font-size: 25rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin-top: 12rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.edit {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
padding: 25rpx 42rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-bottom: 50rpx;
|
||||
color: #7737fe;
|
||||
font-size: 28rpx;
|
||||
|
||||
image {
|
||||
width: 26rpx;
|
||||
height: 26rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<view
|
||||
class="wrapper"
|
||||
:style="{ paddingTop: menu.top + 'px', backgroundColor: bgColor }"
|
||||
:class="{ isPrimary: props.bgColor == '$primaryColor' }"
|
||||
>
|
||||
<!-- #ifdef APP-PLUS || H5 -->
|
||||
<view class="status-bar"> </view>
|
||||
<!-- #endif -->
|
||||
<view
|
||||
class="header-wrapper"
|
||||
:style="{ backgroundColor: bgColor, color: color, height: menu.height + 'px', lineHeight: menu.height + 'px' }"
|
||||
>
|
||||
<view class="header-left" @tap="navBack" v-if="back">
|
||||
<image :src="imgUrl" mode="scaleToFill" />
|
||||
</view>
|
||||
<view class="header-left logo-out" v-if="logOut" @tap="loginOut">
|
||||
<image :src="imgUrl" mode="scaleToFill" />退出登录</view
|
||||
>
|
||||
<view class="header-text">{{ title }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="wrapper-block" :style="{ backgroundColor: bgColor, paddingBottom: pdB }"></view> -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue"
|
||||
import user from "@/hooks/user.js"
|
||||
const props = defineProps({
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: "#fff",
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: "首页",
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "#000",
|
||||
},
|
||||
pdB: {
|
||||
type: String,
|
||||
default: "100rpx",
|
||||
},
|
||||
imgUrl: {
|
||||
type: String,
|
||||
default: "/static/iconImg/left-arrow.svg",
|
||||
},
|
||||
back: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
logOut: { type: Boolean, default: false },
|
||||
})
|
||||
const emits = defineEmits(["back"])
|
||||
let menu = { top: 0, height: "" }
|
||||
// #ifdef MP-WEIXIN
|
||||
menu = uni.getMenuButtonBoundingClientRect()
|
||||
// #endif
|
||||
const navBack = () => {
|
||||
emits("back")
|
||||
uni.navigateBack({
|
||||
fail: (err) => {},
|
||||
})
|
||||
}
|
||||
const loginOut = () => {
|
||||
user.logout()
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "退出成功",
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
position: sticky;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding-bottom: 10rpx;
|
||||
z-index: 50;
|
||||
.status-bar {
|
||||
height: var(--status-bar-height);
|
||||
width: 100%;
|
||||
}
|
||||
.header-wrapper {
|
||||
position: relative;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
.header-left {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 30rpx;
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
transform: translateY(-50%);
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.logo-out {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 150rpx;
|
||||
font-size: 25rpx;
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.wrapper-block {
|
||||
height: var(--status-bar-height);
|
||||
}
|
||||
|
||||
.isPrimary {
|
||||
background: $primaryColor !important;
|
||||
}
|
||||
</style>
|
||||
118
jeepay-ui-uapp-agent/components/newComponents/JInput/JInput.vue
Normal file
118
jeepay-ui-uapp-agent/components/newComponents/JInput/JInput.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<view
|
||||
class="layout"
|
||||
:class="{ first: props.isBorder }"
|
||||
:style="{ padding: props.pd, backgroundColor: props.bgColor, alignItems: align }"
|
||||
>
|
||||
<!-- 最左侧插槽用于存放icon -->
|
||||
<image :src="props.icon" v-if="props.icon" :style="{ width: props.iconSize, height: props.iconSize }" />
|
||||
|
||||
<view class="name" :style="{ color: props.textColor, fontSize: props.size }">{{ props.name }}</view>
|
||||
<view class="input">
|
||||
<slot>
|
||||
<input
|
||||
v-if="props.place != '' || props.value != ''"
|
||||
:type="type"
|
||||
:value="props.value"
|
||||
placeholder-style="color:#A6A6A6;"
|
||||
:placeholder="(rules != null ? '(必填)' : '') + place"
|
||||
:style="{ fontSize: size }"
|
||||
:maxlength="maxlength"
|
||||
@input="onchange"
|
||||
:focus="focus"
|
||||
@focus="emits('focusShow')"
|
||||
@blur="emits('focusNone')"
|
||||
/>
|
||||
<view v-else :style="{ fontSize: props.size, color: props.rightColor }">{{ props.right }}</view>
|
||||
</slot>
|
||||
</view>
|
||||
|
||||
<image src="/static/equipmentImg/arrow.svg" v-if="props.img" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watchEffect, watch, onDeactivated, onBeforeUnmount, onMounted } from "vue"
|
||||
import { addRules, clearOneRule } from "@/hooks/rules"
|
||||
const props = defineProps({
|
||||
name: { type: String, default: "" }, // 左侧文字
|
||||
icon: { type: String, default: "" }, // 左侧图标
|
||||
iconSize: { type: String, default: "40rpx" }, // 左侧图标大小
|
||||
size: { type: String, default: "33rpx" }, // 文字大小
|
||||
right: { type: String, default: "" }, // 右侧文字
|
||||
value: { type: String, default: "" }, // 输入框文字
|
||||
place: { type: String, default: "" }, // 提示文字
|
||||
bgColor: { type: String, default: "" }, // 背景颜色
|
||||
isBorder: { type: Boolean, default: false }, // 是否展示上边框
|
||||
borderBg: { type: String, default: "#f2f2f2" }, // 上边框颜色
|
||||
img: { type: Boolean, default: false }, // 是否展示右箭头
|
||||
pd: { type: String, default: "40rpx 32rpx" },
|
||||
textColor: { type: String, default: "#000" }, // 左侧文字颜色
|
||||
rightColor: { type: String, default: "#fff" }, // 右侧文字颜色
|
||||
size: { type: String, default: "33rpx" }, // 文字大小,
|
||||
type: { type: String, default: "text" }, //输入框类型
|
||||
rules: { default: null },
|
||||
maxlength: { type: Number },
|
||||
align: { type: String }, //对齐方式
|
||||
focus: { type: Boolean, default: false },
|
||||
})
|
||||
const borderColor = ref(props.borderBg)
|
||||
const places = ref("")
|
||||
const emits = defineEmits(["update:value", "focusShow", "focusNone"])
|
||||
const onchange = (e) => emits("update:value", e.detail.value)
|
||||
|
||||
onMounted(() => {
|
||||
if (props.rules !== null) {
|
||||
props.rules.Msg = props.name
|
||||
addRules(props.rules)
|
||||
}
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
if (props.rules !== null) {
|
||||
clearOneRule(props.rules)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
page {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.layout {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
font-size: 33rpx;
|
||||
// line-height: 46rpx;
|
||||
}
|
||||
.input {
|
||||
margin: 0 10rpx 0 20rpx;
|
||||
flex-grow: 1;
|
||||
text-align: right;
|
||||
}
|
||||
image {
|
||||
flex-shrink: 0;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 32rpx;
|
||||
height: 2rpx;
|
||||
width: calc(100% - 32rpx);
|
||||
background-color: v-bind(borderColor);
|
||||
}
|
||||
}
|
||||
.first {
|
||||
&::before {
|
||||
height: 0rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<view class="list-item" :class="{big: props.preBig}">
|
||||
<view class="left">
|
||||
<view class="back" :style="{background: props.bgColor}">
|
||||
<image :src="props.icon" />
|
||||
</view>
|
||||
<view :style="{color: props.leftColor}">{{ props.ifName }}</view>
|
||||
</view>
|
||||
|
||||
<view class="right">
|
||||
<text class="state-color" :style="{background: props.stateColor}"></text>
|
||||
<text class="state-text" :style="{color: props.rightColor}">{{ props.stateText }}</text>
|
||||
<image src="/static/equipmentImg/arrow.svg" style="width:40rpx; height:40rpx;" v-if="isImg" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
const props = defineProps({
|
||||
bgColor: { type: String, default: ''},
|
||||
preBig: { type: Boolean, default: false}, // 预制颜色1
|
||||
icon: { type: String, default: ''},
|
||||
ifName: { type: String, default: ''},
|
||||
stateColor: { type: String, default: ''},
|
||||
stateText: { type: String, default: ''},
|
||||
leftColor: { type: String, default: '#fff'},
|
||||
rightColor: { type: String, default: 'rgba(255, 255, 255, 0.7)'},
|
||||
isImg:{type:Boolean,default:true}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.list-item {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15rpx 0;
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
font-size: 33rpx;
|
||||
}
|
||||
.back {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 5rpx;
|
||||
margin-right: 20rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.state-color {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
.state-text {
|
||||
font-size: 30rpx;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 预制主题1
|
||||
.big {
|
||||
background: rgba(0, 0, 0, 0.03);
|
||||
padding: 30rpx;
|
||||
box-sizing: border-box;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<view class="line" :class="{ 'border-none': props.isBorder }" :style="{ marginLeft: ml, padding: pd }">
|
||||
<image :src="props.iconOn" class="icon" v-if="props.isSelect && iconOn != ''"></image>
|
||||
<image :src="props.iconClose" class="icon" v-else-if="iconOn != ''"></image>
|
||||
<view class="name single-text-beyond" :class="{ color: props.isSelect }">{{ props.name }}</view>
|
||||
<view class="name right-text" :class="{ color: props.isSelect }">
|
||||
{{ text }}
|
||||
<image src="/static/equipmentImg/check.svg" class="select" v-if="props.isSelect"></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue"
|
||||
|
||||
const props = defineProps({
|
||||
iconOn: { type: String, default: "" },
|
||||
iconClose: { type: String, default: "" },
|
||||
name: { type: String, default: "" },
|
||||
isSelect: { type: Boolean, default: false },
|
||||
isBorder: { type: Boolean, default: false },
|
||||
text: { type: String },
|
||||
ml: { type: String },
|
||||
pd: { type: String },
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.line {
|
||||
border-top: 1rpx solid #eee;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 32rpx;
|
||||
box-sizing: border-box;
|
||||
.icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.name {
|
||||
max-width: 300rpx;
|
||||
color: #333333;
|
||||
font-size: 33rpx;
|
||||
line-height: 46rpx;
|
||||
flex-grow: 1;
|
||||
margin: 0 20rpx;
|
||||
}
|
||||
.right-text {
|
||||
text-align: right;
|
||||
}
|
||||
.select {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.color {
|
||||
color: $primaryColor !important;
|
||||
}
|
||||
|
||||
.border-none {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<view class="loading-wrapper" v-if="loadingStatus" @tap="hideLoading"></view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { loadingStatus,hideLoading } from '@/hooks/loading'
|
||||
import { ref } from 'vue'
|
||||
// let loadingStatus = ref(false)
|
||||
// const loadingShow = () => {
|
||||
// loadingStatus.value = true
|
||||
// setTimeout(() => {
|
||||
// console.log('执行')
|
||||
// loadingStatus.value = false
|
||||
// }, 1000)
|
||||
// }
|
||||
// defineExpose({ loadingShow })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.loading-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9999999999;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: $primaryColor;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<view class="card-wrapper" :style="{ padding: wrapPd }" @tap="emits('click')">
|
||||
<view class="card-main bdR20" :style="{ backgroundColor: bgColor, padding: pd }">
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const emits = defineEmits(['click'])
|
||||
const props = defineProps({
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: "#fff",
|
||||
},
|
||||
pd: {
|
||||
type: String,
|
||||
default: "50rpx",
|
||||
},
|
||||
wrapPd: {
|
||||
type: String,
|
||||
default: "50rpx",
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.card-main {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<uni-popup ref="popup" :type="props.dir" :is-mask-click="false" mask-background-color="rgba(0,0,0,0.5)">
|
||||
<view class="Mask" id="msk" :style="{ alignItems: position[type] }" @tap.stop="maskClose($event)">
|
||||
<view class="wrapper" @tap.stop>
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue"
|
||||
const emits = defineEmits(["onClose", "onOpen"])
|
||||
const props = defineProps({
|
||||
dir: {
|
||||
type: String,
|
||||
default: "bottom",
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "bottom",
|
||||
},
|
||||
mask: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
const position = reactive({
|
||||
bottom: "flex-end",
|
||||
top: "flex-start",
|
||||
center: "center",
|
||||
})
|
||||
const popup = ref()
|
||||
const close = () => {
|
||||
emits("onClose")
|
||||
popup.value.close()
|
||||
}
|
||||
const open = () => {
|
||||
emits("onOpen")
|
||||
popup.value.open()
|
||||
}
|
||||
const maskClose = (e) => {
|
||||
if (props.mask) return
|
||||
if (e.target.id === "msk") return close()
|
||||
}
|
||||
|
||||
defineExpose({ open, close })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.Mask {
|
||||
position: relative;
|
||||
z-index: 999999999;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
// background: rgba(0, 0, 0, 0.5);
|
||||
// backdrop-filter: blur(30rpx);
|
||||
.wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,262 @@
|
||||
<template>
|
||||
<view class="pre-wrapper" :class="{ 'preview-two': props.preStyle == 'one', 'preview-one': props.preStyle == 'two' }">
|
||||
<view v-if="activeBox" class="active-box" :class="{ disabled: disabled, active: active }" @tap="emits('activeClick')">
|
||||
<image :src="imageList[disabled ? 0 : 1]" mode="scaleToFill" />
|
||||
</view>
|
||||
<view
|
||||
class="preview-list"
|
||||
:class="{
|
||||
'last-list': isLast,
|
||||
|
||||
'last-none': props.borderNone,
|
||||
}"
|
||||
@tap="emits('click')"
|
||||
>
|
||||
<view class="content-box">
|
||||
<image :src="props.img" class="img" />
|
||||
<view class="content-describe">
|
||||
<text class="title single-text-beyond">{{ props.title }}
|
||||
<slot name="titleTag"/>
|
||||
</text>
|
||||
<text>{{ props.qrcId }}</text>
|
||||
</view>
|
||||
|
||||
<slot>
|
||||
<view class="content-state">
|
||||
<view class="top">
|
||||
<view class="spot" :style="{ backgroundColor: props.spot }"></view>
|
||||
<view class="status">{{ props.status }}</view>
|
||||
</view>
|
||||
<text></text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
|
||||
<!-- 组件下部具名插槽 默认填充内容,图标,描述,号码 -->
|
||||
<slot name="bottom">
|
||||
<view class="info" v-if="mchName || mchNo">
|
||||
<image src="@/static/equipmentImg/mch-little.svg" mode="aspectFit" class="mch-img" />
|
||||
<view class="name">{{ props.mchName }}</view>
|
||||
<view class="number">{{ props.mchNo }}</view>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
/*
|
||||
列表预览组件
|
||||
默认插槽放到最右边
|
||||
具名插槽在下部
|
||||
*/
|
||||
import { ref, reactive, nextTick, watchEffect } from 'vue'
|
||||
const emits = defineEmits(['activeClick', 'click'])
|
||||
const vdata = reactive({
|
||||
infoIsShow: false, // info板块是否展示
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
img: { type: String, default: '/static/equipmentImg/code-open.svg' },
|
||||
title: { type: String, default: '' },
|
||||
qrcId: { type: String, default: '' },
|
||||
spot: { type: String, default: '#fff' },
|
||||
status: { type: String, default: '' },
|
||||
mchName: { type: String, default: '' },
|
||||
mchNo: { type: String, default: '' },
|
||||
isLast: { type: Boolean, default: false }, // 最后一个列表,下划线通底
|
||||
borderNone: { type: Boolean, default: false }, // 最后一个下划线隐藏
|
||||
preStyle: { type: String, default: '' }, // 预制的主题颜色,在最下方
|
||||
disabled: { type: Boolean, default: false }, //是否禁用默认否
|
||||
active: { type: Boolean, default: false }, //是否选中默认未选中
|
||||
activeBox: { type: Boolean, default: false }, // 是否显示 勾选框 默认不显示
|
||||
})
|
||||
|
||||
const imageList = ['/static/iconImg/icon-disabled.svg', '/static/iconImg/icon-active.svg']
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pre-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
.active-box {
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 30rpx;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 6rpx;
|
||||
border: 2rpx solid #d9d9d9;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.active {
|
||||
background-color: #2980fd;
|
||||
}
|
||||
.disabled {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
}
|
||||
.preview-list {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
// 下边框线
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
width: calc(100% - 30rpx);
|
||||
background-color: #d9d9d9;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
// 纯图片
|
||||
.img {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
width: 93rpx;
|
||||
height: 93rpx;
|
||||
margin-right: 25rpx;
|
||||
}
|
||||
|
||||
// 左侧内容
|
||||
.content-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.content-describe {
|
||||
flex: 1;
|
||||
color: #8c8c8c;
|
||||
font-size: 25rpx;
|
||||
// width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
line-height: 35rpx;
|
||||
.title {
|
||||
width: 380rpx;
|
||||
font-size: 33rpx;
|
||||
color: #000;
|
||||
line-height: 46rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 右侧内容 默认为状态点以及文字
|
||||
.content-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.spot {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 16rpx;
|
||||
background-color: #000;
|
||||
}
|
||||
.status {
|
||||
font-size: 30rpx;
|
||||
line-height: 46rpx;
|
||||
white-space: nowrap;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 底部样式
|
||||
.info {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
background-color: #f7f7f7;
|
||||
border-radius: 10rpx;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.mch-img {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0 10rpx;
|
||||
color: #000;
|
||||
font-size: 28rpx;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.number {
|
||||
white-space: nowrap;
|
||||
color: #8c8c8c;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.last-list {
|
||||
// 下边框线
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1rpx;
|
||||
width: 100%;
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
}
|
||||
|
||||
.last-none {
|
||||
// 下边框线
|
||||
&::after {
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 预制样式1 开启状态 标题白色 id 白色0.6
|
||||
.preview-one {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
.content-box {
|
||||
.content-describe {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
.title {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 预制样式2 关闭状态 标题白色 id 白色0.6
|
||||
.preview-two {
|
||||
background: rgba(0, 0, 0, 0.1) !important;
|
||||
.content-box {
|
||||
.content-describe {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
.title {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<view v-if="vdata.dataList.length > 0">
|
||||
<view class="bind-title">{{ props.title }}</view>
|
||||
<view class="layout" >
|
||||
<scroll-view scroll-y="true" :style="{maxHeight: props.maxH}"
|
||||
@scrolltoupper="reset" @scrolltolower="refresh"
|
||||
>
|
||||
<view v-for="(item, index) in vdata.dataList" :key="index">
|
||||
<slot :info="item" :index="index"></slot>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ref, reactive } from 'vue'
|
||||
import { onShow , onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
const props = defineProps({
|
||||
title: { type: String, default: '' },
|
||||
maxH: { type: String, default: '424rpx' }, // 最高高度
|
||||
pd: { type: String, default: '30rpx 50rpx' },
|
||||
requestFun: { type: Function, default: () => {} },
|
||||
params: { type: Object, default: () => ({}) },
|
||||
flag: { type: Boolean, default: true },
|
||||
isonshow: { type: Boolean, default: true },
|
||||
pageSize: { type: Number, default: 10 },
|
||||
})
|
||||
|
||||
const emits = defineEmits(['reset', 'refresh'])
|
||||
|
||||
const vdata = reactive({
|
||||
dataList: [], // 数据列表
|
||||
})
|
||||
|
||||
const listParams = {} // 页面传参对象 getList方法中传的参数
|
||||
|
||||
const queryObj = reactive({
|
||||
pageNumber: 1, // 默认是1
|
||||
pageSize: props.pageSize, // 默认10条,可传参修改
|
||||
isLoad: false, // 是否为上拉加载
|
||||
titlePage: '' // 总页数
|
||||
})
|
||||
|
||||
const getList = (listParamObj) => {
|
||||
// 非下拉刷新才显示加载提示
|
||||
if (queryObj.isLoad) {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
}
|
||||
|
||||
// listParamObj 父组件在函数中携带的请求参数,与页码页数,固定参数,合并到一起,并且当该参数对象在调用时有具体值,会将页码重置为1
|
||||
let paramObj // 参数合并
|
||||
|
||||
if (listParamObj) {
|
||||
queryObj.pageNumber = 1
|
||||
Object.keys(listParamObj).forEach((item) => {
|
||||
listParams[item] = listParamObj[item]
|
||||
})
|
||||
vdata.dataList = []
|
||||
}
|
||||
|
||||
paramObj = Object.assign(
|
||||
{
|
||||
pageNumber: queryObj.pageNumber,
|
||||
pageSize: queryObj.pageSize
|
||||
},
|
||||
props.params,
|
||||
listParams
|
||||
)
|
||||
|
||||
props.requestFun(paramObj)
|
||||
.then(({ bizData }) => {
|
||||
uni.hideLoading()
|
||||
|
||||
queryObj.titlePage = Math.ceil(bizData.total / queryObj.pageSize) // 页码总数
|
||||
|
||||
let data = bizData.records ? bizData.records : bizData
|
||||
|
||||
// 下拉刷新重置数据, 上拉加载新增数据
|
||||
if (queryObj.isLoad) {
|
||||
vdata.dataList.push(...data)
|
||||
} else {
|
||||
vdata.dataList = data
|
||||
}
|
||||
})
|
||||
.catch((err) => uni.hideLoading())
|
||||
}
|
||||
|
||||
// 只在onshow时调用一次, 请求方法
|
||||
const onShowGetList = () => {
|
||||
if (!props.flag) return false
|
||||
uni.showLoading({ title: '加载中' })
|
||||
queryObj.pageNumber = 1 // 页码固定为1
|
||||
let paramObj = Object.assign(
|
||||
{
|
||||
// 合并请求参数
|
||||
pageNumber: 1,
|
||||
pageSize: queryObj.pageSize
|
||||
},
|
||||
props.params
|
||||
)
|
||||
|
||||
props.requestFun(paramObj)
|
||||
.then(({ bizData }) => {
|
||||
|
||||
uni.hideLoading()
|
||||
queryObj.titlePage = Math.ceil(bizData.total / queryObj.pageSize)
|
||||
|
||||
let data = bizData.records ? bizData.records : bizData
|
||||
|
||||
vdata.dataList = data // 由于只在onShow 中调用一次,所以数据重新赋值
|
||||
})
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
if (props.isonshow) {
|
||||
onShowGetList()
|
||||
}
|
||||
})
|
||||
onLoad(() => {
|
||||
if (!props.isonshow) {
|
||||
onShowGetList()
|
||||
}
|
||||
})
|
||||
|
||||
// 下拉刷新
|
||||
const reset = () => {
|
||||
queryObj.pageNumber = 1
|
||||
queryObj.isLoad = false
|
||||
getList()
|
||||
}
|
||||
|
||||
// 上拉加载
|
||||
const refresh = () => {
|
||||
queryObj.pageNumber++
|
||||
if (queryObj.pageNumber > queryObj.titlePage) {
|
||||
queryObj.pageNumber = queryObj.pageNumber
|
||||
return (queryObj.isLoad = false)
|
||||
}
|
||||
queryObj.isLoad = true
|
||||
getList()
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.layout {
|
||||
margin: 30rpx 50rpx;
|
||||
}
|
||||
.bind-title {
|
||||
margin-top: 20rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<view class="search-wrapper" :style="{ padding: wrapPd }">
|
||||
<view class="search-input bdR16">
|
||||
<image src="/static/iconImg/icon-search.svg" mode="scaleToFill" />
|
||||
<input type="text" :placeholder="place" placeholder-style="#8C8C8C" :focus="isFocus" v-model="searchText" :disabled="isDisabled" @input="change" />
|
||||
<view class="search-text" v-if="searchText || flag" @tap="search">{{ text }}</view>
|
||||
</view>
|
||||
<slot>
|
||||
<view class="search-screen" v-if="props.screen" @tap="tapScreen">
|
||||
<image src="/static/iconImg/icon-filter.svg" mode="scaleToFill" />
|
||||
筛选
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import { debounce } from '@/util/debounce'
|
||||
const props = defineProps({
|
||||
screen: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
place: {
|
||||
type: String,
|
||||
default: '搜索代理商名、代理商号、联系人手机号',
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: '#fff',
|
||||
},
|
||||
wrapPd: {
|
||||
type: String,
|
||||
default: '30rpx',
|
||||
},
|
||||
|
||||
isFocus: { type: Boolean, default: false },
|
||||
isDisabled: { type: Boolean, default: false },
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
focus.value = props.isFocus
|
||||
})
|
||||
const focus = ref(false)
|
||||
const text = ref('搜索')
|
||||
const searchText = ref('')
|
||||
const flag = ref(false)
|
||||
// 点击筛选触发回调
|
||||
const emits = defineEmits(['screen', 'search', 'resetSearch'])
|
||||
const tapScreen = () => {
|
||||
emits('screen')
|
||||
}
|
||||
const change = () => {
|
||||
text.value = '搜索'
|
||||
}
|
||||
// 点击触发事件
|
||||
function search() {
|
||||
flag.value = true
|
||||
if (text.value === '搜索') {
|
||||
if (!searchText.value.trim()) return uni.showToast({ title: '请输入搜索条件', icon: 'none' })
|
||||
text.value = '取消'
|
||||
emits('search', searchText.value)
|
||||
} else {
|
||||
searchText.value = ''
|
||||
text.value = '搜索'
|
||||
emits('resetSearch', 'reset')
|
||||
}
|
||||
}
|
||||
defineExpose({ searchText })
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.search-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.search-input {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 21rpx;
|
||||
background-color: #fff;
|
||||
input {
|
||||
flex: 1;
|
||||
font-size: 27rpx;
|
||||
}
|
||||
image {
|
||||
margin: 0 10rpx 0 10rpx;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
.search-text {
|
||||
font-size: 30rxp;
|
||||
padding: 0 10rpx;
|
||||
color: $primaryColor;
|
||||
}
|
||||
}
|
||||
.search-screen {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
image {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin: 0 15rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<view class="upload-wrapper" :style="{ paddingLeft: pdLeft }">
|
||||
<view
|
||||
class="upload-main"
|
||||
:style="{ padding: pd, borderColor: borderBg }"
|
||||
:class="[borderNone != undefined ? 'borderNone' : '']"
|
||||
>
|
||||
<view class="upload-title" :style="{ color: textColor, fontSize: fontSize }"><slot name="title">{{ name }}</slot> </view>
|
||||
<view class="upload-img">
|
||||
<JeepayUpLoad
|
||||
v-if="imgUrl == ''"
|
||||
@uploadSuccess="uploadSuccess"
|
||||
:imgUrl="value"
|
||||
@clear="clearImg"
|
||||
></JeepayUpLoad>
|
||||
<image v-else :src="imgUrl" @tap="previewImage([imgUrl])" mode="aspectFill" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { watch, onBeforeUnmount, ref, onMounted } from "vue"
|
||||
import JeepayUpLoad from "@/components/JeepayUpLoad/JeepayUpLoad"
|
||||
import { addRules, clearOneRule } from "@/hooks/rules"
|
||||
import valid from "@/hooks/validate"
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: String,
|
||||
},
|
||||
pd: {
|
||||
type: String,
|
||||
default: " 30rpx 30rpx 30rpx 0",
|
||||
},
|
||||
borderNone: {
|
||||
type: String,
|
||||
},
|
||||
pdLeft: {
|
||||
type: String,
|
||||
default: "30rpx",
|
||||
},
|
||||
imgUrl: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
borderBg: {
|
||||
type: String,
|
||||
default: "#f2f2f2",
|
||||
},
|
||||
fontSize: { type: String },
|
||||
textColor: {
|
||||
type: String,
|
||||
default: "#000",
|
||||
},
|
||||
name: { type: String },
|
||||
rules: { default: null },
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (props.rules !== null) {
|
||||
props.rules.Msg = "请上传" + props.name
|
||||
addRules(props.rules)
|
||||
}
|
||||
})
|
||||
const emits = defineEmits(["update:value"])
|
||||
const uploadSuccess = (res) => {
|
||||
emits("update:value", res.data)
|
||||
}
|
||||
const previewImage = (v) => {
|
||||
if (!valid.httpOrHttps(v)) return false
|
||||
uni.previewImage({
|
||||
indicator: "number",
|
||||
loop: true,
|
||||
urls: v,
|
||||
})
|
||||
}
|
||||
const clearImg = () => {
|
||||
emits("update:value", "")
|
||||
}
|
||||
onBeforeUnmount(() => {
|
||||
if (props.rules !== null) {
|
||||
clearOneRule(props.rules)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload-wrapper {
|
||||
padding-left: 30rpx;
|
||||
font-size: 33rpx;
|
||||
.upload-main {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-top: 1rpx solid #f2f2f2;
|
||||
image {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.borderNone {
|
||||
border: none !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<view class="login-wrapper" :style="{ padding: pd }">
|
||||
<view class="login-main">
|
||||
<view class="login-title" v-if="title">{{ title }}</view>
|
||||
<view class="login-input" :style="{ backgroundColor: bgColor }">
|
||||
<input
|
||||
:password="password"
|
||||
:placeholder="place"
|
||||
:type="type"
|
||||
placeholder-style="color: #A6A6A6;"
|
||||
:value="value"
|
||||
@input="change($event)"
|
||||
/>
|
||||
<view class="login-right"> <slot></slot> </view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { watchEffect, onBeforeUnmount, onMounted } from "vue"
|
||||
import { addRules, clearOneRule } from "@/hooks/rules"
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: "账号",
|
||||
},
|
||||
place: {
|
||||
type: String,
|
||||
default: "请输入登录名/手机号",
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "text",
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "text",
|
||||
},
|
||||
pd: {
|
||||
type: String,
|
||||
default: "50rpx",
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: "#f3f2f5",
|
||||
},
|
||||
password: { type: Boolean, default: false },
|
||||
rules: { default: null },
|
||||
})
|
||||
const emits = defineEmits(["update:value"])
|
||||
const change = (e) => {
|
||||
emits("update:value", e.detail.value)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (props.rules !== null) {
|
||||
props.rules.Msg = props.title
|
||||
addRules(props.rules)
|
||||
}
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
if (props.rules !== null) {
|
||||
clearOneRule(props.rules)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login-wrapper {
|
||||
padding: 50rpx;
|
||||
.login-title {
|
||||
margin-left: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.login-input {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 110rpx;
|
||||
|
||||
.login-right {
|
||||
align-self: center;
|
||||
}
|
||||
border-radius: 16rpx;
|
||||
background: #f3f2f5;
|
||||
input {
|
||||
flex: 1;
|
||||
font-size: 33rpx;
|
||||
height: 110rpx;
|
||||
margin-left: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,169 @@
|
||||
<template>
|
||||
<view class="s-wrapper" :style="{ borderRadius: props.bdR, backgroundColor: bgColor }">
|
||||
<view class="s-screening">
|
||||
<block v-for="(v, i) in list" :key="v.value">
|
||||
<view class="s-scr-item" :class="{ selected: i == index }" @tap="onSelect(v, i)"> {{ v.text }} </view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="theCustom" :class="{ customer: index === props.list.findIndex((v) => v.value == 'customer') }">
|
||||
<view class="time-picker">
|
||||
<xp-picker
|
||||
ref="star"
|
||||
@confirm="confirm"
|
||||
@cancel="emits('close')"
|
||||
@tap="isShow"
|
||||
mode="ymdhi"
|
||||
:startTime="time.startDate"
|
||||
>{{ time.startDate }}</xp-picker
|
||||
>
|
||||
<text></text>
|
||||
<xp-picker
|
||||
ref="end"
|
||||
@confirm="confirmEnd"
|
||||
@cancel="emits('close')"
|
||||
mode="ymdhi"
|
||||
@tap="isShow"
|
||||
:startTime="time.endDate"
|
||||
>{{ time.endDate }}</xp-picker
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue"
|
||||
import { getDay } from "@/util/timeInterval.js"
|
||||
const time = ref({
|
||||
startDate: `${getDay(0, "-")} 00:00`,
|
||||
endDate: `${getDay(0, "-")} 23:59`,
|
||||
})
|
||||
|
||||
const emits = defineEmits(["search", "open", "close"])
|
||||
const props = defineProps({
|
||||
bdR: {
|
||||
type: String,
|
||||
default: "20rpx",
|
||||
},
|
||||
bgColor: { type: String },
|
||||
list: {
|
||||
type: Array,
|
||||
default: [
|
||||
// { value: 'all', text: '全部' },
|
||||
{ value: "today", text: "今天" },
|
||||
{ value: "yesterday", text: "昨天" },
|
||||
{ value: "currMonth", text: "本月" },
|
||||
{ value: "prevMonth", text: "上月" },
|
||||
{ value: "customer", text: "自定义" },
|
||||
],
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
})
|
||||
const star = ref(null)
|
||||
const end = ref(null)
|
||||
const scrInfo = ref(0)
|
||||
|
||||
const isOpen = ref(false)
|
||||
const onSelect = (val, i) => {
|
||||
if (val.value != "customer") {
|
||||
emits("search", { val, i })
|
||||
} else {
|
||||
emits("search", {
|
||||
val: {
|
||||
text: "自定义",
|
||||
value: "customer",
|
||||
time: `customDate_${time.value.startDate}:00_${time.value.endDate}:00`,
|
||||
},
|
||||
i,
|
||||
})
|
||||
props.index = props.list.findIndex((v) => v.value == "customer")
|
||||
isOpen.value = true
|
||||
}
|
||||
}
|
||||
|
||||
//时间选择器确定
|
||||
const confirm = (e) => {
|
||||
time.value.startDate = e.value
|
||||
confirmEnd({ value: time.value.endDate })
|
||||
emits("close")
|
||||
}
|
||||
const confirmEnd = (e) => {
|
||||
time.value.endDate = e.value
|
||||
let i = props.list.findIndex((v) => v.value == "customer")
|
||||
emits("search", {
|
||||
val: {
|
||||
text: "自定义",
|
||||
value: `customDate_${time.value.startDate}:00_${time.value.endDate}:00`,
|
||||
},
|
||||
i,
|
||||
})
|
||||
|
||||
emits("close")
|
||||
}
|
||||
const isShow = (e) => {
|
||||
if (star.value.pickerVisible || end.value.pickerVisible) {
|
||||
emits("open")
|
||||
} else {
|
||||
emits("close")
|
||||
}
|
||||
}
|
||||
// const endIsShow = () => {
|
||||
// if (end.value.pickerVisible) {
|
||||
// emits("open")
|
||||
// } else {
|
||||
// emits("close")
|
||||
// }
|
||||
// }
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.s-wrapper {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
padding: 20rpx 20rpx 20rpx 20rpx;
|
||||
.s-screening {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.s-scr-item {
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
white-space: nowrap;
|
||||
border-radius: 7rpx;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.selected {
|
||||
background-color: #fff;
|
||||
color: #7737fe;
|
||||
}
|
||||
}
|
||||
.theCustom {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
transition: height 0.3s ease-in;
|
||||
.time-picker {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 90rpx;
|
||||
padding: 0 30rpx;
|
||||
margin-top: 10rpx;
|
||||
background: #fff;
|
||||
font-size: 28rpx;
|
||||
border-radius: 7rpx;
|
||||
color: $primaryColor;
|
||||
|
||||
text {
|
||||
width: 40rpx;
|
||||
height: 2rpx;
|
||||
background-color: $primaryColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
.customer {
|
||||
height: 100rpx;
|
||||
transition: height 0.3s ease-in;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<view class="phone-wrapper pd50">
|
||||
<view class="phone-main bgF bdR20 t-center">
|
||||
<view class="tips fs27 c333 lh46"> 为了您的账号安全,请联系客服进行账号注销处理。客服电话: </view>
|
||||
<view class="phone-Number fb">{{ phoneNumber }} </view>
|
||||
<view class="phone-button">
|
||||
<view @tap="cancel">取消</view>
|
||||
<view class="call-phone fb" @tap="callPhone">拨打电话</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
phoneNumber: {
|
||||
type: String,
|
||||
default: '186 8866 6688'
|
||||
}
|
||||
})
|
||||
const emits = defineEmits(['cancel'])
|
||||
const callPhone = () => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: props.phoneNumber
|
||||
})
|
||||
}
|
||||
const cancel = () => {
|
||||
emits('cancel')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.phone-main {
|
||||
.tips {
|
||||
padding: 50rpx 50rpx 0 50rpx;
|
||||
}
|
||||
.phone-Number {
|
||||
margin-top: 30rpx;
|
||||
font-size: 36rpx;
|
||||
color: #7737fe;
|
||||
}
|
||||
.phone-button {
|
||||
display: flex;
|
||||
margin-top: 50rpx;
|
||||
border-top: 1rpx solid rgb(232, 230, 230);
|
||||
view {
|
||||
width: 50%;
|
||||
height: 110rpx;
|
||||
line-height: 110rpx;
|
||||
color: #8c8c8c;
|
||||
font-size: 33rpx;
|
||||
}
|
||||
.call-phone {
|
||||
border-left: 1rpx solid rgb(232, 230, 230);
|
||||
color: $primaryColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user