上集: https://blog.csdn.net/lmyhplay/article/details/139111979
本集,来具体讲解一下,这个省市区三级联动的小程序收件地址是如何实现的。 其中本节讲解的知识点是: 如何定义一个公共的地址组件。
1、 设计
1.1 缓存设计 pinia
由于从服务器端获取省市区的JSON数据有点大, 故需缓存在客户端,vue3中的 pinia 来缓存状态。
定义一个 store/index.js
import { defineStore } from 'pinia'
export const regionDataStore = defineStore('regionData', {
state: () => {
return {
regions: []
}
},
actions: {
setRegions(regions) {
this.regions = regions;
},
},
})
1.2 定义一个地址组件,用于任意地方使用
地址组件是一个小程序工程中多个地方要使用的,采用公共组件的形式会大大缩短工作量。另一方面:公共组件可以提高小程序的稳定性和重用性。
那么在VUE3 中 如何定义一个地址组件呢?
定义一个地址组件: pages/component/MyAddress.vue
<template>
<nut-address
:bizType="bizType"
:visible="showAddress"
:province="address.province"
:city="address.city"
:country="address.country"
:town="address.town"
@change="onChange"
@close="close"
@close-mask="closeMask"
custom-address-title="请选择所在地区"
></nut-address>
</template>
<script type="ts">
import { emit, reactive, toRefs, defineExpose, ref, onMounted } from 'vue';
import Req from '../../http/request'
import { globalDataStore, regionDataStore } from '../../store'
export default {
name: 'myAddress',
props: {
showAddress: Boolean,
bizType: String
},
setup(props,context) {
console.log('--> props='+JSON.stringify(props));
console.log('--->wrong here <---');
const regionStore = regionDataStore();
console.log('--->wrong here 1 <---');
const userStore = globalDataStore();
console.log('--->wrong here 2 <---');
const state = reactive(
{
userInfo: userStore.userInfo,
province_code: '',
city_code: '',
country_code: '',
province: '',
city: '',
country: '',
town: '',
regions: regionStore.regions,
address: {
province: [],
city: [],
country: [],
town: [],
},
});
const initProvice = () => {
let province = [];
state.regions.forEach( r => {
if (r.children ) {
province.push({ id: r.code, name: r.name});
}
});
let address = state.address;
address.province = province;
state.address = address;
};
// id : code, 由省级编码来找出市级列表
const initCity = (id) => {
console.log('--> initCity code = ' + id);
let city = [];
state.regions.forEach( r => {
if (r.code == id) {
let citys = r.children
citys.forEach( ct => {
city.push({ id: ct.code, name: ct.name});
});
}
});
let address = state.address;
address.city = city;
state.address = address;
};
// 由省、市级编码来找乡镇列表
const initCountry = (provice_code, city_code) => {
let province = state.regions.find( re => re.code == provice_code);
let citys = province.children ;
let city = citys.find( ct => ct.code == city_code) ;
let country = city.children ;
let address = state.address;
address.country = country;
state.address = address;
};
const getRegions = () => {
console.log("--->call getRegions <----");
if (state.regions && state.regions.length > 0) {
console.log("--->从缓存中获取 regions <----");
initProvice()
return ;
}
let params = {};
let header = {"Authorization": state.userInfo.token };
Req('/pub/getThreeLevelRegionTrees', 'GET', params, true, header)
.then(response => {
console.log('---> result =' + JSON.stringify(response));
if (response.resCode == '0') {
let regions = response.data;
state.regions = regions;
regionStore.setRegions(regions);
initProvice()
}
})
};
const onChange = (val) => {
console.log('-->onChange='+JSON.stringify(val));
if ( val.custom == 'province' ) {
state.province = val.value.name;
state.province_code = val.value.id;
console.log('-->state.province_code='+state.province_code);
initCity(val.value.id)
}else if ( val.custom == 'city' ) {
state.city = val.value.name;
state.city_code = val.value.id;
initCountry(state.province_code, val.value.id)
}else if ( val.custom == 'country' ) {
state.country = val.value.name;
state.country_code = val.value.id;
}
else if ( val.custom == 'town' ) {
state.town = val.value.name;
}
// {"custom":"province","value":{"id":1,"name":"北京"},"next":"city"}
//{"custom":"city","value":{"id":7,"name":"朝阳区"},"next":"country"}
// {"custom":"country","value":{"id":3,"name":"八里庄街道"}}
};
const closeMask = () => {
context.emit("closeMask","close");
console.log('-->遮罩关闭<---');
};
const close = (val) => {
console.log('---address:'+ JSON.stringify(val));
let bean = { province: state.province, city: state.city, country: state.country, town: state.town, bizType: props.bizType}
context.emit("closeAddress",bean);
console.log('--->子组件调用父组件方法<-----');
// {"data":{"addressIdStr":"1_7_3_0","addressStr":"北京朝阳区八里庄街道","province":{"id":1,"name":"北京"},"city":{"id":7,"name":"朝阳区"},"country":{"id":3,"name":"八里庄街道"}},"type":"custom"}
};
onMounted(()=> {
console.log('--->公共组件 onMounted call <---');
getRegions();
});
return {
...toRefs(state),
onChange,
close,
props,
getRegions,
initProvice,
initCity,
initCountry,
}
}
}
</script>
<style lang="scss">
</style>
本组件直接使用 Taro 的 <nut-address > 组件。
现对关键的实现做一个说明:
import { globalDataStore, regionDataStore } from '../../store'
这一步就是将在 pinia 中定义的 regionDataStore 引入进来。
props: { showAddress: Boolean, bizType: String },
注意组件有两个属性: showAddress 表示是否显示这个地址组件。
bizType: 代表业务类型, 用以区分是什么业务使用了地址组件。特别是在同一个页面使用到多个地址组件的场景,不致于业务数据混淆。
组件的属性由父组件 (即引用了公共组件的页面来传值)。
公共组件加载后, 会调用 getRegions() 方法。在 onMounted触发。
onMounted(()=> { console.log('--->公共组件 onMounted call <---'); getRegions(); });
以下是getRegions() 获取省市区嵌套JSON的服务器端接口。 如果从 state.regions 获取到数据就直接调用 initProvice() 来初始化一个省级列表集合,并赋值给 address 对象。
如果state.regions 没有数据,就直接从服务端请求,并将数据放在 pinia 状态中,见: regionStore.setRegions(regions);
const getRegions = () => { console.log("--->call getRegions <----"); if (state.regions && state.regions.length > 0) { console.log("--->从缓存中获取 regions <----"); initProvice() return ; } let params = {}; let header = {"Authorization": state.userInfo.token }; Req('/pub/getThreeLevelRegionTrees', 'GET', params, true, header) .then(response => { console.log('---> result =' + JSON.stringify(response)); if (response.resCode == '0') { let regions = response.data; state.regions = regions; regionStore.setRegions(regions); initProvice() } }) };
其中,从服务器端返回的省市区(2023年度)的JSON数据可以去 https://download.csdn.net/download/lmyhplay/89338381?spm=1001.2014.3001.5503 进行下载。
格式如下:
{"data":[{"code":"110000000000","children":[{"code":"110100000000","children":[{"code":"110101000000","name":"东城区"},{"code":"110102000000","name":"西城区"},{"code":"110105000000","name":"朝阳区"},{"code":"110106000000","name":"丰台区"},{"code":"110107000000","name":"石景山区"},{"code":"110108000000","name":"海淀区"},{"code":"110109000000","name":"门头沟区"},{"code":"110111000000","name":"房山区"},{"code":"110112000000","name":"通州区"},{"code":"110113000000","name":"顺义区"},{"code":"110114000000","name":"昌平区"},{"code":"110115000000","name":"大兴区"},{"code":"110116000000","name":"怀柔区"},{"code":"110117000000","name":"平谷区"},{"code":"110118000000","name":"密云区"},{"code":"110119000000","name":"延庆区"}],"name":"市辖区"}] ... }
地址组件的 onChange 方法, 即响应用户点击选择省、市、区文字触发的动作。 用户点击省,就
调用 initCity(val.value.id), 其中 val.value.id 就是JSON中的code 值,即省编码。
请注意:编码值是唯一的。
如果点击到市,就调用: initCountry(state.province_code, val.value.id),来加载出市市级下面的乡镇数据。 val.value.id对应的是市级编码。
const onChange = (val) => { console.log('-->onChange='+JSON.stringify(val)); if ( val.custom == 'province' ) { state.province = val.value.name; state.province_code = val.value.id; console.log('-->state.province_code='+state.province_code); initCity(val.value.id) }else if ( val.custom == 'city' ) { state.city = val.value.name; state.city_code = val.value.id; initCountry(state.province_code, val.value.id) }else if ( val.custom == 'country' ) { state.country = val.value.name; state.country_code = val.value.id; } else if ( val.custom == 'town' ) { state.town = val.value.name; } // {"custom":"province","value":{"id":1,"name":"北京"},"next":"city"} //{"custom":"city","value":{"id":7,"name":"朝阳区"},"next":"country"} // {"custom":"country","value":{"id":3,"name":"八里庄街道"}} };
另外:请注意, nut-address 组件的遮罩关闭和点击右上角的关闭按钮的关闭需要通知父组件将
地址组件的属性 showAddress 置于关闭状态,同时还需要将地址组件用户选择的省市区的对象传给父组件。 这个需要用到vue3 子组件如何向父组件传值的问题。
在子组件(即地址组件)中:如: 选择省市区后关闭地址组件的事件,见代码:
const close = (val) => { console.log('---address:'+ JSON.stringify(val)); let bean = { province: state.province, city: state.city, country: state.country, town: state.town, bizType: props.bizType} context.emit("closeAddress",bean); console.log('--->子组件调用父组件方法<-----'); // {"data":{"addressIdStr":"1_7_3_0","addressStr":"北京朝阳区八里庄街道","province":{"id":1,"name":"北京"},"city":{"id":7,"name":"朝阳区"},"country":{"id":3,"name":"八里庄街道"}},"type":"custom"} };
将地址省市区对象的参数值传给父组件:
context.emit("closeAddress",bean);
这句代码表示,调用父组件的 closeAddress 方法。
来看看父组件(即引用这个公共地址组件)是如何使用的。见代码:
首先是要引入地址组件:
import myAddress from '../components/MyAddress'
接着: 在 components 中,要将引入的子组件加入集合中:
export default { name: 'Index', components: { MyTabbar, UserCenter, IconFont, myAddress, },
引用子组件的代码:
<myAddress :showAddress="showAddress" :bizType="biz_teacher" @closeAddress="closeAddr" @closeMask="closeMask" ref="myAddressCom2"/>
showAddress: false , 在父组件中默认值为false
其中: @closeAddress="closeAddr" 用来捕获子组件调用的 closeAddress方法。
这样就完成了子组件的引用、传参、捕获子组件的方法,子组件向父组件调用方法并传参的整体逻辑。
将本页的代码全部放出,以便大家理解:
<template>
<div class="content">
<UserCenter/>
<nut-empty v-show="!authenInfo.teacher.mobile && !authenInfo.student.mobile " image="error" description="找不到任何注册记录">
<div style="margin-top: 10px">
<nut-button type="primary" @click="register">学员|教员注册</nut-button>
</div>
</nut-empty>
<nut-tabs v-model="value" auto-height @click="change">
<nut-tab-pane v-for="item in funcs" :title="item.name" :pane-key="item.type">
<!-- start of teacher -->
<div v-show="item.type == 'teacher'">
<!-- start of teacher -->
<nut-form v-show="authenInfo.teacher && authenInfo.teacher.name">
<nut-col :span="18">
<nut-form-item label="姓名" required>
<nut-input type="text" v-model="authenInfo.teacher.name" class="form-spec" />
</nut-form-item>
</nut-col>
<nut-col :span="6"> </nut-col>
<nut-col :span="18">
<nut-form-item label="个人图像">
<IconFont v-if="authenInfo.teacher.avatar"
size="80" :key="authenInfo.teacher.id"
:name="authenInfo.teacher.avatar"
></IconFont>
<IconFont v-else
size="80"
:name="defaultIcon"
></IconFont>
</nut-form-item>
</nut-col>
<nut-col :span="6">
<nut-uploader maximum="1" :before-xhr-upload="beforeXhrUpload"> </nut-uploader>
</nut-col>
<nut-col :span="20">
<nut-form-item label="认证时间">
<nut-input type="text" class="form-spec-small" v-model="authenInfo.teacher.authTime" readonly />
</nut-form-item>
</nut-col>
<nut-col :span="4"> </nut-col>
<nut-col :span="18">
<nut-form-item label="手机号" required>
<nut-input v-model="authenInfo.teacher.mobile" type="text" class="form-spec" readonly/>
</nut-form-item>
</nut-col>
<nut-col :span="6"> </nut-col>
<nut-col :span="18">
<nut-form-item label="系统编号">
<nut-input v-model="authenInfo.teacher.authenNo" type="text" class="form-spec" readonly/>
</nut-form-item>
</nut-col>
<nut-col :span="6"> </nut-col>
<nut-col :span="24">
<nut-form-item label="个人介绍">
<nut-textarea class="form-spec" v-model="authenInfo.teacher.brief" placeholder="字数不超过250" showCount="true" autoHeight="true"/>
</nut-form-item>
</nut-col>
<nut-col :span="20">
<nut-form-item label="联系地址所在区">
<nut-input v-model="authenInfo.teacher.address" type="text" class="form-spec-short" readonly/>
</nut-form-item>
</nut-col>
<nut-col :span="4">
<IconFont size="30" name="https://coding-2020.s3.cn-northwest-1.amazonaws.com.cn/assets/address.svg" @click="selectAddress" />
</nut-col>
<nut-col :span="24">
<nut-form-item label="详细地址">
<nut-input v-model="authenInfo.teacher.street" type="text" class="form-spec"/>
</nut-form-item>
</nut-col>
<nut-col :span="24">
<myAddress :showAddress="showAddress" :bizType="biz_teacher" @closeAddress="closeAddr" @closeMask="closeMask" ref="myAddressCom2"/>
</nut-col>
<nut-col :span="6"> </nut-col>
<nut-col :span="12" style="text-align:center;">
<nut-form-item>
<nut-button type="primary" @click="teacherSave">更新资料</nut-button>
</nut-form-item>
</nut-col>
<nut-col :span="6"> </nut-col>
</nut-form>
<nut-empty v-show="!authenInfo.teacher.name" image="error" description="暂未注册教员">
<div style="margin-top: 10px">
<nut-button type="primary" @click="register('teacher')">注册教员</nut-button>
</div>
</nut-empty>
<!-- end of teacher -->
</div>
<!-- end of teacher -->
<!-- start of student -->
<div v-show="item.type == 'student'">
<nut-collapse>
<nut-collapse-item name="box-student" title="学员信息">
<!-- start of student -->
<nut-form v-show="authenInfo.student && authenInfo.student.name">
<nut-col :span="18">
<nut-form-item label="姓名" required>
<nut-input type="text" v-model="authenInfo.student.name" class="form-spec" />
</nut-form-item>
</nut-col>
<nut-col :span="6"> </nut-col>
<nut-col :span="18">
<nut-form-item label="个人图像">
<IconFont v-if="authenInfo.student.avatar"
size="80" :key="authenInfo.student.id"
:name="authenInfo.student.avatar"
></IconFont>
<IconFont v-else
size="80"
:name="defaultIcon"
></IconFont>
</nut-form-item>
</nut-col>
<nut-col :span="6">
<nut-uploader maximum="1" :before-xhr-upload="beforeXhrUpload"> </nut-uploader>
</nut-col>
<nut-col :span="20">
<nut-form-item label="认证时间">
<nut-input type="text" class="form-spec-small" v-model="authenInfo.student.authTime" readonly />
</nut-form-item>
</nut-col>
<nut-col :span="4"> </nut-col>
<nut-col :span="18">
<nut-form-item label="手机号" required>
<nut-input v-model="authenInfo.student.mobile" type="text" class="form-spec" readonly/>
</nut-form-item>
</nut-col>
<nut-col :span="6"> </nut-col>
<nut-col :span="18">
<nut-form-item label="系统编号">
<nut-input v-model="authenInfo.student.authenNo" type="text" class="form-spec" readonly/>
</nut-form-item>
</nut-col>
<nut-col :span="6"> </nut-col>
<nut-col :span="24">
<nut-form-item label="个人介绍">
<nut-textarea class="form-spec" v-model="authenInfo.student.brief" placeholder="字数不超过250" showCount="true" autoHeight="true"/>
</nut-form-item>
</nut-col>
<nut-col :span="20">
<nut-form-item label="联系地址所在区">
<nut-input v-model="authenInfo.student.address" type="text" class="form-spec-short" readonly/>
</nut-form-item>
</nut-col>
<nut-col :span="4">
<IconFont size="30" name="https://coding-2020.s3.cn-northwest-1.amazonaws.com.cn/assets/address.svg" @click="selectAddress" />
</nut-col>
<nut-col :span="24">
<nut-form-item label="详细地址">
<nut-input v-model="authenInfo.student.street" type="text" class="form-spec"/>
</nut-form-item>
</nut-col>
<nut-col :span="24">
<myAddress :showAddress="showAddress" :bizType="biz_student" @closeAddress="closeAddr" @closeMask="closeMask" ref="myAddressCom"/>
</nut-col>
<nut-col :span="6"> </nut-col>
<nut-col :span="12" style="text-align:center;">
<nut-form-item>
<nut-button type="primary" @click="studentSave">更新资料</nut-button>
</nut-form-item>
</nut-col>
<nut-col :span="6"> </nut-col>
</nut-form>
<nut-empty v-show="!authenInfo.student" image="empty" description="暂未注册"></nut-empty>
<!-- end of student -->
</nut-collapse-item>
<nut-collapse-item name="student_archive" title="学员档案">
<nut-empty description="您还没有建立学员档案">
<div style="margin-top: 10px">
<nut-button type="primary" @click="archiveCreate">现在去创建</nut-button>
</div>
</nut-empty>
</nut-collapse-item>
</nut-collapse>
</div>
<!-- end of student -->
</nut-tab-pane>
</nut-tabs>
<div class="box" v-show="!userInfo.logined">
<nut-row>
<nut-col :span="10"> </nut-col>
<nut-col :span="4" style="text-align:center;">
<IconFont
size=40
name="https://coding-2020.s3.cn-northwest-1.amazonaws.com.cn/assets/not_logined.svg"
></IconFont>
</nut-col>
<nut-col :span="10"> </nut-col>
</nut-row>
<nut-row>
<nut-col :span="8"> </nut-col>
<nut-col :span="8">
您当前还未登录
</nut-col>
<nut-col :span="8"> </nut-col>
</nut-row>
<nut-row>
<nut-col :span="8"> </nut-col>
<nut-col :span="8">
<nut-button type="primary" @click="login">现在登录</nut-button>
</nut-col>
<nut-col :span="8"> </nut-col>
</nut-row>
</div>
<!-- start tabbar -->
<MyTabbar :activeName="activeName" />
<!-- end of tabbar -->
</div>
</template>
<script type="ts">
import { h, ref, reactive, toRefs, onMounted } from 'vue';
import MyTabbar from '../components/MyTabbar'
import UserCenter from '../components/userCenter'
import myAddress from '../components/MyAddress'
import { globalDataStore, authenStoreData,globalShopStore } from '../../store'
import Taro, {useRouter,getCurrentInstance} from '@tarojs/taro';
import { IconFont } from '@nutui/icons-vue-taro';
import Req from '../../http/request'
// import FormData from 'formdata-polyfill'
export default {
name: 'Index',
components: {
MyTabbar,
UserCenter,
IconFont,
myAddress,
},
setup() {
const userStore = globalDataStore();
const authenStore = authenStoreData();
const shopStore = globalShopStore();
const instance = getCurrentInstance();
let params = instance.router.params
console.log('---> params :'+JSON.stringify(params));
let value = params.value;
console.log('--->value = '+value);
if (!value ) {
value = 'student'
}
const state = reactive(
{
activeName: 'my',
biz_student: 'student',
biz_teacher: 'teacher',
showAddress: false,
uploadUrl: 'https://codingtechnic.com/pub/mini/fileUpload',
defaultIcon: 'https://coding-2020.s3.cn-northwest-1.amazonaws.com.cn/assets/people_default.png',
teacher: authenStore.authenInfo.teacher,
student: authenStore.authenInfo.student,
value: value,
funcs: [
{ name: '学员', type: 'student'},
{ name: '教员', type: 'teacher'},
],
userInfo: userStore.userInfo,
authenInfo: authenStore.authenInfo,
shop: shopStore.shop,
});
const closeMask = (msg) => {
state.showAddress = false;
console.log('closeMask调用');
};
const closeAddr = (bean) => {
console.log('--->子组件调用了父组件<----'+JSON.stringify(bean));
if ( !state.showAddress) {
console.log('---->地址组件已关闭<----');
return ;
}
state.showAddress = false;
let authenInfo = state.authenInfo
let addr = bean.province + bean.city + bean.country + bean.town
let bizType = bean.bizType;
console.log('--->公共地址组件,bizType='+bizType);
if (bizType == 'student') {
authenInfo.student.address = addr;
console.log('---> addr = ' + addr);
state.authenInfo = authenInfo
state.authenInfo.student = authenInfo.student
}else if (bizType == 'teacher') {
authenInfo.teacher.address = addr;
console.log('---> addr = ' + addr);
state.authenInfo = authenInfo
state.authenInfo.teacher = authenInfo.teacher
}
authenStore.setAuthenInfo(authenInfo);
};
const selectAddress = () => {
state.showAddress = true;
console.log('--->地址组件显示<----');
};
const teacherSave = () => {
let teacher = state.authenInfo.teacher ;
console.log('---->update teacher <-----'+JSON.stringify(teacher));
};
const studentSave = () => {
let student = state.authenInfo.student ;
console.log('---->update student<-----'+ JSON.stringify(student));
};
// 学员上传
const beforeXhrUpload = (taroUploadFile, options) => {
//taroUploadFile 是 Taro.uploadFile , 你也可以自定义设置其它函数
let header = {"Authorization": state.userInfo.token };
console.log('--->options='+JSON.stringify(options));
console.log('--->options.formData='+JSON.stringify(options.formData));
//const file = options.formData.get('file')
let formData = {};
//formData.file = options.taroFilePath;
formData.refer_id = state.authenInfo.student.id
formData.file_type = 'image'
formData.company_id = state.shop.company_id;
formData.type = 'student'
state.formData = formData
console.log('formData='+JSON.stringify(formData));
let params = "?refer_id="+formData.refer_id+"&file_type="+ formData.file_type+"&company_id="+formData.company_id+"&type="+formData.type;
let uploadUrl = state.uploadUrl+params;
console.log('--->uploadUrl='+uploadUrl);
state.uploadUrl = uploadUrl;
const uploadTask = taroUploadFile({
url: uploadUrl,
filePath: options.taroFilePath,
fileType: options.fileType,
header: {
"Authorization": state.userInfo.token
},
name: options.name,
success(res) {
let data = JSON.parse(res.data);
console.log('--->data='+JSON.stringify(data));
if (data.resCode == '0') {
let imgUrl = data.data;
console.log('--->imgUrl='+imgUrl);
let authenInfo = state.authenInfo
authenInfo.student.avatar = imgUrl
state.authenInfo = authenInfo
state.authenInfo.student = authenInfo.student
authenStore.setAuthenInfo(authenInfo);
console.log('---> 个人图像已重置<------');
Taro.showToast({
title: '图像更新成功',
icon: 'success',
duration: 2000,
mask: true
});
Taro.redirectTo({ url: '/pages/myauthen/myauthen?value=student' });
}else{
Taro.showToast({
title: data.resMsg,
icon: 'error',
duration: 2000,
mask: true
});
}
},
fail(fail) {
console.log('--->res='+JSON.stringify(fail));
}
});
};
const archiveCreate = () => {
console.log('---->create Now <-----')
};
const register = (type) => {
Taro.navigateTo({
url: '/pages/authenform/authenform?type='+type
});
};
const login = () => {
let history='/pages/myauthen/myauthen'
Taro.navigateTo({
url: '/pages/login/login?history='+history
});
};
const change = (value) => {
console.log('--->value='+value);
state.value = value;
if (value == 'student' ) {
}else{
}
};
const loadFont = () => {
wx.loadFontFace({
family: 'FZKT',
source: 'url("https://coding-2020.s3.cn-northwest-1.amazonaws.com.cn/assets/ktjt.ttf")',
success: function(res) {
console.log('字体加载成功');
},
fail: function(res) {
console.error('字体加载失败', res);
}
});
};
const getRegUsers = () => {
let header = {"Authorization": state.userInfo.token };
console.log('--->submit state.userInfo='+JSON.stringify(state.userInfo));
const accountInfo = Taro.getAccountInfoSync();
let appId = accountInfo.miniProgram.appId;
let shopId = shopStore.shop.id;
let bean = { openid: state.userInfo.openId, authen_type: 'wechat', shopid: shopId+"", authorizer_appid: appId };
console.log('--->读取注册信息表单数据 :'+JSON.stringify(bean));
state.requesting = true;
Req('/security_go/training/queryRegUsers', 'POST', bean, true, header )
.then(response => {
console.log('--->注册查询结果:'+JSON.stringify(response));
state.requesting = false;
if ( response && response.resCode == '0') {
let list = response.data
let authenInfo = state.authenInfo;
if (list && list.length > 0) {
let student = list.find ( item => item.type == 'student');
if (student) {
state.student = student;
authenInfo.student = student;
}
let teacher = list.find ( item => item.type == 'teacher');
if (teacher) {
state.teacher = teacher;
authenInfo.teacher = teacher;
}
state.authenInfo = authenInfo;
authenStore.setAuthenInfo(authenInfo);
}
}
})
};
onMounted(() => {
console.log('--->state.userInfo.logined='+state.userInfo.logined);
getRegUsers();
// loadFont();
});
return {
...toRefs(state),
login,
change,
register,
getRegUsers,
loadFont,
beforeXhrUpload,
archiveCreate,
studentSave,
selectAddress,
closeAddr,
closeMask,
teacherSave,
}
}
}
</script>
<style lang="less">
@import "../fonts/FZKT.css";
.content {
background-color: rgba(204,204,204, 0.3);
}
.box {
background-color: #FFF;
margin: 6px 10px 6px 10px;
padding: 10px;
}
.material {
padding: 3px;
display: flex;
flex-direction: column;
}
.name {
padding: 5px;
height: 35px;
color: #0066CC;
font-size: 22px;
font-family: 'FZKT'
}
.mobile {
padding: 5px;
height: 35px;
color: #CC3333;
font-size: 22px;
}
.footer {
position: fixed;
bottom: 0;
width: 100%;
left: 0;
right: 0;
}
.form-spec input {
color: #000;
size: 26px;
width: 300px;
}
.form-spec-small input {
color: #000;
size: 16px;
width: 300px;
}
form-spec-short input {
color: #000;
size: 16px;
width: 200px;
}
</style>