Commit aa22ef8339052cde1e85c40515cd591d516b7543
1 parent
f7d384e5
会员地址管理CRUD
Showing
7 changed files
with
433 additions
and
40 deletions
yudao-ui-app/app.scss
yudao-ui-app/pages.json
| @@ -67,13 +67,13 @@ | @@ -67,13 +67,13 @@ | ||
| 67 | } | 67 | } |
| 68 | }, | 68 | }, |
| 69 | { | 69 | { |
| 70 | - "path": "pages/address/add", | 70 | + "path": "pages/address/create", |
| 71 | "style": { | 71 | "style": { |
| 72 | "navigationBarTitleText": "新增地址" | 72 | "navigationBarTitleText": "新增地址" |
| 73 | } | 73 | } |
| 74 | }, | 74 | }, |
| 75 | { | 75 | { |
| 76 | - "path": "pages/address/edit", | 76 | + "path": "pages/address/update", |
| 77 | "style": { | 77 | "style": { |
| 78 | "navigationBarTitleText": "修改地址" | 78 | "navigationBarTitleText": "修改地址" |
| 79 | } | 79 | } |
yudao-ui-app/pages/address/add.vue deleted
yudao-ui-app/pages/address/create.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <view class="container"> | ||
| 3 | + <view class="address-box"> | ||
| 4 | + <u--form labelPosition="left" :model="formData" :rules="rules" ref="form"> | ||
| 5 | + <u-form-item label="收件人名称" prop="name" labelWidth="90" borderBottom ref="item-name"> | ||
| 6 | + <u-input type="text" maxlength="11" v-model="formData.name" clearable placeholder="请填写收件人名称" border="none"></u-input> | ||
| 7 | + </u-form-item> | ||
| 8 | + | ||
| 9 | + <u-form-item label="手机号" prop="mobile" labelWidth="90" borderBottom ref="item-mobile"> | ||
| 10 | + <u-input type="number" maxlength="11" v-model="formData.mobile" clearable placeholder="请填写手机号" border="none"></u-input> | ||
| 11 | + </u-form-item> | ||
| 12 | + | ||
| 13 | + <u-form-item label="省市地区" prop="areaText" labelWidth="90" borderBottom @click=" regionVisible = true; hideKeyboard()" ref="item-areaText"> | ||
| 14 | + <u--input v-model="formData.areaText" disabled disabledColor="#ffffff" placeholder="请选择省市地区" border="none"></u--input> | ||
| 15 | + <u-icon slot="right" name="arrow-right"></u-icon> | ||
| 16 | + <w-picker :visible.sync="regionVisible" mode="region" :value="defaultRegion" default-type="value" :hide-area="false" @confirm="onConfirm($event, 'region')" @cancel="onCancel" ref="region"></w-picker> | ||
| 17 | + </u-form-item> | ||
| 18 | + | ||
| 19 | + <u-form-item label="详细地址" prop="detail" labelWidth="90" borderBottom ref="item-detail"> | ||
| 20 | + <u--textarea placeholder="请输入街道门牌号不低于6个字" v-model="formData.detail" count></u--textarea> | ||
| 21 | + </u-form-item> | ||
| 22 | + | ||
| 23 | + <u-form-item label="默认地址" prop="type" labelWidth="90" borderBottom ref="item-type"> | ||
| 24 | + <u-radio-group v-model="formData.type"> | ||
| 25 | + <u-radio :customStyle="{ marginRight: '16px' }" v-for="(item, index) in typeList" :key="index" :label="item.name" :name="item.value"></u-radio> | ||
| 26 | + </u-radio-group> | ||
| 27 | + </u-form-item> | ||
| 28 | + | ||
| 29 | + <view class="btn-group"> | ||
| 30 | + <u-button type="primary" text="保存地址" customStyle="margin-top: 50px" @click="handleSubmit"></u-button> | ||
| 31 | + </view> | ||
| 32 | + </u--form> | ||
| 33 | + </view> | ||
| 34 | + </view> | ||
| 35 | +</template> | ||
| 36 | + | ||
| 37 | +<script> | ||
| 38 | +import { createAddress } from '../../api/address' | ||
| 39 | + | ||
| 40 | +export default { | ||
| 41 | + data() { | ||
| 42 | + return { | ||
| 43 | + regionVisible: false, | ||
| 44 | + defaultRegion: ['110000', '110100', '110101'], | ||
| 45 | + typeList: [ | ||
| 46 | + { | ||
| 47 | + name: '是', | ||
| 48 | + value: 1 | ||
| 49 | + }, | ||
| 50 | + { | ||
| 51 | + name: '否', | ||
| 52 | + value: 2 | ||
| 53 | + } | ||
| 54 | + ], | ||
| 55 | + formData: { | ||
| 56 | + name: '', | ||
| 57 | + mobile: '', | ||
| 58 | + areaText: '', | ||
| 59 | + areaCode: '', | ||
| 60 | + detail: '', | ||
| 61 | + detailAddress: '', | ||
| 62 | + type: 1 | ||
| 63 | + }, | ||
| 64 | + rules: { | ||
| 65 | + name: [ | ||
| 66 | + { | ||
| 67 | + type: 'string', | ||
| 68 | + min: 2, | ||
| 69 | + max: 12, | ||
| 70 | + required: true, | ||
| 71 | + message: '请填写收件人名称', | ||
| 72 | + trigger: ['blur', 'change'] | ||
| 73 | + }, | ||
| 74 | + { | ||
| 75 | + message: '收件人名称不能为空', | ||
| 76 | + // 触发器可以同时用blur和change | ||
| 77 | + trigger: ['change', 'blur'] | ||
| 78 | + } | ||
| 79 | + ], | ||
| 80 | + mobile: [ | ||
| 81 | + { | ||
| 82 | + type: 'integer', | ||
| 83 | + required: true, | ||
| 84 | + message: '请填写手机号', | ||
| 85 | + trigger: ['blur', 'change'] | ||
| 86 | + }, | ||
| 87 | + { | ||
| 88 | + // 自定义验证函数,见上说明 | ||
| 89 | + validator: (rule, value, callback) => { | ||
| 90 | + // 上面有说,返回true表示校验通过,返回false表示不通过 | ||
| 91 | + // uni.$u.test.mobile()就是返回true或者false的 | ||
| 92 | + return uni.$u.test.mobile(value) | ||
| 93 | + }, | ||
| 94 | + message: '手机号码不正确', | ||
| 95 | + // 触发器可以同时用blur和change | ||
| 96 | + trigger: ['change', 'blur'] | ||
| 97 | + } | ||
| 98 | + ], | ||
| 99 | + areaText: { | ||
| 100 | + type: 'string', | ||
| 101 | + required: true, | ||
| 102 | + message: '请选择省市地区', | ||
| 103 | + trigger: ['blur', 'change'] | ||
| 104 | + }, | ||
| 105 | + detailAddress: { | ||
| 106 | + type: 'string', | ||
| 107 | + min: 6, | ||
| 108 | + max: 30, | ||
| 109 | + required: true, | ||
| 110 | + message: '请填写详细地址', | ||
| 111 | + trigger: ['blur', 'change'] | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | + } | ||
| 115 | + }, | ||
| 116 | + onLoad() {}, | ||
| 117 | + methods: { | ||
| 118 | + onConfirm(res) { | ||
| 119 | + this.formData.areaText = res.result | ||
| 120 | + this.formData.areaCode = res.value[2] | ||
| 121 | + }, | ||
| 122 | + onCancel() {}, | ||
| 123 | + hideKeyboard() { | ||
| 124 | + uni.hideKeyboard() | ||
| 125 | + }, | ||
| 126 | + handleSubmit() { | ||
| 127 | + this.$refs.form.validate().then(res => { | ||
| 128 | + this.formData.detailAddress = this.formData.areaText + this.formData.detail | ||
| 129 | + console.log(this.formData) | ||
| 130 | + createAddress(this.formData).then(res => { | ||
| 131 | + uni.$u.toast('地址已保存') | ||
| 132 | + setTimeout(() => { | ||
| 133 | + uni.navigateBack() | ||
| 134 | + }, 1000) | ||
| 135 | + }) | ||
| 136 | + }) | ||
| 137 | + } | ||
| 138 | + } | ||
| 139 | +} | ||
| 140 | +</script> | ||
| 141 | + | ||
| 142 | +<style lang="scss" scoped> | ||
| 143 | +.address-box { | ||
| 144 | + width: 690rpx; | ||
| 145 | + margin: 0 auto; | ||
| 146 | + padding-top: 30rpx; | ||
| 147 | +} | ||
| 148 | +</style> |
yudao-ui-app/pages/address/edit.vue deleted
yudao-ui-app/pages/address/list.vue
| 1 | <template> | 1 | <template> |
| 2 | - <view class="container"> </view> | 2 | + <view class="container"> |
| 3 | + <view class="address-list" v-for="(item, index) in addressList" :key="item.id"> | ||
| 4 | + <view class="address-item" @click="handleClick" @longpress="handleLongPress(item)"> | ||
| 5 | + <view class="left"> | ||
| 6 | + <u-avatar :text="item.name ? item.name.slice(0, 1) : 'U'" fontSize="18" randomBgColor></u-avatar> | ||
| 7 | + </view> | ||
| 8 | + <view class="middle"> | ||
| 9 | + <view class="info"> | ||
| 10 | + <view class="name">{{ item.name }}</view> | ||
| 11 | + <view class="mobile">{{ item.mobile }}</view> | ||
| 12 | + <u-tag class="type" v-if="item.type === 1" text="默认" plain size="mini" type="success"></u-tag> | ||
| 13 | + </view> | ||
| 14 | + <view class="detail"> | ||
| 15 | + <u--text :lines="2" size="14" color="#939393" :text="item.detailAddress"></u--text> | ||
| 16 | + </view> | ||
| 17 | + </view> | ||
| 18 | + <navigator class="right" :url="`/pages/address/update?addressId=${item.id}`" open-type="navigate" hover-class="none"> | ||
| 19 | + <u-icon name="edit-pen" size="28"></u-icon> | ||
| 20 | + </navigator> | ||
| 21 | + </view> | ||
| 22 | + </view> | ||
| 23 | + | ||
| 24 | + <navigator class="fixed-btn-box" url="/pages/address/create" open-type="navigate" hover-class="none"> | ||
| 25 | + <u-button type="primary" size="large" text="新增地址"></u-button> | ||
| 26 | + </navigator> | ||
| 27 | + <u-safe-bottom customStyle="background: #ffffff"></u-safe-bottom> | ||
| 28 | + </view> | ||
| 3 | </template> | 29 | </template> |
| 4 | 30 | ||
| 5 | <script> | 31 | <script> |
| 32 | +import { getAddressList, deleteAddress } from '../../api/address' | ||
| 33 | + | ||
| 6 | export default { | 34 | export default { |
| 7 | data() { | 35 | data() { |
| 8 | return { | 36 | return { |
| 9 | - title: '' | 37 | + addressList: [] |
| 10 | } | 38 | } |
| 11 | }, | 39 | }, |
| 12 | onLoad() {}, | 40 | onLoad() {}, |
| 13 | - methods: {} | 41 | + onShow() { |
| 42 | + this.loadAddressListData() | ||
| 43 | + }, | ||
| 44 | + methods: { | ||
| 45 | + loadAddressListData() { | ||
| 46 | + getAddressList().then(res => { | ||
| 47 | + this.addressList = res.data | ||
| 48 | + }) | ||
| 49 | + }, | ||
| 50 | + handleLongPress(item) { | ||
| 51 | + uni.showModal({ | ||
| 52 | + title: '提示', | ||
| 53 | + content: `删除收件人[${item.name}${item.mobile}]\n地址:${item.detailAddress.slice(0, 5)}......${item.detailAddress.slice(-6)}?`, | ||
| 54 | + success: res => { | ||
| 55 | + if (res.confirm) { | ||
| 56 | + deleteAddress({ id: item.id }).then(res => { | ||
| 57 | + uni.$u.toast('地址已删除') | ||
| 58 | + this.loadAddressListData(); | ||
| 59 | + }) | ||
| 60 | + } else if (res.cancel) { | ||
| 61 | + //console.log('用户点击取消') | ||
| 62 | + } | ||
| 63 | + } | ||
| 64 | + }) | ||
| 65 | + }, | ||
| 66 | + handleClick(){ | ||
| 67 | + // TODO 提交订单时选择地址逻辑 | ||
| 68 | + } | ||
| 69 | + } | ||
| 14 | } | 70 | } |
| 15 | </script> | 71 | </script> |
| 16 | 72 | ||
| 17 | -<style lang="scss" scoped></style> | 73 | +<style lang="scss" scoped> |
| 74 | +.address-list { | ||
| 75 | + .address-item { | ||
| 76 | + padding: 10rpx 0; | ||
| 77 | + border-bottom: $custom-border-style; | ||
| 78 | + @include flex-space-between; | ||
| 79 | + .left { | ||
| 80 | + margin: 20rpx; | ||
| 81 | + } | ||
| 82 | + .middle { | ||
| 83 | + flex: 1; | ||
| 84 | + margin: 20rpx; | ||
| 85 | + @include flex(column); | ||
| 86 | + .info { | ||
| 87 | + @include flex-left; | ||
| 88 | + .name { | ||
| 89 | + font-size: 30rpx; | ||
| 90 | + font-weight: 700; | ||
| 91 | + } | ||
| 92 | + .mobile { | ||
| 93 | + font-size: 28rpx; | ||
| 94 | + margin-left: 15rpx; | ||
| 95 | + } | ||
| 96 | + .type { | ||
| 97 | + margin-left: 15rpx; | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + .detail { | ||
| 101 | + margin-top: 10rpx; | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + .right { | ||
| 105 | + margin: 20rpx; | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +.fixed-btn-box { | ||
| 111 | + position: fixed; | ||
| 112 | + bottom: 0; | ||
| 113 | + left: 0; | ||
| 114 | + width: 750rpx; | ||
| 115 | +} | ||
| 116 | +</style> |
yudao-ui-app/pages/address/update.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <view class="container"> | ||
| 3 | + <view class="address-box"> | ||
| 4 | + <u--form labelPosition="left" :model="formData" :rules="rules" ref="form"> | ||
| 5 | + <u-form-item label="收件人名称" prop="name" labelWidth="90" borderBottom ref="item-name"> | ||
| 6 | + <u-input type="text" maxlength="11" v-model="formData.name" clearable placeholder="请填写收件人名称" border="none"></u-input> | ||
| 7 | + </u-form-item> | ||
| 8 | + | ||
| 9 | + <u-form-item label="手机号" prop="mobile" labelWidth="90" borderBottom ref="item-mobile"> | ||
| 10 | + <u-input type="number" maxlength="11" v-model="formData.mobile" clearable placeholder="请填写手机号" border="none"></u-input> | ||
| 11 | + </u-form-item> | ||
| 12 | + | ||
| 13 | + <u-form-item label="省市地区" prop="areaText" labelWidth="90" borderBottom @click=" regionVisible = true; hideKeyboard()" ref="item-areaText"> | ||
| 14 | + <u--input v-model="formData.areaText" disabled disabledColor="#ffffff" placeholder="请选择省市地区" border="none"></u--input> | ||
| 15 | + <u-icon slot="right" name="arrow-right"></u-icon> | ||
| 16 | + <w-picker :visible.sync="regionVisible" mode="region" :value="defaultRegion" default-type="value" :hide-area="false" @confirm="onConfirm($event, 'region')" @cancel="onCancel" ref="region"></w-picker> | ||
| 17 | + </u-form-item> | ||
| 18 | + | ||
| 19 | + <u-form-item label="详细地址" prop="detail" labelWidth="90" borderBottom ref="item-detail"> | ||
| 20 | + <u--textarea placeholder="请输入街道门牌号不低于6个字" v-model="formData.detail" count></u--textarea> | ||
| 21 | + </u-form-item> | ||
| 22 | + | ||
| 23 | + <u-form-item label="默认地址" prop="type" labelWidth="90" borderBottom ref="item-type"> | ||
| 24 | + <u-radio-group v-model="formData.type"> | ||
| 25 | + <u-radio :customStyle="{ marginRight: '16px' }" v-for="(item, index) in typeList" :key="index" :label="item.name" :name="item.value"></u-radio> | ||
| 26 | + </u-radio-group> | ||
| 27 | + </u-form-item> | ||
| 28 | + | ||
| 29 | + <view class="btn-group"> | ||
| 30 | + <u-button type="primary" text="更新地址" customStyle="margin-top: 50px" @click="handleSubmit"></u-button> | ||
| 31 | + </view> | ||
| 32 | + </u--form> | ||
| 33 | + </view> | ||
| 34 | + </view> | ||
| 35 | +</template> | ||
| 36 | + | ||
| 37 | +<script> | ||
| 38 | +import { getAddressById, updateAddress } from '../../api/address' | ||
| 39 | + | ||
| 40 | +export default { | ||
| 41 | + data() { | ||
| 42 | + return { | ||
| 43 | + id: '', | ||
| 44 | + regionVisible: false, | ||
| 45 | + defaultRegion: ['110000', '110100', '110101'], | ||
| 46 | + typeList: [ | ||
| 47 | + { | ||
| 48 | + name: '是', | ||
| 49 | + value: 1 | ||
| 50 | + }, | ||
| 51 | + { | ||
| 52 | + name: '否', | ||
| 53 | + value: 2 | ||
| 54 | + } | ||
| 55 | + ], | ||
| 56 | + formData: { | ||
| 57 | + id: '', | ||
| 58 | + name: '', | ||
| 59 | + mobile: '', | ||
| 60 | + areaText: '', | ||
| 61 | + areaCode: '', | ||
| 62 | + detail: '', | ||
| 63 | + detailAddress: '', | ||
| 64 | + type: 1 | ||
| 65 | + }, | ||
| 66 | + rules: { | ||
| 67 | + name: [ | ||
| 68 | + { | ||
| 69 | + type: 'string', | ||
| 70 | + min: 2, | ||
| 71 | + max: 12, | ||
| 72 | + required: true, | ||
| 73 | + message: '请填写收件人名称', | ||
| 74 | + trigger: ['blur', 'change'] | ||
| 75 | + }, | ||
| 76 | + { | ||
| 77 | + message: '收件人名称不能为空', | ||
| 78 | + // 触发器可以同时用blur和change | ||
| 79 | + trigger: ['change', 'blur'] | ||
| 80 | + } | ||
| 81 | + ], | ||
| 82 | + mobile: [ | ||
| 83 | + { | ||
| 84 | + type: 'integer', | ||
| 85 | + required: true, | ||
| 86 | + message: '请填写手机号', | ||
| 87 | + trigger: ['blur', 'change'] | ||
| 88 | + }, | ||
| 89 | + { | ||
| 90 | + // 自定义验证函数,见上说明 | ||
| 91 | + validator: (rule, value, callback) => { | ||
| 92 | + // 上面有说,返回true表示校验通过,返回false表示不通过 | ||
| 93 | + // uni.$u.test.mobile()就是返回true或者false的 | ||
| 94 | + return uni.$u.test.mobile(value) | ||
| 95 | + }, | ||
| 96 | + message: '手机号码不正确', | ||
| 97 | + // 触发器可以同时用blur和change | ||
| 98 | + trigger: ['change', 'blur'] | ||
| 99 | + } | ||
| 100 | + ], | ||
| 101 | + areaText: { | ||
| 102 | + type: 'string', | ||
| 103 | + required: true, | ||
| 104 | + message: '请选择省市地区', | ||
| 105 | + trigger: ['blur', 'change'] | ||
| 106 | + }, | ||
| 107 | + detailAddress: { | ||
| 108 | + type: 'string', | ||
| 109 | + min: 6, | ||
| 110 | + max: 30, | ||
| 111 | + required: true, | ||
| 112 | + message: '请填写详细地址', | ||
| 113 | + trigger: ['blur', 'change'] | ||
| 114 | + } | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + }, | ||
| 118 | + onLoad(e) { | ||
| 119 | + if (!e.addressId) { | ||
| 120 | + uni.$u.toast('请求参数错误') | ||
| 121 | + } else { | ||
| 122 | + this.id = e.addressId | ||
| 123 | + this.loadAddressData() | ||
| 124 | + } | ||
| 125 | + }, | ||
| 126 | + methods: { | ||
| 127 | + loadAddressData() { | ||
| 128 | + getAddressById({ id: this.id }).then(res => { | ||
| 129 | + this.formData = res.data | ||
| 130 | + this.initRegionData() | ||
| 131 | + }) | ||
| 132 | + }, | ||
| 133 | + initRegionData(){ | ||
| 134 | + //回显 【省市地区】 和 【详细地址】 信息 | ||
| 135 | + if (this.formData.areaCode) { | ||
| 136 | + const areaCode = this.formData.areaCode + '' | ||
| 137 | + //通过地区code反解析出【省-市-地区】code | ||
| 138 | + this.defaultRegion.splice(0, 3, areaCode.substring(0,2).padEnd(6, '0'), areaCode.substring(0,4).padEnd(6, '0'), areaCode) | ||
| 139 | + this.$nextTick(res => { | ||
| 140 | + let areaText = this.$refs.region._data.result.result | ||
| 141 | + this.formData.areaText = areaText | ||
| 142 | + //通过从完整详细地址除去【省-市-地区】得到后半段地址信息 | ||
| 143 | + this.formData.detail = this.formData.detailAddress.replace(areaText, '') | ||
| 144 | + this.$forceUpdate(); | ||
| 145 | + }) | ||
| 146 | + } | ||
| 147 | + }, | ||
| 148 | + onConfirm(res) { | ||
| 149 | + this.formData.areaText = res.result | ||
| 150 | + this.formData.areaCode = res.value[2] | ||
| 151 | + }, | ||
| 152 | + onCancel() {}, | ||
| 153 | + hideKeyboard() { | ||
| 154 | + uni.hideKeyboard() | ||
| 155 | + }, | ||
| 156 | + handleSubmit() { | ||
| 157 | + this.$refs.form.validate().then(res => { | ||
| 158 | + this.formData.detailAddress = this.formData.areaText + this.formData.detail | ||
| 159 | + console.log(this.formData) | ||
| 160 | + updateAddress(this.formData).then(res => { | ||
| 161 | + uni.$u.toast('地址已更新') | ||
| 162 | + setTimeout(() => { | ||
| 163 | + uni.navigateBack() | ||
| 164 | + }, 1000) | ||
| 165 | + }) | ||
| 166 | + }) | ||
| 167 | + } | ||
| 168 | + } | ||
| 169 | +} | ||
| 170 | +</script> | ||
| 171 | + | ||
| 172 | +<style lang="scss" scoped> | ||
| 173 | +.address-box { | ||
| 174 | + width: 690rpx; | ||
| 175 | + margin: 0 auto; | ||
| 176 | + padding-top: 30rpx; | ||
| 177 | +} | ||
| 178 | +</style> |