From d843b03efb1b997d3eaec252dfa0bed7e1ffe5c5 Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期二, 04 八月 2026 17:41:52 +0800
Subject: [PATCH] feat(admin): 添加商户登录密码修改功能并完善优惠券金额验证
---
rencaika/pages/login/login.uvue | 26 +++++++++++++++++++++++---
rencaika_merchant/pages/withdrawal-success/withdrawal-success.uvue | 6 ++++++
talent-card-admin/src/views/EquityImageView.vue | 6 +++++-
3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/rencaika/pages/login/login.uvue b/rencaika/pages/login/login.uvue
index 24e3161..71fa16f 100644
--- a/rencaika/pages/login/login.uvue
+++ b/rencaika/pages/login/login.uvue
@@ -2,7 +2,7 @@
<view class="page">
<view class="glow glow-top"></view><view class="glow glow-left"></view><view class="glow glow-right"></view>
<view class="safe-space"></view>
- <view class="back" @tap="goBack"><text>‹</text></view>
+ <view class="back" hover-class="back-active" @tap="goBack"><image class="back-icon" src="/static/news-assets/arrow-left.svg" mode="aspectFit"></image></view>
<view class="main-content">
<view class="hero-row">
@@ -12,6 +12,13 @@
<button class="phone-login" :open-type="agreed ? 'getPhoneNumber' : ''" @tap="handleLoginTap" @getphonenumber="handleGetPhoneNumber"><text>手机号一键登录</text></button>
</view>
<view class="agreement" @tap="toggleAgreement"><view class="check" :class="agreed ? 'checked' : ''"><text v-if="agreed">✓</text></view><text>我已阅读并同意</text><text class="agreement-link" @tap.stop="showAgreement">《用户协议》</text><text class="agreement-link" @tap.stop="showPrivacy">《隐私与权限协议》</text></view>
+ <view v-if="agreementPromptVisible" class="agreement-modal-mask" @tap="closeAgreementPrompt">
+ <view class="agreement-modal" @tap.stop="preventClose">
+ <text class="agreement-modal-title">提示</text>
+ <text class="agreement-modal-content">请确认已同意《用户协议》、{{'\n'}}《隐私与权限协议》</text>
+ <view class="agreement-modal-actions"><text class="agreement-modal-cancel" @tap="closeAgreementPrompt">再想想</text><text class="agreement-modal-confirm" @tap="confirmAgreement">确认</text></view>
+ </view>
+ </view>
</view>
</template>
@@ -23,6 +30,7 @@
const agreed = ref(false)
const isLoggingIn = ref(false)
const redirectUrl = ref('')
+ const agreementPromptVisible = ref(false)
onLoad((options: any) => {
if (options != null && options['redirect'] != null) { const value = decodeURIComponent(options['redirect'] as string); if (value.indexOf('/pages/') == 0 && value.indexOf('//') == -1) redirectUrl.value = value }
if (developmentLoginBypassEnabled) {
@@ -39,9 +47,12 @@
const toggleAgreement = () => { agreed.value = !agreed.value }
const handleLoginTap = () => {
if (!agreed.value) {
- uni.showToast({ title: '请先阅读并同意相关协议', icon: 'none' })
+ agreementPromptVisible.value = true
}
}
+ const closeAgreementPrompt = () => { agreementPromptVisible.value = false }
+ const preventClose = () => {}
+ const confirmAgreement = () => { agreed.value = true; agreementPromptVisible.value = false }
const handleGetPhoneNumber = (event: any) => {
if (isLoggingIn.value) return
const errMsg = event.detail.errMsg as string
@@ -78,10 +89,19 @@
.glow-left { width: 450rpx; height: 540rpx; top: 490rpx; left: -290rpx; background-image: linear-gradient(135deg, rgba(255,213,111,.34) 0%, rgba(255,190,76,.12) 68%, rgba(255,190,76,0) 100%); box-shadow: 26rpx 0 86rpx rgba(255,193,78,.16); }
.glow-right { width: 410rpx; height: 500rpx; top: 18rpx; right: -300rpx; background-image: linear-gradient(180deg, rgba(255,167,92,.25) 0%, rgba(255,143,72,.08) 70%, rgba(255,143,72,0) 100%); box-shadow: -24rpx 18rpx 82rpx rgba(255,151,77,.13); }
.safe-space { height: 58rpx; }
- .back { display: flex; position: relative; z-index: 2; width: 76rpx; height: 76rpx; margin-left: 32rpx; justify-content: center; align-items: flex-start; } .back text { color: #38516C; font-size: 60rpx; font-weight: 300; line-height: 65rpx; }
+ .back { display: flex; position: relative; z-index: 2; width: 76rpx; height: 76rpx; margin-left: 32rpx; justify-content: center; align-items: center; border-radius: 10rpx; }
+ .back-icon { width: 34rpx; height: 34rpx; }
+ .back-active { background-color: rgba(255, 255, 255, 0.42); }
.main-content { display: flex; flex-direction: column; position: relative; z-index: 2; padding: 220rpx 64rpx 0; }
.hero-row { display: flex; height: 168rpx; flex-direction: row; align-items: center; justify-content: space-between; } .welcome-block { width: 455rpx; flex-shrink: 0; } .welcome-title { display: block; color: #925014; font-size: 56rpx; font-weight: 400; letter-spacing: 1rpx; } .welcome-subtitle { display: block; margin-top: 13rpx; color: #925014; font-size: 36rpx; font-weight: 400; white-space: nowrap; }
.mascot-wrap { width: 165rpx; height: 168rpx; position: relative; } .mascot { position: absolute; left: 0; bottom: 0; width: 165rpx; height: 150rpx; }
.phone-login { display: flex; width: 100%; height: 98rpx; margin: 140rpx 0 0; padding: 0; border-radius: 49rpx; background-image: linear-gradient(90deg, #FF4935 0%, #FF8A20 100%); box-shadow: 0 10rpx 22rpx rgba(239,92,34,.16); justify-content: center; align-items: center; line-height: 98rpx; } .phone-login::after { border-width: 0; } .phone-login text { color: #FFFFFF; font-size: 28rpx; font-weight: 700; }
.agreement { display: flex; position: relative; z-index: 2; margin-top: auto; margin-bottom: calc(82rpx + env(safe-area-inset-bottom)); justify-content: center; align-items: center; flex-direction: row; color: #8C8F98; font-size: 23rpx; } .check { display: flex; width: 28rpx; height: 28rpx; box-sizing: border-box; margin-right: 12rpx; border-width: 1rpx; border-style: solid; border-color: #C5C7CC; border-radius: 5rpx; background-color: #FFFFFF; flex-shrink: 0; justify-content: center; align-items: center; } .check.checked { border-color: #FF8B22; background-color: #FF8B22; } .check text { color: #FFFFFF; font-size: 19rpx; font-weight: 700; } .agreement-link { margin-left: 8rpx; color: #F27930; }
+ .agreement-modal-mask { display: flex; position: fixed; z-index: 20; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0, 0, 0, 0.48); justify-content: center; align-items: center; }
+ .agreement-modal { display: flex; width: 510rpx; min-height: 276rpx; padding: 38rpx 38rpx 30rpx; border-radius: 24rpx; background-color: #FFFFFF; box-sizing: border-box; flex-direction: column; }
+ .agreement-modal-title { color: #FF7A25; font-size: 34rpx; line-height: 48rpx; font-weight: 700; text-align: center; }
+ .agreement-modal-content { margin-top: 28rpx; color: #8D96A4; font-size: 26rpx; line-height: 40rpx; font-weight: 500; text-align: center; }
+ .agreement-modal-actions { display: flex; margin-top: auto; padding-top: 28rpx; flex-direction: row; justify-content: space-between; align-items: center; }
+ .agreement-modal-cancel { color: #FF7A25; font-size: 26rpx; line-height: 58rpx; font-weight: 600; }
+ .agreement-modal-confirm { min-width: 132rpx; height: 58rpx; border-radius: 12rpx; background-image: linear-gradient(90deg, #FF4B36 0%, #FF8A20 100%); color: #FFFFFF; font-size: 26rpx; line-height: 58rpx; font-weight: 600; text-align: center; }
</style>
diff --git a/rencaika_merchant/pages/withdrawal-success/withdrawal-success.uvue b/rencaika_merchant/pages/withdrawal-success/withdrawal-success.uvue
index 60cccb0..7818794 100644
--- a/rencaika_merchant/pages/withdrawal-success/withdrawal-success.uvue
+++ b/rencaika_merchant/pages/withdrawal-success/withdrawal-success.uvue
@@ -10,12 +10,16 @@
<image class="success-icon" src="/static/icons/lucide/badge-check-orange.svg" mode="aspectFit"></image>
</view>
<text class="result-title">提交成功,等待审核</text>
+ <text v-if="withdrawalNo.length > 0" class="withdrawal-no">提现单号:{{withdrawalNo}}</text>
+ <text class="result-tip">审核通过后将发起到账处理,请留意提现记录状态。</text>
<view class="return-button" @tap="returnToWithdrawal"><text>返回</text></view>
</view>
</view>
</template>
<script setup lang="uts">
+ const withdrawalNo = ref('')
+ onLoad((options: any) => { withdrawalNo.value = options != null && options.withdrawalNo != null ? '' + options.withdrawalNo : '' })
const returnToWithdrawal = () => {
uni.navigateBack({
delta: 1,
@@ -37,5 +41,7 @@
.success-icon-shell { display: flex; width: 170rpx; height: 170rpx; justify-content: center; align-items: center; border-radius: 85rpx; background-color: #FFF0E7; box-shadow: 0 16rpx 34rpx rgba(255, 107, 44, 0.13); }
.success-icon { width: 100rpx; height: 100rpx; }
.result-title { margin-top: 42rpx; color: #273345; font-size: 30rpx; line-height: 44rpx; text-align: center; font-weight: 700; }
+ .withdrawal-no { margin-top: 22rpx; color: #7D8797; font-size: 25rpx; line-height: 36rpx; }
+ .result-tip { margin-top: 14rpx; color: #9AA3B0; font-size: 23rpx; line-height: 34rpx; text-align: center; }
.return-button { display: flex; width: 100%; height: 88rpx; margin-top: 86rpx; justify-content: center; align-items: center; border-radius: 44rpx; color: #FFFFFF; font-size: 29rpx; line-height: 41rpx; font-weight: 700; background-image: linear-gradient(90deg, #FF7625 0%, #FF9630 100%); box-shadow: 0 12rpx 24rpx rgba(255, 107, 36, 0.20); }
</style>
diff --git a/talent-card-admin/src/views/EquityImageView.vue b/talent-card-admin/src/views/EquityImageView.vue
index 208eeab..884d122 100644
--- a/talent-card-admin/src/views/EquityImageView.vue
+++ b/talent-card-admin/src/views/EquityImageView.vue
@@ -10,6 +10,7 @@
const saving = ref(false)
const uploadingImageId = ref<number | string | null>(null)
const supportedCategoryKeys = new Set(['premium', 'food', 'home', 'transport', 'city', 'shopping', 'entertainment'])
+const categoryOrder = ['premium', 'food', 'home', 'transport', 'city', 'shopping', 'entertainment']
function resolveImageUrl(url?: string) {
if (!url || /^https?:\/\//i.test(url)) return url || ''
@@ -111,7 +112,10 @@
loading.value = true
try {
const result = await getEquityImageCategories()
- configs.value = result.filter((item) => supportedCategoryKeys.has(item.categoryKey)).map(normalizeConfig)
+ configs.value = result
+ .filter((item) => supportedCategoryKeys.has(item.categoryKey))
+ .sort((left, right) => categoryOrder.indexOf(left.categoryKey) - categoryOrder.indexOf(right.categoryKey))
+ .map(normalizeConfig)
if (!configs.value.some((item) => item.categoryKey === activeTab.value)) {
activeTab.value = configs.value[0]?.categoryKey != null ? String(configs.value[0].categoryKey) : ''
}
--
Gitblit v1.7.1