| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- <template>
- <view class="formBox">
- <view :class="['input_list', { 'scan_page': scanPage }]">
- <block v-for="(item, index) in localFormConfigList" :key="index">
- <!-- **********************switch开关 -->
- <view
- :class="['input_item', 'input_item_fir', !scanPage && 'border_bottom', item.className]"
- v-if="item.type == 'switch' && item.isShow == '1' && isInclude(currentType, item.store.type)"
- >
- <view class="input_tit">{{ item.label }}</view>
- <switch
- class="public_switch"
- :checked="item.defValue == 'true' && isInclude(currentType, item.store.type)"
- @change="switchChange($event, item.vModel)"
- />
- </view>
- <!-- ******************************input框 -->
- <view
- :class="['input_item', !scanPage && 'border_bottom', item.className]"
- v-if="item.type == 'text' && item.isShow == '1' && isInclude(currentType, item.store.type)"
- >
- <view class="input_tit">{{ item.label }}</view>
- <view class="input_con">
- <input
- class="input"
- @blur="setVal($event, item.vModel)"
- :value="item.defValue"
- placeholder-class="placeholder"
- :placeholder="item.placeholder"
- />
- <!-- 获取验证码 -->
- <block v-if="item.vModel == 'provingCode'">
- <view
- :class="['code_con_txt', disabledBtn ? '' : 'colorCustom']"
- @click="getCode"
- v-if="seconds <= 0"
- >获取验证码</view>
- <view class="code_con_txt colorCustom" v-else>{{ seconds }}秒后重新获取</view>
- </block>
- <!-- 获取手机号 -->
- <block v-if="(item.vModel == 'certNum' || item.vModel == 'guardianCertNum') && showPhotoImg">
- <view class="code_con_txt" @click="photoBtnClick">
- <image class="photo_btn" :src="iconUrl.photograph"></image>
- </view>
- </block>
- </view>
- </view>
- <!-- ****************************单选框 -->
- <view
- :class="['input_item', !scanPage && 'border_bottom', item.className]"
- v-if="item.type == 'radio' && item.isShow == '1' && isInclude(currentType, item.store.type)"
- >
- <view class="input_tit">{{ item.label }}</view>
- <view class="input_con">
- <view class="radio_list">
- <view
- :class="['radio_item', item.defValue == optIndex ? 'backgroundCustom' : '']"
- v-for="(cell, optIndex) in item.options"
- :key="optIndex"
- @click="radioClick(item.vModel, optIndex)"
- >{{ cell.label }}</view>
- </view>
- </view>
- </view>
- <!-- ********************************日期框 -->
- <view
- :class="['input_item', !scanPage && 'border_bottom', item.className]"
- v-if="item.type == 'datePicker' && item.isShow == '1' && isInclude(currentType, item.store.type)"
- >
- <view class="input_tit">{{ item.label }}</view>
- <picker
- mode="date"
- @change="setVal($event, item.vModel)"
- :end="today"
- :value="item.defValue"
- >
- <view class="input_con">
- <input class="input" disabled :value="item.defValue" />
- <image class="public_right_img" :src="iconUrl.icon_right"></image>
- </view>
- </picker>
- </view>
- <!-- ****************************下拉框 -->
- <view
- :class="['input_item', !scanPage && 'border_bottom', item.className]"
- v-if="item.type == 'select' && item.isShow == '1' && isInclude(currentType, item.store.type)"
- >
- <view class="input_tit">{{ item.label }}</view>
- <picker
- @change="pickerChange($event, item.vModel)"
- :value="item.defValue"
- :range="item.options"
- range-key="label"
- :disabled="item.isDisabled"
- >
- <view class="input_con">
- <input
- :class="['input', item.isDisabled && 'inputDisabled']"
- disabled
- :value="item.options[item.defValue] ? item.options[item.defValue].label : ''"
- />
- <image class="public_right_img" :src="iconUrl.icon_right"></image>
- </view>
- </picker>
- </view>
- <!-- ****************************省市区 -->
- <view
- :class="['input_item', !scanPage && 'border_bottom', item.className]"
- v-if="item.type == 'region' && item.isShow == '1' && isInclude(currentType, item.store.type)"
- >
- <view class="input_tit">{{ item.label }}</view>
- <picker
- @change="regionChange($event, item.vModel)"
- mode="region"
- :value="item.defValue"
- >
- <view class="input_con">
- <view class="input">{{ item.defValue || '请选择' + item.label }}</view>
- <image class="public_right_img" :src="iconUrl.icon_right"></image>
- </view>
- </picker>
- </view>
- <!-- ***************************** 提示 -->
- <view
- class="tip"
- v-if="item.type == 'tip' && isInclude(currentType, item.store.type)"
- >{{ item.label }}</view>
- </block>
- </view>
- <view class="public_btn backgroundCustom_F08" @click="toSelect">{{ btnName }}</view>
- <view
- class="public_btn addHealthCard colorCustom"
- @click="toRelation"
- v-if="showRelation"
- >已有健康卡,一键快速关联</view>
- <canvas
- canvas-id="pressCanvas"
- class="press-canvas"
- :style="{ width: windowWidth + 'px', height: windowWidth + 'px' }"
- ></canvas>
- </view>
- </template>
- <script lang="ts" setup>
- import { ref, reactive, watch, onMounted } from 'vue';
- import { uploadZxFileUrl, idCardVerification, sendVerificationCode_V3 } from '@/pagesPersonal/service';
- import { common,imgCompress } from '@/utils';
- import icon from '@/utils/icon';
- import store from '@/store';
- const props = defineProps({
- /**form表单列表 */
- formConfigList: {
- type: Array,
- default: () => []
- },
- /**当前方式 default 默认(身份识别) children新生儿(监护人身份证) */
- currentType: {
- type: String,
- default: ''
- },
- /**
- * 按钮名称
- */
- btnName: {
- type: String,
- default: '下一步'
- },
- /**
- * 是否在健康卡身份证识别页面
- * 此页面需要修改form样式
- */
- scanPage: {
- type: Boolean,
- default: false
- },
- /**
- * 证件号码input后面是否展示照相机图片
- */
- showPhotoImg: {
- type: Boolean,
- default: true
- },
- /**
- * 是否展示 关联健康卡按钮
- */
- showRelation: {
- type: Boolean,
- default: false
- }
- });
- const emit = defineEmits(['toSelect']);
- const iconUrl = ref(icon)
- const mobile = ref(''); //获取验证码时用到的手机号
- const pcId = ref(''); //验证码pcId,
- const seconds = ref(0); //获取验证码剩余时间
- const disabledBtn = ref(true); //获取验证码按钮是否禁用
- const windowWidth = ref(0);
- const today = ref('');
- const localFormConfigList = ref<any[]>([]);
- const currentType = ref('');
- let timer: any = null;
- onMounted(() => {
- const sysInfo = uni.getSystemInfoSync();
- windowWidth.value = sysInfo.windowWidth;
- });
- watch(
- () => props.formConfigList,
- (newVal) => {
- if (!common.isEmpty(newVal)) {
- let cType = props.currentType;
- let fList = JSON.parse(JSON.stringify(newVal)); // Deep copy to avoid mutating prop
- fList.map((item: any) => {
- item.store = common.isJSON(item.store) ? JSON.parse(item.store) : item.store;
- item.options = common.isJSON(item.options) ? JSON.parse(item.options) : item.options;
- /**日期初始化 */
- if (item.type == 'datePicker') {
- item.defValue = common.newDay();
- }
- });
- if (!cType) {
- if (fList.filter((item: any) => item.vModel == 'children' && item.defValue == 'true').length > 0) {
- /**如果新生儿已开启 */
- cType = 'children';
- } else {
- cType = 'default';
- }
- }
- fList.sort((a: any, b: any) => {
- if (a.store.index && b.store.index) {
- return Number(a.store.index) - Number(b.store.index);
- } else {
- return 1;
- }
- });
- fList = setFormConfigList(fList);
-
- today.value = common.newDay();
- localFormConfigList.value = fList;
- currentType.value = cType;
- }
- },
- { immediate: true, deep: true }
- );
- // WXS helper replacement
- const isInclude = (str: string, strs: string | string[]) => {
- if (strs && strs.indexOf(str) != -1) {
- return true;
- } else {
- return false;
- }
- };
- /**
- * 读取身份证按钮点击
- */
- const photoBtnClick = async () => {
- let resp = await chooseImage();
- if (!common.isEmpty(resp)) {
- let data = await upLoad(resp);
- if (!common.isEmpty(data)) {
- let queryData = {
- filePath: data.url.replace(/\\/g, '/'),
- type: 1 //1身份证 2户口本
- };
- let { resData } = await idCardVerification(queryData);
- if (resData.RespCode == 10000 && resData.Data) {
- let idCardInfo = resData.Data;
- let fList = localFormConfigList.value;
- let cType = currentType.value;
- fList.map((item) => {
- if (cType == 'children') {
- /**如果是新生儿 给监护人证件信息赋值 */
- if (item.vModel == 'guardianName') {
- item.defValue = idCardInfo[0].Names;
- } else if (item.vModel == 'guardianCertNum') {
- item.defValue = idCardInfo[0].IdCards;
- }
- } else {
- /**否则给当前就诊人证件信息赋值 */
- if (item.vModel == 'memberName') {
- item.defValue = idCardInfo[0].Names;
- } else if (item.vModel == 'certNum') {
- item.defValue = idCardInfo[0].IdCards;
- }
- }
- });
- localFormConfigList.value = fList;
- }
- }
- }
- };
- /**选取照片 */
- const chooseImage = () => {
- return new Promise((resolve) => {
- uni.chooseImage({
- count: 1,
- sourceType: ['album', 'camera'],
- /**album:从相册选图 camera:使用相机 */
- success: (res) => {
- resolve(res);
- }
- });
- });
- };
- /**
- * 上传图片
- */
- const upLoad = (resp: any) => {
- uni.showLoading({
- mask: true
- });
- return new Promise<any>((resolve) => {
- imgCompress.getLessLimitSizeImage(
- 'pressCanvas',
- resp.tempFilePaths[0],
- 1,
- windowWidth.value,
- (path: string) => {
- uni.uploadFile({
- url: uploadZxFileUrl,
- filePath: path,
- name: 'newsFile',
- formData: {
- user: 'test'
- },
- header: {
- token: store.state.token
- },
- success(res) {
- uni.hideLoading();
- let data = JSON.parse(res.data);
- if (data.RespCode == '10000') {
- resolve(data);
- } else {
- common.showModal('图片上传失败');
- resolve(false);
- }
- }
- });
- }
- );
- });
- };
- /**
- * 点击获取验证码
- */
- const getCode = async () => {
- if (disabledBtn.value) {
- return;
- }
- let queryData = {
- mobile: mobile.value
- };
- let { resData } = await sendVerificationCode_V3(queryData);
- if (resData.RespCode == 10000 && resData.Data) {
- pcId.value = resData.Data[0].pcId;
- common.showModal('发送成功!');
- startCountDown();
- }
- };
- const startCountDown = () => {
- if (timer) clearInterval(timer);
- seconds.value = 60;
- disabledBtn.value = true;
- timer = setInterval(() => {
- seconds.value--;
- if (seconds.value <= 0) {
- clearInterval(timer);
- seconds.value = 0;
- disabledBtn.value = false;
- }
- }, 1000);
- };
- /**
- * 滑块开关
- */
- const switchChange = async (e: any, key: string) => {
- let value = e.detail.value;
- let cType = currentType.value;
- let fList = localFormConfigList.value;
- fList.map((item) => {
- if (item.vModel == key) {
- item.defValue = value ? 'true' : 'false';
- }
- });
- if (value && key == 'children') {
- cType = key;
- } else if (key == 'children') {
- /**关闭新生儿 */
- cType = 'default';
- }
- /**开启新生儿时 显示性别和出生日期 关闭时隐藏*/
- fList.map((cell) => {
- if (cell.vModel == 'sex' || cell.vModel == 'birthDate') {
- if (key == 'children') {
- /**判断当前证件类型是否为身份证 如果是身份证 不显示性别和出生日期 */
- let certType = fList.filter((item) => item.vModel == 'certType')[0];
- cell.isShow = value
- ? '1'
- : certType.options[certType.defValue].value == '01'
- ? '0'
- : '1';
- }
- }
- });
- fList = setFormConfigList(fList);
- currentType.value = cType;
- localFormConfigList.value = fList;
- };
- /**
- * 选择证件类型
- */
- const pickerChange = (e: any, key: string) => {
- let value = e.detail.value;
- let fList = localFormConfigList.value;
- let cType = currentType.value;
- fList.map((item) => {
- if (item.vModel == key) {
- item.defValue = value;
- if (item.vModel == 'certType' && cType != 'children') {
- fList.map((cell) => {
- /**如果选择的不是身份证 显示性别和出生日期(新生儿页面不隐藏) */
- if (cell.vModel == 'sex' || cell.vModel == 'birthDate') {
- cell.isShow = item.options[value].value != '01' ? '1' : '0';
- }
- /**如果选择的不是身份证 禁用验证方式选择 */
- if (cell.vModel == 'checkType') {
- cell.isDisabled = item.options[value].value != '01' ? true : false;
- cell.defValue = 0;
- }
- /**如果选择的不是身份证 显示手机号和验证码*/
- if (cell.vModel == 'userMobile' || cell.vModel == 'provingCode') {
- cell.isShow = 1;
- }
- });
- }
- /**选择验证方式 */
- if (item.vModel == 'checkType') {
- fList.map((cell) => {
- /**如果选择的不是手机号验证 隐藏手机号和验证码 1手机号验证 2人脸*/
- if (cell.vModel == 'userMobile' || cell.vModel == 'provingCode') {
- cell.isShow = item.options[value].value == '1' ? '1' : '0';
- }
- });
- }
- }
- });
- localFormConfigList.value = fList;
- };
- /**
- * 省市区选择器
- */
- const regionChange = (e: any, key: string) => {
- let value = e.detail.value;
- let fList = localFormConfigList.value;
- fList.map((item) => {
- if (item.vModel == key) {
- item.defValue = value;
- }
- });
- localFormConfigList.value = fList;
- };
- /**
- * 输入框赋值
- */
- const setVal = (e: any, key: string) => {
- let fList = localFormConfigList.value;
- let value = e.detail.value;
- fList.map((item) => {
- if (item.vModel == key) {
- item.defValue = value;
- /**输入手机号时 判断发送验证码按钮显隐 */
- if (item.vModel == 'userMobile') {
- let reg = new RegExp(item.regularExpressions);
- let disabled = true;
- if (reg.test(item.defValue)) {
- disabled = false;
- }
- disabledBtn.value = disabled;
- mobile.value = item.defValue;
- }
- /**输入身份证号时 转换大写*/
- if (item.vModel == 'certNum' || item.vModel == 'guardianCertNum') {
- item.defValue = item.defValue.toUpperCase();
- }
- }
- });
- localFormConfigList.value = fList;
- };
- /**
- * 单选框点击
- */
- const radioClick = (key: string, index: number) => {
- let fList = localFormConfigList.value;
- fList.map((item) => {
- if (item.vModel == key) {
- item.defValue = index;
- }
- });
- localFormConfigList.value = fList;
- };
- /**
- * 点击下一步
- */
- const toSelect = async () => {
- await common.sleep();
- emit('toSelect', {
- formConfigList: localFormConfigList.value,
- currentType: currentType.value,
- pcId: pcId.value
- });
- };
- /**
- * 点击关联健康卡
- */
- const toRelation = () => {
- /**点击关联健康卡 给父组件一个relation为true判断 */
- emit('toSelect', {
- relation: true
- });
- };
- // 设置圆角
- const setFormConfigList = (fList: any[]) => {
- fList.forEach((item, index) => {
- item.className = '';
- if (item.type == 'tip' && item.isShow == '1') {
- for (let i = 1; i < index; i++) {
- if (fList[index - i].isShow == '1') {
- fList[index - i].className = 'toBoderRadio';
- break;
- }
- }
- }
- });
- return fList;
- };
- </script>
- <style lang="scss" scoped>
- .formBox {
- padding: 0 30upx;
- }
- .input_list {
- display: inline-block;
- width: 100%;
- overflow: hidden;
- border-radius: 24upx;
- }
- .input_item {
- height: 110upx;
- display: flex;
- align-items: center;
- position: relative;
- margin-bottom: -4upx;
- background: #fff;
- padding: 0 30upx;
- }
- .public_right_img {
- right: 30upx;
- }
- .input_con {
- width: 460upx;
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
- .input_tit {
- font-size: 30upx;
- color: rgba(85, 85, 85, 1);
- width: 230upx;
- flex-shrink: 0;
- }
- .radio_list {
- width: 100%;
- display: flex;
- align-items: center;
- }
- .radio_item {
- padding: 6upx 48upx;
- font-family: PingFangSC-Medium, PingFang SC;
- font-weight: 500;
- color: #fff;
- background-color: #ccc;
- border-radius: 64upx;
- line-height: 44upx;
- margin-right: 24upx;
- }
- .input {
- padding: 20upx 0;
- }
- .public_btn {
- margin: 60upx 30upx;
- }
- .code_con .input {
- width: 300upx;
- }
- .code_con_txt {
- font-size: 28upx;
- white-space: nowrap;
- padding: 20upx 0 20upx 20upx;
- color: #999;
- }
- .input_item_fir {
- justify-content: space-between;
- }
- .tip {
- font-size: 30upx;
- font-family: Source Han Sans CN;
- font-weight: 500;
- color: rgba(1, 1, 1, 1);
- padding: 20upx 0;
- background-color: #f1f1f6;
- position: relative;
- }
- .tip + .input_item {
- border-radius: 24upx 24upx 0 0;
- }
- .tip:before,
- .tip:after {
- content: '';
- display: block;
- width: 30upx;
- height: 100%;
- background-color: #f1f1f6;
- top: 0;
- position: absolute;
- }
- .tip:before {
- left: -30upx;
- }
- .tip:after {
- right: -30upx;
- }
- .btnBox {
- width: 150upx;
- }
- .btnBox button {
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: transparent;
- }
- .disabledBtn {
- opacity: 0.5;
- }
- .photo_btn {
- width: 40upx;
- height: 36upx;
- }
- .press-canvas {
- position: absolute;
- top: -2000upx;
- background-color: gray;
- }
- .inputDisabled {
- color: #999;
- }
- .scan_page .input_item {
- height: 80upx;
- line-height: 24upx;
- }
- .addHealthCard {
- border: 1px solid;
- font-family: PingFangSC-Regular, PingFang SC;
- font-weight: 400;
- margin-top: -10upx;
- }
- .toBoderRadio {
- border-radius: 0 0 30upx 30upx;
- }
- </style>
|