347 lines
8.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<template v-if="!readonly">
<view v-if="formProps.expanding && dataOptions.length === 0" style="color:#E79467;">无选项😢,请检查设置</view>
<!-- 多选 -->
<template v-else-if="formProps.multiple">
<uni-data-checkbox v-if="formProps.expanding" :map="optionsKeyMap" multiple v-model="__value"
:localdata="dataOptions" />
<multiple-picker v-slot="{show}" v-else index="name" v-model="__value" :options="dataOptions">
<click-input :value="selectVal" :placeholder="formProps.placeholder || '请选择'" @click="show" />
</multiple-picker>
</template>
<!-- 单选 -->
<template v-else>
<!-- title == '司机姓名' -->
<uni-data-checkbox v-if="formProps.expanding" :map="optionsKeyMap" v-model="__value"
:localdata="dataOptions" />
<picker class="picker" v-else-if="title == '司机姓名'" @cancel="onCancel" @change="ok2" mode="selector" ref="pickerBottom"
:value="index" range-key="name" :range="dataOptions2">
<uni-search-bar v-if="isSearch" bgColor="#fff" v-model="searchValue" class="search" radius="5"
placeholder="请输入" clearButton="auto" cancelButton="none" @input="searchChange" />
<click-input @click="isSearchFn()" :value="(modelValue || []).length > 0 ? dataOptions[index]:null"
index="name" :placeholder="formProps.placeholder || '请选择'" />
</picker>
<picker v-else @change="ok" mode="selector" :value="index" range-key="name" :range="dataOptions">
<click-input :value="(modelValue || []).length > 0 ? dataOptions[index]:null" index="name"
:placeholder="formProps.placeholder || '请选择'" />
</picker>
</template>
</template>
<!-- 只读模式 -->
<template v-else>
<!-- <click-input disabled v-if="formProps.multiple" :value="modelValue.length > 0 ? dataOptions[index]:null"
index="name" /> -->
<click-input disabled v-if="formProps.multiple" :value="(modelValue || []).length > 0 ? dataOptions:null"
index="name" />
<click-input disabled v-else :value="selectVal" />
</template>
</view>
</template>
<script setup>
import {
computed,
onMounted,
ref,
watch
} from 'vue'
import {
$nEmpty
} from '@/utils/tool.js'
import ClickInput from '@/components/ClickInput.vue'
import MultiplePicker from '@/components/common/MultiplePicker.vue'
const props = defineProps({
formProps: {
type: Object,
default: () => {
return {}
}
},
modelValue: {
type: Array,
default: () => {
return []
}
},
readonly: Boolean,
title: String,
})
const _value = computed({
get() {
return props.modelValue || []
},
set(val) {
emits('update:modelValue', val)
}
})
const selectVal = computed(() => {
// console.log('selectVal', JSON.stringify(props.modelValue), JSON.stringify(dataOptions.value.filter(v => (props.modelValue || []).indexOf(v.value) > -1)))
return dataOptions.value && dataOptions.value.filter(v => (props.modelValue || []).indexOf(v.value) > -1).map(v => v.name)
})
const __value = computed({
get() {
return props.formProps.multiple ? _value.value : _value.value[0]
},
set(val) {
if (props.formProps.multiple) {
emits('update:modelValue', val)
} else {
emits('update:modelValue', [val])
}
}
})
const emits = defineEmits(['update:modelValue', 'resize'])
const loading = ref(false)
const dataOptions = ref([])
const dataOptions2 = ref([])
let preHandlerFuc = null
let aftHandlerFuc = null
const optionsKeyMap = {
text: 'name',
value: 'value'
}
const index = ref(0)
function loadOptionsData() {
try {
if (props.formProps.fixed) {
dataOptions.value = props.formProps.options;
} else {
doRequest(dataOptions.value)
}
} catch (e) {
console.log(e)
}
}
watch(() => dataOptions, () => {
dataOptions2.value = dataOptions.value;
}, {
deep: true
});
onMounted(() => {
loadOptionsData()
})
function resizeCollapse() {
setTimeout(() => emits('resize'), 800)
}
function ok(e) {
index.value = e.detail.value
__value.value = dataOptions.value[index.value].value
resizeCollapse();
}
function ok2(e) {
const id = dataOptions2.value[e.detail.value].value;
const findIndex = dataOptions.value.findIndex(item => item.value == id);
// alert(findIndex)
if (findIndex > -1) {
index.value = findIndex;
__value.value = dataOptions.value[findIndex].value;
resizeCollapse();
isSearch.value = false;
}
}
// 搜索查询
const isSearch = ref(false);
const searchValue = ref("");
const searchBottom = ref(0);
function searchChange(e) {
console.log(e);
// ,调模糊查询然后 把返回的结果传给this.list数组
let findList = dataOptions.value.filter(item => item.name.includes(e))
dataOptions2.value = findList
if (e == '') {
dataOptions2.value = dataOptions.value
}
}
const onCancel = () => {
isSearch.value = false;
}
const isSearchFn = () => {
//.box获取class为box的元素如果使用的id= 'box' 则使用'#box'
// uni.createSelectorQuery().in(this).select('.picker').boundingClientRect(data => {
// console.log(JSON.stringify(data))
// console.log(data.height / 100 * window.innerHeight,window.innerHeight)
// console.log(uni.getSystemInfoSync().windowHeight, uni.getSystemInfoSync().windowWidth)
// uni.getSystemInfo({
// success: function (res) {
// console.log(res.screenHeight);
// console.log(res.windowHeight);
// console.log(data.height / 100 * res.screenHeight)
// // data.height / 100 * res.screenHeight - 22
// // searchBottom.value = (45 / 8) + 238;
// }
// });
// // (data.height / 100 * window.innerHeight) * 1.48
// }).exec()
setTimeout(() => {
isSearch.value = true;
}, 500)
}
function doRequest(options) {
const http = props.formProps.http || {}
if (http.url && http.method) {
const params = {
url: http.url,
method: http.method,
headers: {
'content-type': http.contentType === 'JSON' ? 'application/json' :
'application/x-www-form-urlencoded',
...coverParams(http.headers || [])
},
params: {},
data: http.contentType === 'JSON' ? JSON.parse(http.data || '{}') : coverParams(http.params || []),
}
preHandler(params, http.preHandler)
if (http.contentType !== 'JSON') {
params.data = {
...params.data,
...params.params
}
}
loading.value = true
uni.request({
...params,
timeout: 20000,
header: params.headers,
withCredentials: true,
dataType: 'json',
success: (rsp) => {
loading.value = false
// console.log('获取到数据: ', JSON.stringify(rsp))
const ops = aftHandler(rsp, http.aftHandler)
options.push(...(ops || []))
},
fail: (err) => {
loading.value = false
uni.showToast({
icon: 'none',
title: '请求http数据源发生异常:' + JSON.stringify(err)
})
}
})
}
}
//数组转对象
function coverParams(args, isForm = false) {
const params = {};
if (Array.isArray(args)) {
args.forEach(arg => {
if ($nEmpty(arg.name)) {
params[arg.name] = arg.value
}
})
}
return params
}
//前置处理
function preHandler(params, script) {
if (script) {
if (!preHandlerFuc) {
preHandlerFuc = new Function('ctx', `${script}\n preHandler(ctx)`)
}
try {
preHandlerFuc(params)
} catch (e) {
console.log(e)
}
}
}
//后置处理
function aftHandler(rsp, aftHandler) {
if (aftHandler) {
return toFunc(rsp, aftHandler)
} else {
//新格式,带字段设置
if (aftHandler.isJs) {
return toFunc(rsp, aftHandler.js)
} else {
//取值进行转,拿到数组
const dataArr = getData(rsp, ifEmGet(aftHandler.rule.source, 'data'));
const name = ifEmGet(aftHandler.rule.name, 'name')
const value = ifEmGet(aftHandler.rule.value, 'value')
return (dataArr || []).map(v => {
return {
name: v[name],
value: v[value],
}
})
}
}
}
function ifEmGet(v, dv) {
return $nEmpty(v) ? v : dv
}
function getData(obj, path) {
// 将路径字符串分割成数组
const keys = path.split('.');
// 初始化结果为传入的对象
let result = obj;
// 逐层查找属性值
for (const key of keys) {
if (result.hasOwnProperty(key)) {
result = result[key];
} else {
return undefined;
}
}
return result;
}
function toFunc(rsp, script) {
if (script) {
if (!aftHandlerFuc) {
aftHandlerFuc = new Function('rsp', `${script}\n return aftHandler(rsp)`)
}
try {
return aftHandlerFuc(rsp) || []
} catch (e) {
console.log(e)
}
}
return []
}
</script>
<style scoped>
.search {
position: fixed;
/* bottom: 465rpx; */
/* bottom: 242px; */
bottom: 400rpx;
left: 50%;
transform: translateX(-50%);
z-index: 9999;
padding: 0;
}
.search /deep/ .uni-searchbar__box {
width: 400rpx;
border: 2rpx solid #f5f5f5;
}
</style>