新增代发订单列表、扫码反查与拣货页,完善绑定/进度展示与 nginx/vite SPA 回退;同步 SKU 申报、价格发布跳过、字典与 H5 代发体验优化。 Co-authored-by: Cursor <cursoragent@cursor.com>
267 lines
5.7 KiB
Vue
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>
|