first
This commit is contained in:
134
components/JeepayRed/JeepayRedBizinfoSelect.vue
Normal file
134
components/JeepayRed/JeepayRedBizinfoSelect.vue
Normal file
@@ -0,0 +1,134 @@
|
||||
<!--
|
||||
Jeepay 门店选择 / 应用选择
|
||||
|
||||
@author terrfly
|
||||
@site https://www.jeequan.com
|
||||
@date 2022/12/06 12:55
|
||||
-->
|
||||
<template>
|
||||
|
||||
<!-- 选择门店 -->
|
||||
<JeepayPopupListSelect
|
||||
ref="jeepayRedPopupListSelectByBizinfos"
|
||||
:reqTableDataFunc="reqTableDataByBizsFunc"
|
||||
:searchInputName="getSearchInputName()"
|
||||
:fields="getField()"
|
||||
/>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { reqLoad, API_URL_MCH_STORE_LIST, API_URL_MCH_APP_LIST } from '@/http/apiManager.js'
|
||||
|
||||
|
||||
// 定义组件参数
|
||||
const props = defineProps({
|
||||
configMode: { type: String, default: ''}, // 搜索时仅展示商户号
|
||||
// 是否多选框, 默认单选。
|
||||
isCheckbox: { type: Boolean, default: false },
|
||||
|
||||
// 自动关闭, 点击确定, 自动关闭
|
||||
autoClose: { type: Boolean, default: true },
|
||||
|
||||
// 业务类型: 默认门店
|
||||
bizType: { type: String, default: 'store' },
|
||||
|
||||
// 是否支持选择 【 全部门店 、 全部应用 】
|
||||
isShowAllBiz: { type: Boolean, default: false },
|
||||
// 特殊参数处理
|
||||
params:{type:Object,default:()=>({})}
|
||||
|
||||
})
|
||||
|
||||
|
||||
const jeepayRedPopupListSelectByBizinfos = ref()
|
||||
|
||||
|
||||
function getField(){
|
||||
|
||||
if(props.bizType == 'store'){
|
||||
return { key: 'storeId', left: 'storeName', right: 'storeId' }
|
||||
}
|
||||
|
||||
if(props.bizType == 'mchApp'){
|
||||
return { key: 'appId', left: 'appName', right: 'appId' }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getSearchInputName(){
|
||||
if(props.bizType == 'store'){
|
||||
return "storeName"
|
||||
}
|
||||
|
||||
if(props.bizType == 'mchApp'){
|
||||
return "appName"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function reqTableDataByBizsFunc(params) {
|
||||
Object.assign(params,props.params)
|
||||
console.log(params);
|
||||
|
||||
let apiResult = null;
|
||||
|
||||
if(props.bizType == 'store'){
|
||||
apiResult = reqLoad.list(API_URL_MCH_STORE_LIST, params)
|
||||
}
|
||||
|
||||
if(props.bizType == 'mchApp'){
|
||||
apiResult = reqLoad.list(API_URL_MCH_APP_LIST, params)
|
||||
}
|
||||
|
||||
return apiResult.then((apiRes) => {
|
||||
return processApiResBizData(params, apiRes)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 选择门店
|
||||
function open (defaultVal){
|
||||
console.log(defaultVal,'defaultValdefaultVal')
|
||||
return jeepayRedPopupListSelectByBizinfos.value.open(defaultVal).then((selected) => {
|
||||
|
||||
// 自动关闭
|
||||
if(props.autoClose){
|
||||
close()
|
||||
}
|
||||
|
||||
return selected;
|
||||
})
|
||||
}
|
||||
|
||||
function close(){
|
||||
jeepayRedPopupListSelectByBizinfos.value.close() //自行关闭
|
||||
}
|
||||
|
||||
|
||||
function processApiResBizData(params, apiRes){
|
||||
|
||||
// 第一页 拼接全部门店 (index = 0 )
|
||||
if(params.pageNumber == 1 && props.isShowAllBiz){
|
||||
|
||||
if(props.bizType == 'store'){
|
||||
apiRes.bizData.records.unshift({storeName: '全部门店', storeId: ''})
|
||||
}
|
||||
|
||||
if(props.bizType == 'mchApp'){
|
||||
apiRes.bizData.records.unshift({appName: '全部应用', appId: ''})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return apiRes
|
||||
}
|
||||
|
||||
|
||||
// 将表格事件暴露出去 https://www.jianshu.com/p/39d14c25c987
|
||||
defineExpose({ open, close })
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
355
components/JeepayRed/JeepayRedPopupListSelect.vue
Normal file
355
components/JeepayRed/JeepayRedPopupListSelect.vue
Normal file
@@ -0,0 +1,355 @@
|
||||
<!--
|
||||
组件作用: 弹层, 列表支持 单选, 多选。
|
||||
|
||||
使用方法:
|
||||
|
||||
<JeepayPopupListSelect ref="jeepayPopupListSelect" :reqTableDataFunc="reqTableDataFunc" :fields="{ key: 'articleId', left: 'articleId', right: 'title'}"/>
|
||||
jeepayPopupListSelect.value.open().then((selected) => {
|
||||
console.log(selected);
|
||||
jeepayPopupListSelect.value.close() //自行关闭
|
||||
})
|
||||
|
||||
@author terrfly
|
||||
@site https://www.jeequan.com
|
||||
@date 2022/11/26 16:24
|
||||
-->
|
||||
<template>
|
||||
<uni-popup ref="popupRef" type="bottom" @maskClick="close" @change="change" mask-background-color="rgba(0,0,0,.5)" :safe-area="false">
|
||||
<view class="card-wrapper">
|
||||
<view class="selected-title" v-if="title">
|
||||
{{ title }}
|
||||
</view>
|
||||
<view v-if="props.searchInputName" class="input-search">
|
||||
<uni-easyinput
|
||||
v-model="vdata.searchData[props.searchInputName]"
|
||||
prefixIcon="search"
|
||||
:inputBorder="false"
|
||||
:clearable="false"
|
||||
:styles="{
|
||||
backgroundColor: 'transparent',
|
||||
}"
|
||||
type="text"
|
||||
placeholder="搜索"
|
||||
placeholderStyle=" color: rgba(0,0,0,0.85);font-size: 30rpx;"
|
||||
/>
|
||||
<view class="search-button" @tap="searchFunc">搜索</view>
|
||||
</view>
|
||||
<!-- 数据渲染 -->
|
||||
<JTableList ref="jeepayTableListRef" :reqTableDataFunc="reqTableDataFuncWrapper" :searchData="vdata.searchData" :initData="false" height='406rpx'>
|
||||
<template #tableBody="{ record }">
|
||||
<view class="store" @tap="selectFunc(record)">
|
||||
<template v-if="isCheckbox">
|
||||
<view class="more-selected" :class="{ 'more-disabled': record.hasDirector, 'more-active': hasSelected(record) }">
|
||||
<image :src="record.hasDirector ? '/static/iconImg/icon-disable.svg' : '/static/iconImg/icon-check.svg'" mode="scaleToFill" />
|
||||
</view>
|
||||
</template>
|
||||
<view v-else :class="{ 'store-dot-def': true, 'active-dot': hasSelected(record) }"></view>
|
||||
<slot name="content" :record="record">
|
||||
<view class="store-inner-slot">
|
||||
<view class="left">
|
||||
<text>{{ record[props.fields.left] }}</text>
|
||||
</view>
|
||||
<view class="right">{{ record[props.fields.right] }}</view>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</template>
|
||||
</JTableList>
|
||||
|
||||
<!-- <button v-if="vdata.hasNext" @tap="jeepayTableListRef.addNext()">下一页</button> -->
|
||||
|
||||
<view class="footer-wrapper">
|
||||
<view class="footer-main">
|
||||
<view class="footer-button">
|
||||
<view class="flex-center" hover-class="touch-button" @tap="close">取消</view>
|
||||
<view @tap="confirmFunc" class="confirm flex-center" hover-class="touch-button">确认</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, nextTick, reactive, ref, render, watch } from 'vue'
|
||||
|
||||
const jeepayTableListRef = ref()
|
||||
|
||||
// 定义组件参数
|
||||
const props = defineProps({
|
||||
// 请求业务数据, 参数可自行控制。
|
||||
reqTableDataFunc: { type: Function, default: () => {} },
|
||||
|
||||
// 搜索输入框的name , 不传入则不显示搜索。
|
||||
searchInputName: { type: String },
|
||||
|
||||
// 约定的字段 , 若不合适请通过插槽自行插入。
|
||||
fields: { type: Object, default: { key: 'id', left: 'left', right: 'right' } },
|
||||
|
||||
// 是否多选框, 默认单选。
|
||||
isCheckbox: { type: Boolean, default: false },
|
||||
// 标题有则显示无则隐藏
|
||||
title: [String, Number],
|
||||
})
|
||||
let changePageMetaOverflowFunc = inject('changePageMetaOverflowFunc')
|
||||
const emits = defineEmits(['confirm'])
|
||||
|
||||
const popupRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
searchData: {}, //当前页的搜索条件
|
||||
|
||||
hasNext: false, // 是否包含下一页数据
|
||||
|
||||
selectedList: [], // 选择的值
|
||||
|
||||
promiseObject: {},
|
||||
})
|
||||
|
||||
// 点击搜索
|
||||
function searchFunc() {
|
||||
jeepayTableListRef.value.refTable(true)
|
||||
}
|
||||
|
||||
/** reqTableDataFunc 处理函数 */
|
||||
function reqTableDataFuncWrapper(params) {
|
||||
return props.reqTableDataFunc(params).then(({ bizData }) => {
|
||||
vdata.hasNext = bizData.hasNext // 是否包含下一页
|
||||
return Promise.resolve({ bizData })
|
||||
})
|
||||
}
|
||||
|
||||
// 是否选中
|
||||
function hasSelected(record) {
|
||||
return vdata.selectedList.filter((r) => r[props.fields.key] == record[props.fields.key]).length > 0
|
||||
}
|
||||
|
||||
/** 选择函数 **/
|
||||
function selectFunc(record) {
|
||||
// 判断是否已存在
|
||||
if (hasSelected(record)) {
|
||||
// 多选需删除
|
||||
if (props.isCheckbox) {
|
||||
vdata.selectedList.splice(
|
||||
vdata.selectedList.findIndex((r) => r[props.fields.key] == record[props.fields.key]),
|
||||
1
|
||||
)
|
||||
}
|
||||
|
||||
// 单选无需操作
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 多选直接添加
|
||||
if (props.isCheckbox) {
|
||||
if (record.hasDirector) return //如果被其他店长绑定 禁止选中
|
||||
return vdata.selectedList.push(record)
|
||||
} else {
|
||||
// 单选
|
||||
|
||||
return (vdata.selectedList = [record])
|
||||
}
|
||||
}
|
||||
|
||||
// 点击确定事件
|
||||
function confirmFunc() {
|
||||
// 多选
|
||||
if (props.isCheckbox) {
|
||||
emits('confirm', vdata.selectedList)
|
||||
return vdata.promiseObject.resolve(vdata.selectedList)
|
||||
}
|
||||
|
||||
// 单选 仅返回第一个即可。
|
||||
emits('confirm', vdata.selectedList.length > 0 ? vdata.selectedList[0] : null)
|
||||
vdata.promiseObject.resolve(vdata.selectedList.length > 0 ? vdata.selectedList[0] : null)
|
||||
}
|
||||
|
||||
// 显示弹层, 并且返回一个promise
|
||||
// promise.then(selected)
|
||||
// 注意: 此Promise 只会回调一次, 如需要验证是否选中正确, 需要使用@confirm事件。
|
||||
// 如果对拿到的值不做校验,获取到然后关闭。 那么可以直接使用.then() 然后立马关闭弹层。
|
||||
function open(defaultVal) {
|
||||
// 清空数据
|
||||
vdata.selectedList = []
|
||||
vdata.searchData[props.searchInputName] = ''
|
||||
|
||||
// 默认选中。
|
||||
if (defaultVal) {
|
||||
if (Array.isArray(defaultVal)) {
|
||||
vdata.selectedList = defaultVal
|
||||
} else {
|
||||
vdata.selectedList = [defaultVal]
|
||||
}
|
||||
}
|
||||
|
||||
popupRef.value.open()
|
||||
|
||||
nextTick(() => {
|
||||
jeepayTableListRef.value.refTable(true)
|
||||
uni.hideTabBar() // 可能报错, 在nextTick中, 不影响其他业务。
|
||||
})
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
vdata.promiseObject.resolve = resolve
|
||||
vdata.promiseObject.reject = reject
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭弹层
|
||||
function close() {
|
||||
popupRef.value.close()
|
||||
uni.showTabBar()
|
||||
}
|
||||
const change = (e) => {
|
||||
if (changePageMetaOverflowFunc) {
|
||||
changePageMetaOverflowFunc(!e.show)
|
||||
}
|
||||
}
|
||||
// 将表格事件暴露出去 https://www.jianshu.com/p/39d14c25c987
|
||||
defineExpose({ open, close })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-wrapper {
|
||||
border-radius: 32rpx 32rpx 0 0;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
min-height: 70vh;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
.selected-title {
|
||||
height: 110rpx;
|
||||
line-height: 110rpx;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
border-bottom: 1rpx solid #ededed;
|
||||
}
|
||||
.input-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 10rpx;
|
||||
margin: 30rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #f7f7f7;
|
||||
.search-button {
|
||||
padding: 24rpx 30rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: #2980fd;
|
||||
}
|
||||
}
|
||||
.store {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 0 40rpx;
|
||||
height: 120rpx;
|
||||
font-size: 30rpx;
|
||||
.more-selected {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 20rpx;
|
||||
border: 2rpx solid rgba(217, 217, 217, 1);
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.more-disabled {
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
.more-active {
|
||||
background-color: #2980fd;
|
||||
}
|
||||
.store-dot-def {
|
||||
position: relative;
|
||||
margin-right: 20rpx;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
background-color: #d7d8d9;
|
||||
border-radius: 50%;
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
border-radius: 50%;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
.active-dot {
|
||||
background-color: #2980fd;
|
||||
}
|
||||
|
||||
.store-inner-slot {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.right {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
.all-store::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 40rpx;
|
||||
right: 40rpx;
|
||||
height: 1rpx;
|
||||
background-color: #ededed;
|
||||
}
|
||||
.footer-wrapper {
|
||||
height: 186rpx;
|
||||
.footer-main {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: env(safe-area-inset-bottom);
|
||||
border-top: 1rpx solid #ededed;
|
||||
.tips {
|
||||
margin: 20rpx;
|
||||
text-align: center;
|
||||
font-size: 27rpx;
|
||||
color: #a6a6a6;
|
||||
}
|
||||
.footer-button {
|
||||
padding: 0 30rpx;
|
||||
margin-top: 30rpx;
|
||||
padding-bottom: 30rpx;
|
||||
display: flex;
|
||||
|
||||
justify-content: space-between;
|
||||
view {
|
||||
width: 330rpx;
|
||||
height: 110rpx;
|
||||
font-size: 33rpx;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 20rpx;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
.confirm {
|
||||
color: #fff;
|
||||
background: $jeepay-bg-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user