fix: 立即续费
All checks were successful
构建并部署前端到生产环境 / build-and-deploy (push) Successful in 1m16s

This commit is contained in:
luo
2026-07-28 14:47:34 +08:00
parent 4f281da778
commit 64bccffe28
5 changed files with 69 additions and 14 deletions

View File

@@ -18,10 +18,13 @@
{{ networkStatus == 1 ? '正常' : '停机' }}
</view>
</view>
<button class="renew-button" @tap.stop="emit('renew')">立即续费</button>
</view>
</template>
<script setup>
const emit = defineEmits(['renew']);
defineProps({
currentCardNo: { type: String, default: '' },
deviceInfo: { type: Object, default: () => ({}) },
@@ -44,5 +47,17 @@
flex: 1;
}
.renew-button {
margin: 24rpx 0 0;
background: var(--primary);
color: #fff;
border: none;
border-radius: 12rpx;
font-size: 26rpx;
line-height: 2.6;
&::after { border: none; }
}
}
</style>

View File

@@ -36,3 +36,24 @@ The client SHALL create a renewal by calling `POST /api/c/v1/orders/create` with
- **WHEN** neither asset info nor the relevant historical order supplies a valid package ID
- **THEN** the client SHALL show that renewal is unavailable
- **AND** the client SHALL not guess an ID from the ordinary package catalog
### Requirement: Renewal buttons SHALL be limited to the homepage and order list
The client SHALL show an `立即续费` button in the homepage asset summary and in every order card in the order list. The client SHALL NOT show a renewal button in the order detail page, package catalog, package-order page, or other pages.
#### Scenario: Customer renews from the homepage
- **WHEN** the homepage asset summary is displayed
- **THEN** the client SHALL show an `立即续费` button
- **AND** tapping it SHALL start the standard renewal flow for the asset's current package ID when one is available
#### Scenario: Customer renews from an order card
- **WHEN** an order is displayed in the order list
- **THEN** the client SHALL show an `立即续费` button for that order
- **AND** tapping it SHALL use the order's package IDs for the standard renewal flow
#### Scenario: Customer views another page
- **WHEN** the customer views any page other than the homepage or order list
- **THEN** the client SHALL NOT show an `立即续费` button

View File

@@ -19,6 +19,7 @@
- [x] 3.2 Keep discontinued packages out of the ordinary package catalog for new customers and agents
- [x] 3.3 Add the eligible existing-customer renewal path using `current_package_id` or historical `package_ids`
- [x] 3.4 Reuse `POST /api/c/v1/orders/create` for renewal and preserve selected identifier, package IDs, payment method, and existing payment result handling
- [x] 3.5 Show `立即续费` only on the homepage asset summary and every order-list card
## 4. Wallet recharge and payment completion

View File

@@ -2,7 +2,7 @@
<view class="container">
<UserInfoCard :currentCardNo="currentCardNo" :deviceInfo="deviceInfo" :onlineStatus="onlineStatus"
:isDevice="userInfo.isDevice" :networkStatus="deviceInfo.network_status"
:isExpiring="deviceInfo.isExpiring" :expiryDays="deviceInfo.expiryDays" />
:isExpiring="deviceInfo.isExpiring" :expiryDays="deviceInfo.expiryDays" @renew="startHomepageRenewal" />
<DeviceStatusCard v-if="userInfo.isDevice" :deviceInfo="deviceInfo" :isRealName="isRealName"
:isDevice="userInfo.isDevice" @authentication="enterDetail('authentication')" />
@@ -156,6 +156,7 @@
network_status: 1,
status: 1,
packageName: '-',
currentPackageId: 0,
expireDate: '-',
isExpiring: false,
expiryDays: null,
@@ -251,10 +252,11 @@
deviceInfo.network_status = data.network_status;
deviceInfo.status = data.status;
deviceInfo.imei = data.imei || '-';
deviceInfo.asset_type = data.asset_type || 'device';
deviceInfo.bound_phone = data.bound_phone || '';
deviceInfo.packageName = data.current_package || '-';
deviceInfo.expireDate = formatDate(data.estimated_final_expires_at);
deviceInfo.asset_type = data.asset_type || 'device';
deviceInfo.bound_phone = data.bound_phone || '';
deviceInfo.packageName = data.current_package || '-';
deviceInfo.currentPackageId = Number(data.current_package_id || 0);
deviceInfo.expireDate = formatDate(data.estimated_final_expires_at);
deviceInfo.isExpiring = data.is_expiring === true;
deviceInfo.expiryDays = data.days_until_final_expiry ?? null;
deviceInfo.expiryEstimateStatus = data.expiry_estimate_status || 'none';
@@ -350,6 +352,18 @@
}
};
const startHomepageRenewal = () => {
const packageId = Number(deviceInfo.currentPackageId || 0);
if (!packageId) {
uni.showToast({ title: '当前资产暂无可续费套餐', icon: 'none' });
return;
}
const packageName = deviceInfo.packageName === '-' ? '' : deviceInfo.packageName;
const query = `renewal_package_ids=${encodeURIComponent(String(packageId))}&renewal_package_names=${encodeURIComponent(packageName)}`;
uni.navigateTo({ url: `/pages/package-order/package-order?${query}` });
};
const modifyWifi = () => {
wifi_info.ssid = deviceInfo.ssidName;
wifi_info.pwd = deviceInfo.ssidPwd;

View File

@@ -62,13 +62,13 @@
</view>
</view>
<view v-if="item.payment_status === 1" class="card-footer">
<button class="btn-pay" :disabled="orderPayingId !== null" @tap.stop="showOrderPaymentMethods(item)">
<view class="card-footer">
<button v-if="item.payment_status === 1" class="btn-pay" :disabled="orderPayingId !== null"
@tap.stop="showOrderPaymentMethods(item)">
{{ isOrderPaying(item) ? '处理中...' : '立即支付' }}
</button>
</view>
<view v-else-if="item.payment_status === 2 && item.package_ids?.length" class="card-footer">
<button class="btn-pay btn-renew" @tap.stop="startHistoricalRenewal(item)">继续续费</button>
<button class="btn-pay btn-renew" :disabled="orderPayingId !== null"
@tap.stop="startHistoricalRenewal(item)">立即续费</button>
</view>
</view>
</view>
@@ -236,7 +236,10 @@
const startHistoricalRenewal = (order) => {
const packageIds = Array.isArray(order?.package_ids) ? order.package_ids.filter(Boolean) : [];
if (!packageIds.length) return;
if (!packageIds.length) {
uni.showToast({ title: '当前订单暂无可续费套餐', icon: 'none' });
return;
}
const packageNames = Array.isArray(order.package_names) ? order.package_names : [];
const query = `renewal_package_ids=${encodeURIComponent(packageIds.join(','))}&renewal_package_names=${encodeURIComponent(packageNames.join('|'))}`;
uni.navigateTo({ url: `/pages/package-order/package-order?${query}` });
@@ -523,9 +526,9 @@
padding-top: 24rpx;
border-top: 1rpx solid #f0f0f0;
display: flex;
justify-content: flex-end;
gap: 16rpx;
.btn-pay {
.btn-pay {
background: #1890ff;
color: #fff;
border: none;
@@ -533,7 +536,8 @@
padding: 16rpx 40rpx;
font-size: 26rpx;
font-weight: 500;
width: 100%;
width: auto;
flex: 1;
&[disabled] {
opacity: 0.7;