front/src/views/h5/customer-center/components/H5EditProfileSheet.vue
zzh 8155ba93d9 feat: 代发订单分轨与运营页,补 SPA 回退与 H5/下单优化
新增代发订单列表、扫码反查与拣货页,完善绑定/进度展示与 nginx/vite SPA 回退;同步 SKU 申报、价格发布跳过、字典与 H5 代发体验优化。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 10:27:37 +08:00

267 lines
5.7 KiB
Vue

<template>
<a-drawer
:visible="visible"
placement="bottom"
height="auto"
:footer="false"
:header="false"
unmount-on-close
:mask-closable="!saving"
:drawer-style="drawerStyle"
popup-container="body"
class="h5-profile-drawer"
@cancel="close"
>
<div class="h5-pf">
<div class="h5-pf__handle" aria-hidden="true" />
<header class="h5-pf__head">
<h3>{{ t('h5.me.editProfile') }}</h3>
<button type="button" class="h5-pf__close" :disabled="saving" @click="close">
<icon-close />
</button>
</header>
<div class="h5-pf__body">
<section class="h5-pf__card">
<label class="h5-pf__label">{{ t('wechat.register.customerName') }}</label>
<a-input v-model="form.customerName" allow-clear />
<label class="h5-pf__label">{{ t('wechat.register.phone') }}</label>
<a-input v-model="form.phone" allow-clear />
<label class="h5-pf__label">{{ t('wechat.register.email') }}</label>
<a-input v-model="form.email" allow-clear />
</section>
</div>
<footer class="h5-pf__foot">
<button type="button" class="h5-pf__btn" :disabled="saving" @click="submit">
<span v-if="saving" class="h5-pf__loading" aria-hidden="true" />
{{ t('h5.me.save') }}
</button>
</footer>
</div>
</a-drawer>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { Message } from '@arco-design/web-vue';
import { IconClose } from '@arco-design/web-vue/es/icon';
import { CustomerService } from '@/api/customer';
defineOptions({ name: 'H5EditProfileSheet' });
const props = defineProps<{
visible: boolean;
customerId?: number | string;
initial?: {
customerName?: string;
phone?: string;
email?: string;
};
}>();
const emit = defineEmits<{
'update:visible': [value: boolean];
success: [payload: { customerName: string; phone: string; email: string }];
}>();
const { t } = useI18n();
const saving = ref(false);
const form = reactive({ customerName: '', phone: '', email: '' });
const drawerStyle = {
borderRadius: '20px 20px 0 0',
overflow: 'hidden',
maxHeight: 'min(92vh, 780px)',
};
function close() {
if (saving.value) return;
emit('update:visible', false);
}
async function submit() {
if (!props.customerId) return;
saving.value = true;
try {
const payload = {
customerName: form.customerName.trim(),
phone: form.phone.trim(),
email: form.email.trim(),
};
await CustomerService.update(props.customerId, payload);
Message.success(t('h5.me.updateSuccess'));
emit('success', payload);
emit('update:visible', false);
} catch (e: any) {
Message.error(e?.message || t('h5.me.updateFailed'));
} finally {
saving.value = false;
}
}
watch(
() => props.visible,
(visible) => {
if (!visible) return;
form.customerName = props.initial?.customerName || '';
form.phone = props.initial?.phone || '';
form.email = props.initial?.email || '';
},
{ immediate: true },
);
</script>
<style lang="less">
.h5-profile-drawer {
.arco-drawer-content {
border-radius: 20px 20px 0 0;
overflow: hidden;
max-height: min(92vh, 780px);
}
.arco-drawer-body {
padding: 0;
display: flex;
flex-direction: column;
max-height: min(92vh, 780px);
}
}
</style>
<style lang="less" scoped>
.h5-pf {
display: flex;
flex-direction: column;
max-height: min(92vh, 780px);
background: #f5f7f8;
}
.h5-pf__handle {
width: 36px;
height: 4px;
margin: 10px auto 0;
border-radius: 999px;
background: #c9cdd4;
}
.h5-pf__head {
position: relative;
display: flex;
align-items: center;
justify-content: center;
height: 48px;
h3 {
margin: 0;
font-size: 16px;
font-weight: 600;
color: #1d2129;
}
}
.h5-pf__close {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
width: 36px;
height: 36px;
border: none;
border-radius: 10px;
background: transparent;
color: #86909c;
font-size: 18px;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:disabled {
opacity: 0.5;
}
}
.h5-pf__body {
flex: 1;
min-height: 0;
overflow: auto;
padding: 0 16px 12px;
}
.h5-pf__card {
background: #fff;
border-radius: 16px;
padding: 16px;
box-shadow: 0 4px 16px rgba(15, 23, 42, 0.04);
:deep(.arco-input-wrapper) {
background: #f7f8fa !important;
border: none !important;
box-shadow: none !important;
border-radius: 12px;
min-height: 44px;
}
:deep(.arco-input-wrapper.arco-input-focus) {
background: color-mix(in srgb, var(--app-primary-color) 8%, #fff) !important;
}
}
.h5-pf__label {
display: block;
margin: 14px 0 8px;
font-size: 13px;
color: #4e5969;
&:first-child {
margin-top: 0;
}
}
.h5-pf__foot {
padding: 12px 16px calc(14px + env(safe-area-inset-bottom, 0px));
background: #fff;
box-shadow: 0 -6px 20px rgba(15, 23, 42, 0.04);
}
.h5-pf__btn {
width: 100%;
height: 48px;
border: none;
border-radius: 12px;
background: var(--app-primary-color);
color: #fff;
font-size: 15px;
font-weight: 600;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
cursor: pointer;
box-shadow: 0 8px 18px color-mix(in srgb, var(--app-primary-color) 28%, transparent);
&:disabled {
opacity: 0.7;
box-shadow: none;
}
}
.h5-pf__loading {
width: 16px;
height: 16px;
border: 2px solid rgba(255, 255, 255, 0.35);
border-top-color: #fff;
border-radius: 50%;
animation: h5-pf-spin 0.7s linear infinite;
}
@keyframes h5-pf-spin {
to {
transform: rotate(360deg);
}
}
</style>