123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718 |
- <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; /* 赋值*/
- console.log(e, item);
- 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) {
- // @ts-ignore
- let values = data[data.value];
- if (!values && values !== 0) {
- values = data.itemData.find((item) => item.checked).value;
- }
- values = parseInt(values);
- data[data.value] = isNaN(values)
- ? data.itemData.find((item) => item.checked).value
- : values;
- }
- // 如果等于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>
|