Commit 0b77380e authored by 肖健's avatar 肖健

新增省市区;更改bug;挪车码领取页面初版

parent a4665bad
{
"id": "active-form",
"name": "表单 动态表单 uniapp最强动态表单 表单校验 快速生成表单 全端支持",
"name": "京东挪车牌",
"version": "1.1.0",
"description": "最强动态表单 以js的方式快速生成表单接口 支持表单校验 ui设计师样式优化",
"description": "京东挪车牌",
"keywords": [
"表单",
"动态表单",
"表单校验",
"快速生成表单",
"全端"
"挪车牌"
],
"dependencies": {
"crypto-js": "^4.1.1",
......
......@@ -57,6 +57,13 @@
{
"path": "pages/login/wv-common/wv-common",
"style": {}
},
{
"path": "pages/mrAct/index",
"style": {
"navigationBarTitleText": "京东挪车码领取",
"enablePullDownRefresh": false
}
}
],
"subPackages": [
......
......@@ -363,7 +363,7 @@
if(jdNavToObj){
uni.removeStorageSync('jdNavToObj')
this.$goToLocation(item)
this.$goToLocation(jdNavToObj)
}
}
......
<!-- 挪车码领取活动页面 -->
<template>
<view style="background-color: #fff;">
<view class="car_info">
<view class="info_list" style="padding:20rpx 0;">
<view class="left">
品牌车型:
</view>
<view class="right info" style="width:500rpx;" v-if="carInfo" @click="getCarList">
<image :src="carInfo.logoUrl" mode=""></image>
<view>
<view>
{{carInfo.brand + "-" + carInfo.seriesName}}
</view>
{{carInfo.carModel}}
</view>
<image class="gt" src="@/static/move-car/move-car-code1.png">
</view>
<view class="right" style="width:500rpx;" v-else @click="getCarList">
<text style="margin-right:10rpx;color:#999;">请选择</text>
<image class="gt" src="@/static/move-car/move-car-code1.png">
</view>
</view>
</view>
<view style="margin: 0 auto; width: 90%;">
<u--form labelPosition="left" errorType="toast" :labelStyle="{'fontSize': '32rpx'}" labelWidth="200rpx" :model="actInfo" :rules="rules" ref="form1">
<u-form-item label="收货人:" prop="userName" borderBottom>
<u--input v-model="actInfo.userName" maxlength="50" border="none" inputAlign="right"></u--input>
</u-form-item>
<u-form-item label="收货电话:" prop="telNumber" borderBottom>
<u--input v-model="actInfo.telNumber" maxlength="20" border="none" inputAlign="right" @change="checkMobileInfo"></u--input>
</u-form-item>
<u-form-item label="收货地址:" prop="address" borderBottom>
<u--input v-model="actInfo.address" @tap="chooseAddress" placeholder="省/市/区" disabled disabledColor="transparent" border="none" inputAlign="right"></u--input>
<u-icon slot="right" name="arrow-right" @tap="chooseAddress"></u-icon>
</u-form-item>
<u-form-item label="详细地址:" prop="detailInfo" borderBottom>
<u--input v-model="actInfo.detailInfo" maxlength="100" border="none" inputAlign="right"></u--input>
</u-form-item>
<u-form-item label="验证码:" prop="smsCode" borderBottom>
<u--input v-model="actInfo.smsCode" type="number" maxlength="6" border="none" inputAlign="right"></u--input>
<view slot="right" style="margin-left: 20rpx;border-left: 2rpx solid rgba(0,0,0,.1);padding-left:20rpx;">
<text style="font-size:32rpx; " @tap="getCode">{{tips}}</text>
</view>
</u-form-item>
<u-form-item v-if="captcha" label="图形验证:" prop="vc" borderBottom>
<u--input v-model="actInfo.vc" maxlength="20" border="none" inputAlign="right" ></u--input>
<image slot="right" :src="captchaImg" style="width: 101px; height: 38px;margin-left: 20rpx;" @click="getCaptchaImage"></image>
</u-form-item>
</u--form>
<u-button type="primary" text="提交" @click="submitAct" :disabled="disabledSubmit"></u-button>
<u-code ref="uCode" @change="codeChange" seconds="60" @start="disabled1 = true" @end="disabled1 = false"></u-code>
<address-picker :show="addressShow" @confirm="addressConfirm" @cancel="addressCancel"></address-picker>
<!-- 爱车选择弹框 -->
<u-popup :show="selectCar" mode="bottom" round="10" @close="selectCar = false">
<view class="love_car_list">
<view class="love_title">
选择车辆
<text @click.stop="selectCar = false">x</text>
</view>
<view class="love_list">
<view v-if="carList.length != 0">
<view class="love_item" v-for="(item,i) in carList" :key="i" @click="radioChange(item)">
<image :src="item.logoUrl"></image>
<view class="love_info">
<view>
{{item.brand + "-" + item.seriesName}}
</view>
<view>
{{item.carModel}}
</view>
</view>
<view class="radio">
<image src="@/static/move-car/radio-active.png" v-if="item.id === radioValue"></image>
<image src="@/static/move-car/radio.png" v-else></image>
</view>
</view>
</view>
<view style="padding-top:140rpx;text-align: center;" v-else>
暂时没有车辆,请添加!
</view>
</view>
<view class="love_btn">
<button type="primary" @click="addCar">
<image src="@/static/move-car/love-car5.png">添加车辆
</button>
</view>
</view>
</u-popup>
</view>
</view>
</template>
<script>
export default {
data() {
return {
addressShow:false,
//获取短信验证码相关 begin
disabled1: false,
tips : '',
//获取短信验证码相关 end
//选择车辆相关 begin
selectCar:false,
radioValue:"",
//选择车辆id
carId: '',
carList:[],
carInfo: null,
//选择车辆相关 end
disabledSubmit:false,
//是否已经领取过
already: true,
//已经领取的错误提示文案
alreadyMsg : '',
//是否要显示图形验证码
captcha : false,
captchaImg : '',
actInfo: {
carId:'',
userName: '',
telNumber: '',
address: '',
detailInfo: '',
vc:'',
vi: '',
smsCode: '',
},
rules: {
'carId': [{
type: 'string',
required: true,
message: '请选择品牌车型',
trigger: ['blur', 'change']
}],
'userName': [{
type: 'string',
required: true,
message: '请填写收货人',
trigger: ['blur', 'change']
}],
'telNumber': [
{
type: 'string',
required: true,
message: '请填写收货电话',
trigger: ['blur', 'change']
},
{
// 自定义验证函数,见上说明
validator: (rule, value, callback) => {
// 上面有说,返回true表示校验通过,返回false表示不通过
// uni.$u.test.mobile()就是返回true或者false的
return uni.$u.test.mobile(value);
},
message: '收货电话格式不正确',
// 触发器可以同时用blur和change
trigger: ['change','blur'],
}
],
'address': [{
type: 'string',
required: true,
message: '请选择收货地址',
trigger: ['blur', 'change']
}],
'detailInfo': [{
type: 'string',
required: true,
message: '请输入详细地址',
trigger: ['blur', 'change']
}],
'smsCode': [{
type: 'number',
required: true,
message: '请输入短信验证码',
trigger: ['blur', 'change']
}],
'vc': [
{
type: 'string',
required: false,
message: '请输入图形验证码',
trigger: ['blur', 'change']
},
{
// 自定义验证函数,见上说明
validator: (rule, value, callback) => {
if(this.captcha) {
if(!value) {
return false
}
}
return true
},
message: '请输入图形验证码',
// 触发器可以同时用blur和change
trigger: ['change','blur'],
}
],
},
}
},
methods: {
chooseAddress() {
this.addressShow = true
},
addressConfirm(e) {
this.addressShow = false
this.actInfo.address = e.value.join('/');
},
addressCancel() {
this.addressShow = false
},
codeChange(text) {
this.tips = text;
},
getCode() {
let that = this
if(!that.actInfo.telNumber) {
uni.$u.toast('请填写收货电话')
return
}
if(!uni.$u.test.mobile(that.actInfo.telNumber)) {
uni.$u.toast('收货电话格式不正确')
return
}
if (that.$refs.uCode.canGetCode) {
// 模拟向后端请求验证码
uni.showLoading({
title: '正在获取短信验证码'
})
that.$http.request({
url:'/app/smsCode/mr_activity',
method:'post',
data:{phone: that.actInfo.telNumber},
load:false
}).then(res => {
uni.hideLoading();
// 这里此提示会被this.start()方法中的提示覆盖
uni.$u.toast('验证码已发送');
// 通知验证码组件内部开始倒计时
that.$refs.uCode.start();
})
} else {
//uni.$u.toast('倒计时结束后再发送');
}
},
// 选择爱车
radioChange(item){
this.carInfo = item
this.radioValue = item.id
this.selectCar = false
this.actInfo.carId = item.id
},
// 获取爱车列表
getCarList(){
this.$http.request({
url:'/app/vehicleAdmin/list',
method:'get',
data:{},
isFactory:false,
}).then(res => {
this.carList = res.data || []
this.selectCar = true
})
},
// 添加车辆
addCar() {
this.selectCar = false
uni.navigateTo({
url: '/pages/transitionPage'
});
},
//活动检查信息
getCaptchaImage() {
let that = this
that.$http.request({
url:'/app/move/activity/captchaImage',
method:'get',
data:{ },
load:false
}).then(res => {
that.actInfo.vi = res.uuid
that.captchaImg = 'data:image/gif;base64,' + res.img
})
},
//活动检查信息
async getActCheckInfo() {
let that = this
await that.$http.request({
url:'/app/move/activity/c',
method:'get',
data:{ },
isFactory:false,
load:false
}).then(res => {
that.already = res.already
if(that.already) {
that.disabledSubmit = true
}
that.alreadyMsg = res.alreadyMsg
})
},
//活动检查手机信息
async checkMobileInfo() {
let that = this
let token = uni.getStorageSync('userToken')
let telNumber = that.actInfo.telNumber
if(!uni.$u.test.mobile(telNumber) || !token) {
return
}
await that.$http.request({
url:'/app/move/activity/c/m',
method:'post',
data:{ telNumber : telNumber},
load:false
}).then(res => {
that.captcha = res.captcha
//为true的时候加载图形验证码
if(that.captcha) {
that.getCaptchaImage()
}
})
},
//活动检查信息
submitAct() {
let that = this
that.$refs.form1.validate().then(res => {
let data = JSON.parse(JSON.stringify(that.actInfo))
let address = data.address.split('/')
data.address = null;
data.province = address[0]
data.city = address[1]
data.district = address[2]
let opts = {
url: '/app/move/activity',
method: 'post'
}
that.http.httpTokenRequest(opts, data).then(res => {
let code = res.data.code
if (code == 200) {
console.log('success', res)
} else if (code == 1000000003 || code == 1000000004) {
that.getCaptchaImage()
uni.$u.toast(res.data.msg)
} else if (code == 1000000005) { //禁用领取按钮
that.disabledSubmit = true
} else{
uni.$u.toast(res.data.msg)
}
})
}).catch(errors => {
if(!that.actInfo.carId) {
uni.$u.toast('请选择品牌车型')
return
}
if(errors && errors.length > 0) {
uni.$u.toast(errors[0].message)
}
})
},
},
onReady() {
this.$refs.form1.setRules(this.rules)
},
onLoad(option) {
let that = this
let token = uni.getStorageSync('userToken')
if(token) {
that.getActCheckInfo()
// that.getCaptchaImage()
}
},
}
</script>
<style lang="scss" scoped>
// 爱车列表
.love_car_list{
padding:30rpx 40rpx;
.love_title{
text-align: center;
font-size: 36rpx;
font-weight: bold;
margin-bottom:30rpx;
position: relative;
text{
position: absolute;
right:20rpx;
top:-4rpx;
font-size:40rpx;
font-weight:500;
color: #666;
}
}
.love_list{
height:400rpx;
overflow: auto;
.love_item{
padding:20rpx 0;
display: flex;
align-items: center;
justify-content: space-between;
border-top: 2rpx solid #E8E8E8;
&:first-child{
border:none;
}
image{
width:100rpx;height:100rpx;
}
.love_info{
width:450rpx;
>view{
&:first-child{
font-size:34rpx;
font-weight: bold;
margin-bottom:10rpx;
}
&:last-child{
font-size: 28rpx;
color:#666;
}
}
}
.radio{
width:60rpx;
>image{
width:48rpx;height:48rpx;
}
}
}
}
.love_btn{
padding:50rpx;
button {
height:80rpx;
line-height:80rpx;
border-radius:50rpx;
// background: linear-gradient(150deg, #E1251B, #E14A1B);
background: linear-gradient(-36deg, #1C81E8, #1CA2E8);
box-shadow:2rpx 4rpx 6rpx 0 rgba(20, 68, 225, 0.29);
// box-shadow: 0 6rpx 13rpx 2rpx rgba(225, 50, 27, 0.17);
border:0;
font-size:32rpx !important;
>image{
width:30rpx;height:30rpx;
margin-right:10rpx;
position: relative;
top:4rpx;
}
}
}
}
// 已绑定车辆信息
.car_info{
background: #FFFFFF;
background-color: #fff;
padding:0 40rpx;
position: relative;
top:-6rpx;
.select-car{
line-height:80rpx;
text-align: right;
font-size: 28rpx;
color: #E1251B;
}
.info_list{
line-height:90rpx;
display: flex;
justify-content: space-between;
align-items: center;
// border-bottom:2rpx solid rgba(0,0,0,.1);
.left{
font-size: 32rpx;
}
.right{
font-size: 28rpx;
color: #666;
line-height: 1.8;
word-wrap:break-word;
text-align: right;
&.info{
display: flex;
align-items: center;
justify-content: flex-end;
text-align: left;
// padding:20rpx 0;
image{
max-width:48rpx;height: 48rpx;
}
>view{
margin:0 10rpx;
line-height: 1.5;
>view{
font-weight:bold;
font-size: 32rpx;
color: #333;
}
}
}
.car__input{
width: 100%;
}
.gt{
max-width:16rpx !important;height:20rpx !important;
}
}
}
.car_btn{
width: 400rpx;
line-height: 76rpx;
background: #FFFFFF;
border: 2rpx solid #DDDDDD;
border-radius: 10rpx;
text-align: center;
margin:30rpx auto 0;
font-size: 32rpx;
color: #666;
}
}
</style>
\ No newline at end of file
## 1.0.3(2022-12-18)
三级联动地区选择器,根据uView的picker选择器二次封装,所以使用时记得安装uVIew和scss
## 1.0.2(2022-12-18)
三级联动地区选择器,根据uView的picker选择器二次封装,所以使用时记得安装uVIew和scss
## 1.0.1(2022-12-18)
基于uView封装的地区选择器,内置了地区数据,只在vue2的微信小程序做了测试,所以其余平台全部是X
## 1.0.0(2022-12-18)
基于uView封装的地区选择器,内置了地区数据,只在vue2的微信小程序做了测试,所以其余平台全部是X
<template>
<view class="">
<u-picker :show="show" ref="uPicker" :title="title" :showToolbar="showToolbar" :itemHeight="itemHeight"
:cancelText="cancelText" :cancelColor="cancelColor" :confirmText="confirmText" :confirmColor="confirmColor"
:loading="loading" :visibleItemCount="visibleItemCount" :defaultIndex="indexs" :columns="columns"
:closeOnClickOverlay="closeOnClickOverlay" @confirm="confirm" @close="close" @cancel="cancel"
@change="changeHandler">
</u-picker>
</view>
</template>
<script>
import area from "../../province-city-county.json"
export default {
props: {
show: {
type: Boolean,
default: () => false
},
title: {
type: String,
default: () => ""
},
showToolbar: {
type: Boolean,
default: () => true
},
itemHeight: {
type: [String, Number],
default: () => 44
},
cancelText: {
type: String,
default: () => "取消"
},
cancelColor: {
type: String,
default: () => "#909193"
},
confirmText: {
type: String,
default: () => "确认"
},
confirmColor: {
type: String,
default: () => "#3c9cff"
},
visibleItemCount: {
type: [String, Number],
default: () => 5
},
loading: {
type: Boolean,
default: () => false
},
indexs: Array,
closeOnClickOverlay: Boolean,
addressData:{
type:Object,
default:()=>{}
}
},
data(){
return {
columns: [],
province: [],
city: [],
area: [],
}
},
mounted(){
this.formatData()
},
methods: {
changeHandler(e) {
const {
columnIndex,
value,
values, // values为当前变化列的数组内容
indexs,
picker = this.$refs.uPicker
} = e
if (columnIndex === 0) {
picker.setColumnValues(1, this.city[indexs[0]].map(v => v.name))
picker.setColumnValues(2, this.area[indexs[0]][0].map(v => v.name))
}
if (columnIndex === 1) {
picker.setColumnValues(2, this.area[indexs[0]][indexs[1]].map(v => v.name))
}
},
formatData() {
this.province = area.map(t => {
return {
name: t.name,
areaId: t.areaId
}
})
this.city = area.map(t => t.children.map(v => {
return {
name: v.name,
areaId: v.areaId
}
}))
this.area = area.map(t => t.children.map(v => v.children.map(i => {
return {
name: i.name,
areaId: i.areaId
}
})))
//默认显示数据
this.columns = [
this.province.map(res => res.name),
this.city[0].map(res => res.name),
this.area[0][0].map(res => res.name)
]
//数据回显
if (this.addressData?.province && this.addressData?.city && this.addressData?.area) {
//省索引
let pIdx = this.province.findIndex(v => v.name == this.addressData.province);
//根据省索引设置默认市数据
this.columns[1] = this.city[pIdx].map(res => res.name)
//市索引
let cIdx = this.city[pIdx].findIndex(v => v.name == this.addressData.city);
//根据市索引设置默认区数据
this.columns[2] = this.area[pIdx][cIdx].map(res => res.name)
//区索引
let aIdx = this.area[pIdx][cIdx].findIndex(v => v.name == this.addressData.area);
this.indexs = [pIdx, cIdx, aIdx];
}
},
confirm(e) {
this.$emit("confirm", e)
},
close() {
this.$emit("close")
},
open() {
this.$emit("open")
this.formatData()
},
cancel(){
this.$emit("cancel")
}
}
}
</script>
<style>
</style>
{
"id": "address-picker",
"displayName": "三级联动地区选择器,address-picker,包含港澳台",
"version": "1.0.3",
"description": "三级联动地区选择器,根据uView的picker选择器二次封装,所以使用时记得安装uVIew和scss",
"keywords": [
"address-picker",
"address",
"picker",
"地区",
"地区选择器"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "n"
},
"App": {
"app-vue": "u",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
},
"H5-pc": {
"Chrome": "y",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
# address-picker
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment