123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- <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>
|