|
@@ -0,0 +1,218 @@
|
|
|
+<template>
|
|
|
+ <CtTable
|
|
|
+ class="mt-3"
|
|
|
+ :items="items"
|
|
|
+ :headers="headers"
|
|
|
+ :loading="false"
|
|
|
+ :elevation="0"
|
|
|
+ :isTools="true"
|
|
|
+ :showPage="false"
|
|
|
+ :showSelect="props.showSelect"
|
|
|
+ selectStrategy="single"
|
|
|
+ itemKey="id"
|
|
|
+ @add="handleAdd"
|
|
|
+ @selected="handleSelected"
|
|
|
+ >
|
|
|
+ <template #actions="{ item }">
|
|
|
+ <v-btn color="primary" @click.stop="handleEdit(item)" variant="text">编辑</v-btn>
|
|
|
+ <v-btn color="error" @click.stop="handleDelete(item)" variant="text">删除</v-btn>
|
|
|
+ <v-btn v-if="!item.defaultStatus" color="success" @click.stop="handleSetDefault(item)" variant="text">设为默认</v-btn>
|
|
|
+ </template>
|
|
|
+ </CtTable>
|
|
|
+
|
|
|
+ <CtDialog :visible="showDialog" titleClass="text-h6" :footer="true" :widthType="3" :title="isAdd ? '新增收货地址' : '编辑收货地址'" @submit="handleSubmit" @close="handleClose">
|
|
|
+ <CtForm ref="CtFormRef" :items="formItems">
|
|
|
+ <template #areaId="{ item }">
|
|
|
+ <div class="d-flex" style="width: 100%;">
|
|
|
+ <div class="mt-2" style="color: #777; width: 100px;">省市区 *</div>
|
|
|
+ <el-cascader
|
|
|
+ ref="cascaderAddr"
|
|
|
+ v-model="item.value"
|
|
|
+ size="large"
|
|
|
+ clearable
|
|
|
+ class="mb-5"
|
|
|
+ placeholder="省市区 *"
|
|
|
+ style="flex: 1;"
|
|
|
+ :props="{ value: 'id', label: 'name', emitPath: false }"
|
|
|
+ :options="item.items"
|
|
|
+ @change="handleChangeArea(item)"
|
|
|
+ @clear="item.labelValue = ''"
|
|
|
+ ></el-cascader>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #defaultStatus="{ item }">
|
|
|
+ <div class="d-flex align-center">
|
|
|
+ <span class="color-666 mr-5">设为默认地址</span>
|
|
|
+ <v-switch v-model="item.value" hide-details color="primary"></v-switch>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </CtForm>
|
|
|
+ </CtDialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+defineOptions({ name: 'personal-personCenter-address-index' })
|
|
|
+import { ref } from 'vue'
|
|
|
+import { getMallUserAddressList, deleteMallUserAddress, createMallUserAddress, updateMallUserAddress } from '@/api/mall/address'
|
|
|
+import Confirm from '@/plugins/confirm'
|
|
|
+import { getDict } from '@/hooks/web/useDictionaries'
|
|
|
+import Snackbar from '@/plugins/snackbar'
|
|
|
+const props = defineProps({
|
|
|
+ showSelect: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const isAdd = ref(true)
|
|
|
+const editId = ref(null)
|
|
|
+const showDialog = ref(false)
|
|
|
+const items = ref([])
|
|
|
+const headers = [
|
|
|
+ { title: '收货人', key: 'name', sortable: false },
|
|
|
+ { title: '联系电话', key: 'mobile', sortable: false },
|
|
|
+ { title: '所在地区', key: 'areaName', sortable: false },
|
|
|
+ { title: '详细地址', key: 'detailAddress', sortable: false },
|
|
|
+ { title: '是否默认', key: 'defaultStatus', sortable: false, value: item => item.defaultStatus ? '是' : '否' },
|
|
|
+ { title: '操作', key: 'actions', sortable: false }
|
|
|
+]
|
|
|
+const cascaderAddr = ref()
|
|
|
+const CtFormRef = ref()
|
|
|
+const formItems = ref({
|
|
|
+ options: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ key: 'name',
|
|
|
+ value: null,
|
|
|
+ default: localStorage.getItem('baseInfo') ? JSON.parse(localStorage.getItem('baseInfo')).name : '',
|
|
|
+ hide: false,
|
|
|
+ label: '收货人姓名 *',
|
|
|
+ rules: [v => !!v || '请输入收货人姓名'],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ key: 'mobile',
|
|
|
+ value: null,
|
|
|
+ default: localStorage.getItem('userInfo') ? JSON.parse(localStorage.getItem('userInfo')).phone : '',
|
|
|
+ label: '收货人联系电话 *',
|
|
|
+ outlined: true,
|
|
|
+ rules: [v => !!v || '请填写收货人联系电话']
|
|
|
+ },
|
|
|
+ {
|
|
|
+ slotName: 'areaId',
|
|
|
+ key: 'areaId',
|
|
|
+ labelValue: '',
|
|
|
+ value: null,
|
|
|
+ default: null,
|
|
|
+ items: []
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'textarea',
|
|
|
+ key: 'detailAddress',
|
|
|
+ value: '',
|
|
|
+ default: null,
|
|
|
+ label: '详细地址 *',
|
|
|
+ rules: [ v => !!v || '请填写详细地址' ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ slotName: 'defaultStatus',
|
|
|
+ key: 'defaultStatus',
|
|
|
+ value: false,
|
|
|
+ default: false,
|
|
|
+ }
|
|
|
+ ]
|
|
|
+})
|
|
|
+getDict('areaTreeData', null, 'areaTreeData').then(({ data }) => {
|
|
|
+ data = data?.length && data || []
|
|
|
+ formItems.value.options.find(e => e.key === 'areaId').items = data
|
|
|
+})
|
|
|
+
|
|
|
+const singleSelectObj = ref([])
|
|
|
+const handleSelected = (e) => {
|
|
|
+ singleSelectObj.value = e?.length ? items.value.find(item => item.id === e[0]) : null
|
|
|
+}
|
|
|
+
|
|
|
+const getSelected = () => {
|
|
|
+ return singleSelectObj.value
|
|
|
+}
|
|
|
+
|
|
|
+// 获取地址列表
|
|
|
+const getAddressList = async () => {
|
|
|
+ const data = await getMallUserAddressList()
|
|
|
+ items.value = data
|
|
|
+}
|
|
|
+getAddressList()
|
|
|
+
|
|
|
+// 新增
|
|
|
+const handleAdd = () => {
|
|
|
+ formItems.value.options.forEach(e => e.value = e.default)
|
|
|
+ showDialog.value = true
|
|
|
+ isAdd.value = true
|
|
|
+}
|
|
|
+
|
|
|
+// 地区选择
|
|
|
+const handleChangeArea = (item) => {
|
|
|
+ const node = cascaderAddr.value.getCheckedNodes() ? cascaderAddr.value.getCheckedNodes()[0] : null
|
|
|
+ if (!node) return
|
|
|
+ item.labelValue = node.pathLabels.join(' ')
|
|
|
+}
|
|
|
+
|
|
|
+// 设置为默认地址
|
|
|
+const handleSetDefault = async (item) => {
|
|
|
+ Confirm('系统提示', '是否确定设置该地址为默认收货地址?').then(async () => {
|
|
|
+ await updateMallUserAddress({ ...item, defaultStatus: true })
|
|
|
+ Snackbar.success('设置成功')
|
|
|
+ await getAddressList()
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 编辑
|
|
|
+const handleEdit = (item) => {
|
|
|
+ isAdd.value = false
|
|
|
+ editId.value = item.id
|
|
|
+ formItems.value.options.forEach(e => e.value = item[e.key])
|
|
|
+ showDialog.value = true
|
|
|
+}
|
|
|
+
|
|
|
+// 提交
|
|
|
+const handleClose = () => {
|
|
|
+ showDialog.value = false
|
|
|
+ editId.value = null
|
|
|
+}
|
|
|
+
|
|
|
+const handleSubmit = async () => {
|
|
|
+ const { valid } = await CtFormRef.value.formRef.validate()
|
|
|
+ if (!valid) return
|
|
|
+ const obj = {}
|
|
|
+ formItems.value.options.forEach(e => {
|
|
|
+ if (e.key === 'areaId') {
|
|
|
+ obj.areaId = e.value
|
|
|
+ obj.areaName = e.labelValue
|
|
|
+ } else obj[e.key] = e.value
|
|
|
+ })
|
|
|
+ if (!obj.areaId && !obj.areaName) return Snackbar.warning('请将必填项填写完整')
|
|
|
+ try {
|
|
|
+ isAdd.value ? await createMallUserAddress(obj) : await updateMallUserAddress(obj)
|
|
|
+ Snackbar.success(isAdd.value ? '新增成功' : '编辑成功')
|
|
|
+ handleClose()
|
|
|
+ getAddressList()
|
|
|
+ } catch {}
|
|
|
+}
|
|
|
+
|
|
|
+// 删除
|
|
|
+const handleDelete = (item) => {
|
|
|
+ Confirm('系统提示', '是否确认删除该收货地址?').then(async () => {
|
|
|
+ await deleteMallUserAddress(item.id)
|
|
|
+ Snackbar.success('删除成功')
|
|
|
+ await getAddressList()
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ getSelected
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+
|
|
|
+</style>
|