123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548 |
- <template>
- <!-- 表单 -->
- <form style="padding:10px 0" @submit="formSubmit">
- <view class="header-info" v-if="config.isHeader">
- <view class="title">
- 上传后请核对识别信息
- </view>
- <view class="info">
- 如有错误请及时手动修改
- </view>
- </view>
- <view v-for="(item,index) in formData" :key="index">
-
- <view v-show="!item.show">
- <!-- 头部标题 -->
- <view class="upload-car-bottom" v-if="item.type == 100">
- {{item.title}}
- </view>
- <!-- 是否显示-->
- <view style="min-height: 90rpx;" :style="item.vertical == 2 ? 'margin-top: 20rpx' : ''"
- :class="item.vertical == 2 ? 'as-layout-vertical' : 'as-layout-horizontal'" v-else>
- <!-- 标题 -->
- <view v-if="item.titleShow||item.titleShow===undefined&&item.type!=14" class="as-gravity-center-start"
- :style="'min-width:'+ config.titleWidth + 'rpx'"
- style="margin:0 20rpx;flex-direction: row;display: flex;flex-direction: row;">
- <image class="img-size" :src="item.required ? '/static/image/must.png' : ''"></image>
- <view :class="item.vertical == 2 ? 'text-left' : 'text-justify'" class="text-title" style="width:100%;">
- {{item.title}}
- </view>
- </view>
-
- <!-- 内容 -->
- <view class="as-weight as-gravity-center-start">
- <!-- 文本内容 -->
- <view v-if="item.type == 1" class="text" :style="item.style">{{item[item.value]}}</view>
- <!-- 输入框 -->
- <view v-if="item.type == 2" style="width: 100%;">
- <input :disabled="item.disabled" v-model="item[item.value]" :type="item.inputType"
- :placeholder="item.hint ? item.hint : '请输入' + item.title" placeholder-class="text-hint"
- class="text as-gravity-center-start" :maxlength="item.maxlength" :style="item.style"
- style="min-height: 90rpx;word-break:break-all" />
- </view>
- <!-- 多项选择器 -->
- <view v-if="item.type == 3">
- <checkbox-group @change="checkboxChange($event,item)" :disabled="item.disabled">
- <view class="as-layout-horizontal" style="flex-wrap: wrap;margin: 10px 0;">
- <label style="display: flex;flex-direction: row;margin-right: 30rpx;"
- v-for="(itemData,index) in item.itemData " :key="index">
- <checkbox style="transform:scale(0.7)" :value="itemData.value" :checked="itemData.checked" />
- <view>{{itemData.value}}</view>
- </label>
- </view>
- </checkbox-group>
- </view>
- <!-- 普通选择器 当 range 是一个 Array<Object> 时,通过 range-key 来指定 Object 中 key 的值作为选择器显示内容
- :range-key="item[item.value]"-->
- <view v-if="item.type == 4" style="width: 100%;">
- <!-- range[范围] value[初始选择]-->
- <picker color="uni-picker-container" :disabled="item.disabled" :range-key="item.itemKey"
- :mode="item.mode ? item.mode : 'selector'" @change="bindPickerChange($event,item)"
- :range="item.itemData">
- <view class="text">
- {{item[item.value] ? (item.itemKey ? item[item.value][item.itemKey] : item[item.value]) :
- item.hint ? item.hint : '请选择' + item.title}}
- </view>
- </picker>
- </view>
-
- <!-- 富文本框 -->
- <view v-if="item.type == 5" style="width: 100%;">
- <view style="margin: 20rpx 30rpx 0 30rpx;border: 1px solid #999999;height: 200rpx;border-radius: 10px;">
- <textarea :disabled="item.disabled" class="text" v-model="item[item.value]"
- @input="textareaInput($event,item)" placeholder-class="text-hint" style="width: 100%;margin: 20rpx"
- :maxlength="item.maxlength" auto-height :placeholder="item.hint ? item.hint : '请输入' + item.title">
- </textarea>
- <view v-if="item.maxlength" class="as-gravity-center-end"
- style="display: flex;flex-direction: row;height: 20%;">
- <view class="text">{{!item.num ? '0' : item.num}}</view>
- <view class="text">/{{item.maxlength ? item.maxlength : 100}}</view>
- </view>
- </view>
- </view>
-
- <!-- 图片选择器 :imgWidth="imgWidth ? imgWidth : 0"-->
- <view v-if="item.type == 6" style="width: 100%;">
- <form-image @backImg="backImg($event,item)" style="width: 100%;" :retract="40"></form-image>
- </view>
-
- <!-- 单向选择器 -->
- <view v-if="item.type == 7" style="width: 100%;">
- <radio-group @change="radioChange($event,item)">
- <view class="as-layout-horizontal">
- <label style="display: flex;flex-direction: row;margin-right: 30rpx;"
- v-for="(itemData, index) in item.itemData" :key="index">
- <radio color="#1AAC1B" style="transform:scale(0.7)" :value="itemData.value"
- :checked="itemData.checked" />
- <view>{{itemData.name}}</view>
- </label>
- </view>
- </radio-group>
- </view>
-
- <!-- 证件照上传 -->
- <view v-if="item.type == 8" style="width: 100%;">
- <view style="margin: 0 40rpx;">
- <view class="text-error">
- {{item.hint && item.hint.split(',')[0] ? item.hint.split(',')[0] : ''}}
- </view>
- <view class="as-layout-horizontal as-gravity-center" style="height: 260rpx;margin-top: 20rpx;"
- :class="{dan:item.inputType === '999'}">
- <view class="as-layout-vertical as-gravity-center" style="width: 90%;height: 100%;">
- <image
- :src="item.placeholderImg ? item.placeholderImg.split(',')[0] : '../../static/image/license2.png'"
- style="width: 100%;height: 80%;" :style="item.style" @tap="ImageSelection(item,1)"></image>
- <view class="as-gravity-center text-hint" style="margin-top: 5rpx;">
- {{item.hint && item.hint.split(',')[1] ? item.hint.split(',')[1] : ''}}
- </view>
- </view>
- <view style="width: 40rpx;"></view>
- <view class="as-layout-vertical" style="width: 90%;height: 100%;" v-if="item.inputType != '999'">
- <image
- :src="item.placeholderImg && item.placeholderImg.split(',')[1] ? item.placeholderImg.split(',')[1] : '../../static/image/license2.png'"
- style="width: 100%;height: 80%;" @tap="ImageSelection(item,2)"></image>
- <view class="as-gravity-center text-hint" style="margin-top: 5rpx;">
- {{item.hint && item.hint.split(',')[2] ? item.hint.split(',')[2] : ''}}
- </view>
- </view>
- </view>
- </view>
- </view>
-
- <!-- 车牌号输入 -->
- <view v-if="item.type == 9" style="width: 100%">
- <view style="margin: 20rpx 30rpx 0 30rpx;">
- <car-num-ber-input @numberInputResult="numberInputResult($event,item)" :defaultStr='item[item.value]'>
- </car-num-ber-input>
- </view>
- </view>
-
- <!-- 省市区选择器 -->
- <view v-if="item.type == 10" style="width: 100%">
- <pick-regions :defaultRegion="defaultRegionCode" @getRegion="handleGetRegion($event,item)">
- <view class="text">
- {{handleTxt(item)}}
- </view>
- </pick-regions>
- </view>
-
- <!-- 短信验证码 -->
- <view v-if="item.type == 11" style="width: 100%;">
- <view class="as-layout-horizontal as-gravity-center">
- <input v-model="item[item.value]" type="number"
- :placeholder="item.hint ? item.hint : '请输入' + item.title" placeholder-class="text-hint"
- class="text as-gravity-center-start" :maxlength="item.maxlength" :style="item.style"
- style="min-height: 90rpx;word-break:break-all" />
-
- <button style="width: 160rpx;font-size: 24rpx;height: 60rpx" :disabled="item.disabled"
- @click="SMSsending($event,item)">{{item.hint ? item.hint : '获取验证码'}}</button>
- </view>
-
- </view>
-
- <!-- 隐私协议 -->
- <view v-if="item.type == 12" style="width: 100%;">
- <view class="as-layout-horizontal as-gravity-center">
- <checkbox value="cb" />请先阅读并同意
- <a style="color:#007AFF;text-decoration: underline;">《开户服务协议》</a>
- </view>
- </view>
-
-
- <!-- 车牌颜色 -->
- <view v-if="item.type == 13" style="width: 100%;">
- <licensePlateColor @numberplateResult="numberplateResult($event,item)" :defaultStr='item[item.value]'
- :vanType='vanType'>
- </licensePlateColor>
- </view>
- <!-- 上传图片,证件照等 -->
- <view v-if="item.type == 14" style="width: 100%;">
- <upload-car-img :dataList='item' @uploadImgHandle='uploadImgHandle($event,item)' />
- </view>
- <!-- <view v-if="item.type == 15" style="width: 100%;">
- <view class="input-box">
- <text class="sub-label">长</text>
- <input v-model="state.outlineL" @input="outlineInput" :disabled="state.isEnableChangeOCRCarInfo" />
- <text class="sub-text">X</text>
- <text class="sub-label">宽</text>
- <input v-model="state.outlineW" @input="outlineInput" :disabled="state.isEnableChangeOCRCarInfo" />
- <text class="sub-text">X</text>
- <text class="sub-label">高</text>
- <input v-model="state.outlineH" @input="outlineInput" :disabled="state.isEnableChangeOCRCarInfo" />
- <text class="sub-text">mm</text>
- </view>
- </view> -->
-
- <!-- 车辆用户类型选择 -->
- <view v-if="item.type == 101" style="width: 100%;">
- <CarUserType :dataList='item' @useCarUserType='useCarUserType($event,item)' />
- </view>
- <!-- 汽车尺寸处理 -->
- <view v-if="item.type == 102" style="width: 100%;">
-
- </view>
- <!-- 用户类型选择 -->
- <view v-if="item.type == 103" style="width: 100%;">
- <UserType :dataList='item' @useUserType='useUserType($event,item)' />
- </view>
- </view>
-
- </view>
-
- <!-- 最后一位不展示 且 设置为展示 -->
- <view v-show="item.underline" class="as-line-h" style="margin: 0rpx 20rpx 0rpx 20rpx;"></view>
- </view>
- </view>
-
- <view style="display: flex;flex-direction: row;">
- <button v-if="config.btnBack" class="back-bg as-gravity-center btn as-weight"
- @click="back">{{config.submitOneName ? config.submitOneName : '上一步'}}
- </button>
- <button class="btn btn-text as-gravity-center nav-bg as-weight"
- form-type="submit">{{config.submitName ? config.submitName : '提交'}}
- </button>
- </view>
-
- </form>
- </template>
- <script setup lang='ts'>
- import {
- TypeData
- } from './tools'
- import licensePlateColor from '@/components/LicensePlateColor.vue';
- import carNumBerInput from '@/components/car-number-input/car-number-input'
- import uploadCarImg from '@/components/upload-car-img/upload-car-img'
- import CarUserType from '@/components/CarUserType.vue'
- import UserType from '@/components/UserType.vue'
- import {
- pathToBase64
- } from '../../static/js/util/imageTool.js'
- import pickRegions from '@/components/pick-regions/pick-regions.vue'
- import {
- computed
- } from 'vue'
-
- const defaultRegionCode = '520115'
- const props = defineProps({
- vanType: {
- default: 'all'
- },
- formData: {
- type: Array as() => Array < TypeData > ,
- // type: Array as() => Array < any > ,
- default: () => []
- },
- config: {
- type: Object,
- default: function() {
- return {
- submitName: '提交', //提交按钮名称
- titleWidth: 240, //标题宽度
- isHeader: false, //头部信息展示
- }
- }
- }
- })
-
-
- const emit = defineEmits < {
- (e: 'submit', content: any): void,
- (e: 'bindPickerChange', event: any, item: TypeData): void,
- (e: 'handleGetRegion', event: any, item: TypeData): void,
- (e: 'uploadImg', content: any, item: TypeData, index: Number): void,
- (e: 'radioChange', event: any, item: TypeData): void,
- (e: 'sendText', event: any, item: TypeData): void,
- (e: 'uploadImgOcr', fileLise: any, item: any): void,
- } > ()
- //defineExpose 可宏来显式指定在 <script setup> 组件中要暴露出去的属性。
-
- //普通选择器
- function bindPickerChange(e: any, item: TypeData) {
- let select = e.target.value
- // #ifdef H5
- select = e.detail.value
- // #endif
- if (item.mode == 'date' || item.mode == 'time') {
- /* 日期选择器*/
- item[item.value] = select
- } else {
- /* 普通选择器*/
- item[item.value] = select || item.itemData[select]
- }
- emit('bindPickerChange', e, item)
- }
- // 车辆选择器处理
- function useCarUserType(e, item) {
- item[item.value] = e
- }
-
- function useUserType(e, item) {
- item[item.value] = e
- console.log(e);
- }
-
- function handleTxt(item) {
- if (!item.value) {
- return '请选择省市区'
- }
- const str = item[item.value] || '请选择省市区'
- return str
- }
- // 获取选择的地区
- function handleGetRegion(e: any, item: TypeData) {
- item[item.value] = e[0].name + e[1].name + e[2].name
- emit('handleGetRegion', e, item);
- }
-
- //多项选择器
- function checkboxChange(e: any, item: TypeData) {
- item[item.value] = e.detail.value /* 赋值*/
- }
-
- //单项选择器
- function radioChange(e: any, item: TypeData) {
- item[item.value] = e.detail.value /* 赋值*/
- emit('radioChange', e, item)
- }
-
- //富文本框输入内容
- function textareaInput(e: Event, item: TypeData) {
- item.num = item[item.value].length
- }
-
- //点击图片按钮
- function backImg(e: Event, item: TypeData) {
- item[item.value] = e
- }
-
- function back(e: Event) {
-
- }
-
- //车牌输入
- function numberInputResult(e: any, item: TypeData) {
- var str = e.replace(/\s*/g, "");
- item[item.value] = str
- }
-
- function numberplateResult(e: any, item) {
- item[item.value] = e.id
- console.log(e);
- }
-
-
- //短信验证码发送
- function SMSsending(e: any, item: TypeData) {
- let time = 60;
- emit('sendText', e, item)
- const fn = setInterval(function() {
- time--
- item.hint = time + 's'
- item.disabled = true
- if (time == 0) {
- clearInterval(fn)
- item.disabled = false
- item.hint = '获取验证码'
- }
- }, 1000)
- }
-
- //选择图片按钮
- function ImageSelection(item: TypeData, index: number) {
- uni.chooseImage({
- count: 1, //最多可以选择的文件个数
- sourceType: ['camera'], //album 从相册选视频,camera 使用相机拍摄,默认为:['album', 'camera']
- success(res: any) {
- if (res.tempFiles[0].size > 2000000) {
- uni.showToast({
- title: '图片大于2M,请重新上传',
- icon: 'none',
- duration: 1500
- })
- return;
- }
- // #ifdef H5
- pathToBase64(res.tempFilePaths[0]).then(data => {
- emit('uploadImg', data, item, index)
- })
- // #endif
- },
- fail(res: any) {
- if (!res.authSetting['scope.album']) {
- uni.showModal({
- title: '授权失败',
- content: '需要从您的相机或相册获取图片,请在设置界面打开相关权限',
- success: (res) => {
- if (res.confirm) {
- uni.openSetting()
- }
- }
- })
- }
- }
- })
- }
-
- function showToast(hint: string) {
- uni.showToast({
- icon: 'none',
- title: hint
- })
- }
- // type为14,上传图片
- function uploadImgHandle(fileList, item) {
- emit('uploadImgOcr', fileList, item)
- }
- //内容提交
- function formSubmit() {
- let content = {}
- // console.log('data值', props.formData)
- /* 整理数据对象返回内容 */
- for (var i = 0; i < props.formData.length; i++) {
- let data = props.formData[i]
- if (data.show) continue;
- // console.log('data', data)
- /* 时间另外判断 */
- if (data.type == 7 && data[data.value] === undefined) {
- data[data.value] = data.itemData.find(item => item.checked).value
- }
- // 如果等于100说明是标题,跳过
- if (data.type == 100) {
- continue
- }
- if (data.required && !data.show) {
- let reg = new RegExp(':', 'g') //g代表全部
- let newMsg = data.title.replace(reg, '');
- if (data.value.indexOf(',') != -1 && data.type == 8) {
- if (!data[data.value.split(',')[0]]) {
- showToast(data.hint + "不能为空")
- return
- } else if (!data[data.value.split(',')[1]]) {
- showToast(data.hint + "不能为空")
- return
- }
- } else if (data[data.value] === undefined || data[data.value] === '') {
- showToast(newMsg + "不能为空")
- return
- }
- }
- if (data.type == 2 && !data.show) {
- if (data.checkReg) {
- let regs = new RegExp(data.checkReg) //g代表全部
- if (!regs.test(data[data.value])) {
- showToast(data.checkPrompt || data.title + '校验失败')
- return
- }
- }
- if (data.minlength && data[data.value].length && +data.minlength > data[data.value].length) {
- showToast(data.title + '最小长度为' + data.minlength)
- return
- }
- }
-
- if (data.value.indexOf(',') != -1 && data.type == 8) {
- if (data[data.value.split(',')[0]]) {
- content[data.value.split(',')[0]] = data[data.value.split(',')[0]]
- }
- if (data[data.value.split(',')[1]]) {
- content[data.value.split(',')[1]] = data[data.value.split(',')[1]]
- }
- } else if (data.type == 10) {
- for (var s = 0; s < data.value.split(',').length; s++) {
- if (data[data.value]) {
- content[data.value.split(',')[s]] = data[data.value].split('-')[s]
- }
- }
- } else {
- if (data.type == 4 && data.name && data[data.value]) {
- content[data.value] = data[data.value][data.name]
- } else {
- content[data.value] = data[data.value]
- }
- }
- }
- emit('submit', content)
- }
- </script>
- <style lang='scss' scoped>
- .img-size {
- width: 30rpx;
- height: 30rpx;
- }
-
- .upload-car-bottom {
- font-size: 32rpx;
- text-align: left;
- margin: 15rpx 30rpx;
- }
-
- .header-info {
- padding: 40rpx 40rpx 10rpx;
-
- .title {
- font-size: 28rpx;
- color: #000;
- font-weight: bold;
- }
-
- .info {
- margin-top: 8rpx;
- font-size: 24rpx;
- color: #999;
- }
- }
-
- .btn {
- height: 80rpx;
- opacity: 1;
- border-radius: 100rpx;
- margin: 20rpx 20rpx 20rpx 20rpx;
- }
-
- .btn-text {
- color: #FFFFFF;
- font-size: 28rpx;
- }
-
- .nav-bg {
- /* background: linear-gradient(to right, #13E7C1, #43A1E0); */
- border: 1px solid #FFFFFF;
- background: #1AAC1B;
- }
-
- .back-bg {
- border: 1px solid #1AAC1B;
- color: #1AAC1B;
- background: #FFFFFF;
- }
-
- ::v-deep .uni-picker-container .uni-picker-action.uni-picker-action-confirm {
- background-color: blue;
- color: #1AAC1B;
- /* 添加其他样式属性 */
- }
-
- .dan {
- width: 50%;
- }
- </style>
|