新增代发订单列表、扫码反查与拣货页,完善绑定/进度展示与 nginx/vite SPA 回退;同步 SKU 申报、价格发布跳过、字典与 H5 代发体验优化。 Co-authored-by: Cursor <cursoragent@cursor.com>
266 lines
5.6 KiB
Vue
266 lines
5.6 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-pwd-drawer"
|
|
@cancel="close"
|
|
>
|
|
<div class="h5-pwd">
|
|
<div class="h5-pwd__handle" aria-hidden="true" />
|
|
<header class="h5-pwd__head">
|
|
<h3>{{ t('h5.me.resetPassword') }}</h3>
|
|
<button type="button" class="h5-pwd__close" :disabled="saving" @click="close">
|
|
<icon-close />
|
|
</button>
|
|
</header>
|
|
|
|
<div class="h5-pwd__body">
|
|
<section class="h5-pwd__card">
|
|
<label class="h5-pwd__label">{{ t('h5.me.oldPassword') }}</label>
|
|
<a-input-password v-model="form.oldPassword" allow-clear />
|
|
|
|
<label class="h5-pwd__label">{{ t('h5.me.newPassword') }}</label>
|
|
<a-input-password v-model="form.newPassword" allow-clear />
|
|
|
|
<label class="h5-pwd__label">{{ t('h5.me.confirmPassword') }}</label>
|
|
<a-input-password v-model="form.confirmPassword" allow-clear />
|
|
</section>
|
|
</div>
|
|
|
|
<footer class="h5-pwd__foot">
|
|
<button type="button" class="h5-pwd__btn" :disabled="saving" @click="submit">
|
|
<span v-if="saving" class="h5-pwd__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 { AuthService } from '@/api/rbac';
|
|
|
|
defineOptions({ name: 'H5PasswordSheet' });
|
|
|
|
const props = defineProps<{
|
|
visible: boolean;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
'update:visible': [value: boolean];
|
|
success: [];
|
|
}>();
|
|
|
|
const { t } = useI18n();
|
|
const saving = ref(false);
|
|
const form = reactive({ oldPassword: '', newPassword: '', confirmPassword: '' });
|
|
|
|
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 (!form.oldPassword || !form.newPassword) {
|
|
Message.warning(t('h5.me.passwordRequired'));
|
|
return;
|
|
}
|
|
if (form.newPassword !== form.confirmPassword) {
|
|
Message.warning(t('h5.me.passwordMismatch'));
|
|
return;
|
|
}
|
|
saving.value = true;
|
|
try {
|
|
await AuthService.postRbacAuthChangePassword({
|
|
oldPassword: form.oldPassword,
|
|
newPassword: form.newPassword,
|
|
});
|
|
Message.success(t('h5.me.changePasswordSuccess'));
|
|
emit('update:visible', false);
|
|
emit('success');
|
|
} catch (e: any) {
|
|
Message.error(e?.message || t('h5.me.updateFailed'));
|
|
} finally {
|
|
saving.value = false;
|
|
}
|
|
}
|
|
|
|
watch(
|
|
() => props.visible,
|
|
(visible) => {
|
|
if (!visible) return;
|
|
form.oldPassword = '';
|
|
form.newPassword = '';
|
|
form.confirmPassword = '';
|
|
},
|
|
{ immediate: true },
|
|
);
|
|
</script>
|
|
|
|
<style lang="less">
|
|
.h5-pwd-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-pwd {
|
|
display: flex;
|
|
flex-direction: column;
|
|
max-height: min(92vh, 780px);
|
|
background: #f5f7f8;
|
|
}
|
|
|
|
.h5-pwd__handle {
|
|
width: 36px;
|
|
height: 4px;
|
|
margin: 10px auto 0;
|
|
border-radius: 999px;
|
|
background: #c9cdd4;
|
|
}
|
|
|
|
.h5-pwd__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-pwd__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-pwd__body {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow: auto;
|
|
padding: 0 16px 12px;
|
|
}
|
|
|
|
.h5-pwd__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-pwd__label {
|
|
display: block;
|
|
margin: 14px 0 8px;
|
|
font-size: 13px;
|
|
color: #4e5969;
|
|
|
|
&:first-child {
|
|
margin-top: 0;
|
|
}
|
|
}
|
|
|
|
.h5-pwd__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-pwd__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-pwd__loading {
|
|
width: 16px;
|
|
height: 16px;
|
|
border: 2px solid rgba(255, 255, 255, 0.35);
|
|
border-top-color: #fff;
|
|
border-radius: 50%;
|
|
animation: h5-pwd-spin 0.7s linear infinite;
|
|
}
|
|
|
|
@keyframes h5-pwd-spin {
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
</style>
|