623 lines
14 KiB
Vue
623 lines
14 KiB
Vue
<template>
|
|
<div class="app-container">
|
|
<!-- 搜索表单 -->
|
|
<el-form
|
|
ref="searchFormRef"
|
|
:model="searchParams"
|
|
:inline="true"
|
|
label-width="auto"
|
|
size="small"
|
|
>
|
|
</el-form>
|
|
|
|
<!-- 主内容卡片 -->
|
|
<el-card class="content-box">
|
|
<!-- 操作按钮区域 -->
|
|
<div class="action-bar">
|
|
<el-button
|
|
size="mini"
|
|
type="primary"
|
|
@click="handleAddAddress"
|
|
>
|
|
新建收货地址
|
|
</el-button>
|
|
</div>
|
|
|
|
<!-- 地址列表表格 -->
|
|
<el-table
|
|
:data="addressList"
|
|
border
|
|
stripe
|
|
class="my-table"
|
|
show-overflow-tooltip
|
|
>
|
|
<el-table-column
|
|
type="index"
|
|
label="序号"
|
|
align="center"
|
|
width="80"
|
|
/>
|
|
<el-table-column
|
|
label="收货地址"
|
|
align="center"
|
|
>
|
|
<template slot-scope="{ row }">
|
|
{{ formatFullAddress(row) }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
label="操作"
|
|
align="center"
|
|
width="220"
|
|
>
|
|
<template slot-scope="{ row }">
|
|
<el-button
|
|
size="small"
|
|
type="text"
|
|
@click="handleEditAddress(row)"
|
|
>
|
|
编辑
|
|
</el-button>
|
|
<el-button
|
|
size="small"
|
|
type="text"
|
|
class="danger-text"
|
|
@click="handleDeleteAddress(row.id)"
|
|
>
|
|
删除
|
|
</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<!-- 分页组件 -->
|
|
<div class="pagination-wrapper">
|
|
<pagination
|
|
:total="total"
|
|
:page.sync="searchParams.pageNum"
|
|
:limit.sync="searchParams.pageSize"
|
|
@pagination="getAddressListData"
|
|
/>
|
|
</div>
|
|
</el-card>
|
|
|
|
<!-- 地址编辑对话框 -->
|
|
<el-dialog
|
|
:title="dialogTitle"
|
|
:visible="dialogVisible"
|
|
width="40%"
|
|
align-center
|
|
append-to-body
|
|
@close="handleDialogClose"
|
|
>
|
|
<el-form
|
|
ref="addressFormRef"
|
|
:model="addressForm"
|
|
:rules="addressFormRules"
|
|
label-position="right"
|
|
label-width="auto"
|
|
>
|
|
<el-row :gutter="20">
|
|
<!-- 省份选择 -->
|
|
<el-col :span="24">
|
|
<el-form-item
|
|
label="所在省"
|
|
prop="provinceCode"
|
|
>
|
|
<el-select
|
|
v-model="addressForm.provinceCode"
|
|
placeholder="请选择省"
|
|
clearable
|
|
style="width: 95%"
|
|
@change="handleProvinceChange"
|
|
>
|
|
<el-option
|
|
v-for="item in provinceList"
|
|
:key="item.areaId"
|
|
:value="item.areaCode * 1"
|
|
:label="item.areaName"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-col>
|
|
|
|
<!-- 城市选择 -->
|
|
<el-col :span="24">
|
|
<el-form-item
|
|
label="所在市"
|
|
prop="cityCode"
|
|
>
|
|
<el-select
|
|
v-model="addressForm.cityCode"
|
|
placeholder="请选择市"
|
|
clearable
|
|
style="width: 95%"
|
|
@change="handleCityChange"
|
|
>
|
|
<el-option
|
|
v-for="item in cityList"
|
|
:key="item.areaId"
|
|
:value="item.areaCode * 1"
|
|
:label="item.areaName"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-col>
|
|
|
|
<!-- 区县选择 -->
|
|
<el-col :span="24">
|
|
<el-form-item
|
|
label="所在区/县"
|
|
prop="areaCode"
|
|
>
|
|
<el-select
|
|
v-model="addressForm.areaCode"
|
|
placeholder="请选择区/县"
|
|
clearable
|
|
style="width: 95%"
|
|
>
|
|
<el-option
|
|
v-for="item in districtList"
|
|
:key="item.areaId"
|
|
:value="item.areaCode * 1"
|
|
:label="item.areaName"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-col>
|
|
|
|
<!-- 详细地址 -->
|
|
<el-col :span="24">
|
|
<el-form-item
|
|
label="详细地址"
|
|
prop="address"
|
|
>
|
|
<el-input
|
|
v-model="addressForm.address"
|
|
placeholder="请输入详细地址"
|
|
clearable
|
|
:maxlength="99"
|
|
style="width: 95%"
|
|
/>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
|
|
<!-- 对话框按钮 -->
|
|
<div slot="footer" class="dialog-footer">
|
|
<el-button @click="handleCancel">取消</el-button>
|
|
<el-button type="primary" @click="handleSubmit">提交</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
getAreaApi,
|
|
addAddressInfoApi,
|
|
getAddressListApi,
|
|
editAddressApi,
|
|
delAddressApi
|
|
} from '@/api/address-manage/index'
|
|
import { Message } from 'element-ui'
|
|
|
|
export default {
|
|
name: 'AddressManage',
|
|
|
|
data() {
|
|
return {
|
|
// 列表数据
|
|
addressList: [],
|
|
total: 0,
|
|
|
|
// 搜索参数
|
|
searchParams: {
|
|
pageSize: 10,
|
|
pageNum: 1
|
|
},
|
|
|
|
// 对话框相关
|
|
dialogVisible: false,
|
|
dialogTitle: '',
|
|
isEditMode: false,
|
|
|
|
// 表单数据
|
|
addressForm: {
|
|
id: '',
|
|
provinceCode: '',
|
|
cityCode: '',
|
|
areaCode: '',
|
|
address: ''
|
|
},
|
|
|
|
// 地区数据
|
|
provinceList: [],
|
|
cityList: [],
|
|
districtList: [],
|
|
|
|
// 表单引用
|
|
searchFormRef: null,
|
|
addressFormRef: null
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
// 表单验证规则
|
|
addressFormRules() {
|
|
return {
|
|
provinceCode: [
|
|
{ required: true, message: '请选择所在省', trigger: 'change' }
|
|
],
|
|
cityCode: [
|
|
{ required: true, message: '请选择所在市', trigger: 'change' }
|
|
],
|
|
areaCode: [
|
|
{ required: true, message: '请选择所在区/县', trigger: 'change' }
|
|
],
|
|
address: [
|
|
{ required: true, message: '请输入详细地址', trigger: 'blur' },
|
|
{ max: 99, message: '详细地址不能超过99个字符', trigger: 'blur' }
|
|
]
|
|
}
|
|
}
|
|
},
|
|
|
|
created() {
|
|
this.initData()
|
|
},
|
|
|
|
methods: {
|
|
/**
|
|
* 初始化数据
|
|
*/
|
|
async initData() {
|
|
await Promise.all([
|
|
this.getAddressListData(),
|
|
this.getProvinceList()
|
|
])
|
|
},
|
|
|
|
/**
|
|
* 获取地址列表数据
|
|
*/
|
|
async getAddressListData() {
|
|
try {
|
|
const res = await getAddressListApi(this.searchParams)
|
|
if (res.code === 200) {
|
|
this.addressList = res.rows || []
|
|
this.total = res.total || 0
|
|
}
|
|
} catch (error) {
|
|
console.error('获取地址列表失败:', error)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 获取省份列表
|
|
*/
|
|
async getProvinceList() {
|
|
try {
|
|
const res = await getAreaApi(0)
|
|
if (res.code === 200) {
|
|
this.provinceList = res.data || []
|
|
}
|
|
} catch (error) {
|
|
console.error('获取省份列表失败:', error)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 获取城市列表
|
|
*/
|
|
async getCityList(provinceCode) {
|
|
try {
|
|
const res = await getAreaApi(provinceCode)
|
|
if (res.code === 200) {
|
|
this.cityList = res.data || []
|
|
this.districtList = [] // 清空区县列表
|
|
}
|
|
} catch (error) {
|
|
console.error('获取城市列表失败:', error)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 获取区县列表
|
|
*/
|
|
async getDistrictList(cityCode) {
|
|
try {
|
|
const res = await getAreaApi(cityCode)
|
|
if (res.code === 200) {
|
|
this.districtList = res.data || []
|
|
}
|
|
} catch (error) {
|
|
console.error('获取区县列表失败:', error)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 格式化完整地址
|
|
*/
|
|
formatFullAddress(row) {
|
|
const { provinceName = '', cityName = '', areaName = '', address = '' } = row
|
|
return `${provinceName}${cityName}${areaName}${address}`
|
|
},
|
|
|
|
/**
|
|
* 处理新增地址
|
|
*/
|
|
handleAddAddress() {
|
|
this.dialogTitle = '新增收货地址'
|
|
this.isEditMode = false
|
|
this.resetAddressForm()
|
|
this.dialogVisible = true
|
|
},
|
|
|
|
/**
|
|
* 处理编辑地址
|
|
*/
|
|
async handleEditAddress(row) {
|
|
this.dialogTitle = '编辑收货地址'
|
|
this.isEditMode = true
|
|
|
|
// 填充表单数据
|
|
this.addressForm = {
|
|
id: row.id,
|
|
provinceCode: row.provinceCode,
|
|
cityCode: row.cityCode,
|
|
areaCode: row.areaCode,
|
|
address: row.address
|
|
}
|
|
|
|
// 加载地区数据
|
|
await this.loadRegionDataForEdit()
|
|
|
|
this.dialogVisible = true
|
|
},
|
|
|
|
/**
|
|
* 编辑时加载地区数据
|
|
*/
|
|
async loadRegionDataForEdit() {
|
|
const { provinceCode, cityCode } = this.addressForm
|
|
|
|
if (provinceCode) {
|
|
await this.getCityList(provinceCode)
|
|
}
|
|
|
|
if (cityCode) {
|
|
await this.getDistrictList(cityCode)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 处理省份变化
|
|
*/
|
|
async handleProvinceChange(provinceCode) {
|
|
if (!provinceCode) {
|
|
this.cityList = []
|
|
this.districtList = []
|
|
this.addressForm.cityCode = ''
|
|
this.addressForm.areaCode = ''
|
|
return
|
|
}
|
|
|
|
await this.getCityList(provinceCode)
|
|
this.addressForm.cityCode = ''
|
|
this.addressForm.areaCode = ''
|
|
},
|
|
|
|
/**
|
|
* 处理城市变化
|
|
*/
|
|
async handleCityChange(cityCode) {
|
|
if (!cityCode) {
|
|
this.districtList = []
|
|
this.addressForm.areaCode = ''
|
|
return
|
|
}
|
|
|
|
await this.getDistrictList(cityCode)
|
|
this.addressForm.areaCode = ''
|
|
},
|
|
|
|
/**
|
|
* 处理删除地址
|
|
*/
|
|
handleDeleteAddress(id) {
|
|
this.$confirm('确定删除该收货地址吗?', '提示', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(async() => {
|
|
try {
|
|
const res = await delAddressApi(id)
|
|
if (res.code === 200) {
|
|
Message.success('删除成功')
|
|
this.getAddressListData()
|
|
}
|
|
} catch (error) {
|
|
console.error('删除地址失败:', error)
|
|
}
|
|
}).catch(() => {
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 处理表单提交
|
|
*/
|
|
async handleSubmit() {
|
|
try {
|
|
await this.$refs.addressFormRef.validate()
|
|
|
|
const api = this.isEditMode ? editAddressApi : addAddressInfoApi
|
|
const res = await api(this.addressForm)
|
|
|
|
if (res.code === 200) {
|
|
Message.success(this.isEditMode ? '编辑成功' : '新增成功')
|
|
this.dialogVisible = false
|
|
this.getAddressListData()
|
|
}
|
|
} catch (error) {
|
|
// 验证失败或API调用失败
|
|
console.error('提交失败:', error)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 处理对话框关闭
|
|
*/
|
|
handleDialogClose() {
|
|
this.dialogVisible = false
|
|
this.resetAddressForm()
|
|
this.resetRegionLists()
|
|
if (this.$refs.addressFormRef) {
|
|
this.$refs.addressFormRef.clearValidate()
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 处理取消操作
|
|
*/
|
|
handleCancel() {
|
|
this.dialogVisible = false
|
|
},
|
|
|
|
/**
|
|
* 重置地址表单
|
|
*/
|
|
resetAddressForm() {
|
|
this.addressForm = {
|
|
id: '',
|
|
provinceCode: '',
|
|
cityCode: '',
|
|
areaCode: '',
|
|
address: ''
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 重置地区列表
|
|
*/
|
|
resetRegionLists() {
|
|
this.cityList = []
|
|
this.districtList = []
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.app-container {
|
|
height: 100%;
|
|
|
|
.content-box {
|
|
border-radius: 8px;
|
|
//height: calc(100vh - 125px);
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
::v-deep .el-card__body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
padding: 20px;
|
|
}
|
|
|
|
.action-bar {
|
|
margin-bottom: 16px;
|
|
text-align: right;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.pagination-wrapper {
|
|
flex-shrink: 0;
|
|
padding-top: 6px;
|
|
margin-top: auto;
|
|
|
|
::v-deep .pagination-container {
|
|
padding: 0 20px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.danger-text {
|
|
color: #FF5129;
|
|
|
|
&:hover {
|
|
color: #f78989;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 表格样式优化
|
|
::v-deep .el-table {
|
|
flex: 1;
|
|
min-height: 0;
|
|
|
|
&.el-table--striped {
|
|
.el-table__body {
|
|
tr.el-table__row--striped {
|
|
td {
|
|
background-color: #F6FBFA !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.el-table__header {
|
|
background: #E9F0EE;
|
|
|
|
th {
|
|
background: #E9F0EE !important;
|
|
color: #606266;
|
|
font-weight: 600;
|
|
height: 50px;
|
|
}
|
|
}
|
|
|
|
&.el-table--striped {
|
|
.el-table__body {
|
|
tr.el-table__row:hover > td.el-table__cell {
|
|
background-color: #CCF1E9 !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 分页样式
|
|
::v-deep .el-pagination {
|
|
&.is-background {
|
|
.el-pager {
|
|
li.is-active {
|
|
background-color: #3cb4a6;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 对话框样式
|
|
.dialog-footer {
|
|
text-align: right;
|
|
}
|
|
|
|
::v-deep.el-button--primary{
|
|
background-color: #2CBAB2;
|
|
border-color: #2CBAB2;
|
|
}
|
|
|
|
::v-deep .el-button--text{
|
|
height: 22px;
|
|
font-family: Microsoft YaHei, Microsoft YaHei;
|
|
font-weight: 400;
|
|
font-size: 14px;
|
|
color: #2CBAB2;
|
|
line-height: 22px;
|
|
text-align: left;
|
|
font-style: normal;
|
|
text-transform: none;
|
|
}
|
|
</style>
|