gaoluyang
20 小时以前 a26e8d708ab3c8899bee5cae4167ccc3be9b58cd
销售管理整体样式优化,搜索条件修改
已修改10个文件
已添加1个文件
1860 ■■■■■ 文件已修改
src/pages/procurementManagement/paymentLedger/detail.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/procurementManagement/paymentLedger/index.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/invoiceLedger/detail.vue 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/invoiceLedger/index.vue 208 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/invoicingRegistration/index.vue 220 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/receiptPayment/index.vue 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/receiptPaymentHistory/index.vue 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/receiptPaymentLedger/detail.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/receiptPaymentLedger/index.vue 340 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/salesAccount/index.vue 278 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/sales-common.scss 337 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/procurementManagement/paymentLedger/detail.vue
@@ -89,17 +89,16 @@
// è¿”回上一页
const goBack = () => {
    uni.removeStorageSync('supplierId')
    uni.navigateBack();
};
// èŽ·å–é¡µé¢å‚æ•°
const getPageParams = () => {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    const options = currentPage.options;
    if (options.supplierId) {
        supplierId.value = options.supplierId;
    // ä»Žæœ¬åœ°å­˜å‚¨èŽ·å–ä¾›åº”å•†ID
    const storedSupplierId = uni.getStorageSync('supplierId');
    if (storedSupplierId) {
        supplierId.value = storedSupplierId;
    }
};
src/pages/procurementManagement/paymentLedger/index.vue
@@ -116,9 +116,11 @@
const rowClickMethod = (row) => {
  // ä½¿ç”¨ uni.setStorageSync å­˜å‚¨ä¾›åº”商信息
  uni.setStorageSync('supplierId', row.supplierId);
  // è·³è½¬åˆ°å›žæ¬¾è®°å½•明细页面
  uni.navigateTo({
    url: `/pages/procurementManagement/paymentLedger/detail?supplierId=${row.supplierId}`
    url: '/pages/procurementManagement/paymentLedger/detail'
  });
};
src/pages/sales/invoiceLedger/detail.vue
@@ -26,24 +26,24 @@
                </u-form-item>
            </u-cell-group>
            
            <u-cell-group title="附件材料(仅支持 pdf)">
                <u-upload
                    accept=".pdf"
                    multiple
                    :afterRead="afterReadUpload"
                    :beforeRead="beforeReadPdf"
                >
                    <u-button class="upload-btn" type="primary">
                        ä¸Šä¼ æ–‡ä»¶
                    </u-button>
                </u-upload>
                <view class="uploaded-list" v-if="fileList.length">
                    <view class="uploaded-item" v-for="(f, idx) in fileList" :key="idx">
                        <text class="file-name">{{ f.name || getFileNameFromUrl(f.url) }}</text>
                        <u-button size="mini" type="error" plain @click="removeUploaded(idx)">移除</u-button>
                    </view>
                </view>
            </u-cell-group>
<!--            <u-cell-group title="附件材料(仅支持 pdf)">-->
<!--                <u-upload-->
<!--                    accept=".pdf"-->
<!--                    multiple-->
<!--                    :afterRead="afterReadUpload"-->
<!--                    :beforeRead="beforeReadPdf"-->
<!--                >-->
<!--                    <u-button class="upload-btn" type="primary">-->
<!--                        ä¸Šä¼ æ–‡ä»¶-->
<!--                    </u-button>-->
<!--                </u-upload>-->
<!--                <view class="uploaded-list" v-if="fileList.length">-->
<!--                    <view class="uploaded-item" v-for="(f, idx) in fileList" :key="idx">-->
<!--                        <text class="file-name">{{ f.name || getFileNameFromUrl(f.url) }}</text>-->
<!--                        <u-button size="mini" type="error" plain @click="removeUploaded(idx)">移除</u-button>-->
<!--                    </view>-->
<!--                </view>-->
<!--            </u-cell-group>-->
            
            <!-- æäº¤æŒ‰é’® -->
            <view class="footer-btns">
src/pages/sales/invoiceLedger/index.vue
@@ -2,28 +2,28 @@
    <view class="sales-account">
        <!-- ä½¿ç”¨é€šç”¨é¡µé¢å¤´éƒ¨ç»„ä»¶ -->
        <PageHeader title="开票台账" @back="goBack" />
        <!-- æœç´¢å’Œç­›é€‰åŒºåŸŸï¼ˆä¿æŒä¸Žé”€å”®å°è´¦é£Žæ ¼ä¸€è‡´ï¼‰ -->
        <view class="search-filter-section">
        <view class="search-section">
            <view class="search-bar">
                <view class="search-input">
                    <input
                    <up-input
                        class="search-text"
                        placeholder="客户名称/销售合同号"
                        placeholder="请输入客户名称/合同号搜索"
                        v-model="searchForm.searchText"
                        confirm-type="search"
                        @confirm="handleQuery"
                        @change="handleQuery"
                        clearable
                    />
                </view>
<!--                <view class="filter-button" @click="showFilter = true">-->
<!--                    <up-icon name="list" size="24" color="#999"></up-icon>-->
<!--                </view>-->
                <!--                <view class="filter-button" @click="showFilter = true">-->
                <!--                    <up-icon name="list" size="24" color="#999"></up-icon>-->
                <!--                </view>-->
                <view class="filter-button" @click="handleQuery">
                    <up-icon name="search" size="24" color="#999"></up-icon>
                </view>
            </view>
        </view>
        <!-- åˆ—表区域 -->
        <view class="ledger-list" v-if="ledgerList.length > 0">
            <view v-for="(item, index) in ledgerList" :key="index">
@@ -112,16 +112,16 @@
                        >
                            æŸ¥çœ‹é™„ä»¶
                        </up-button>
                        <up-button
                            type="primary"
                            size="small"
                            class="action-btn"
                            v-else
                            :disabled="item.invoicePerson !== userStore.nickName"
                            @click="openUpload(item)"
                        >
                            ä¸Šä¼ 
                        </up-button>
<!--                        <up-button-->
<!--                            type="primary"-->
<!--                            size="small"-->
<!--                            class="action-btn"-->
<!--                            v-else-->
<!--                            :disabled="item.invoicePerson !== userStore.nickName"-->
<!--                            @click="openUpload(item)"-->
<!--                        >-->
<!--                            ä¸Šä¼ -->
<!--                        </up-button>-->
                    </view>
                </view>
            </view>
@@ -129,7 +129,7 @@
        <view v-else class="no-data">
            <text>暂无开票台账数据</text>
        </view>
        <!-- ç­›é€‰å¼¹çª— -->
        <up-popup v-model="showFilter" mode="bottom" round><up-transition>
            <view class="filter-popup">
@@ -158,7 +158,7 @@
                </view>
            </view>
        </up-transition></up-popup>
        <!-- æ—¥åŽ†ï¼šå¼€ç¥¨æ—¥æœŸèŒƒå›´ -->
        <up-popup v-model="showInvoiceRange" mode="bottom"><up-transition>
            <up-datetime-picker
@@ -169,7 +169,7 @@
                @cancel="showInvoiceRange = false"
            />
        </up-transition></up-popup>
        <!-- æ—¥æœŸï¼šå½•入日期 -->
        <up-popup v-model="showCreateDatePicker" mode="bottom"><up-transition>
            <up-datetime-picker
@@ -181,9 +181,9 @@
                @cancel="showCreateDatePicker = false"
            />
        </up-transition></up-popup>
        
        <!-- å•行上传弹窗(无表单) -->
        <up-popup v-model="showUpload" mode="bottom" round><up-transition>
            <view class="upload-container">
@@ -210,7 +210,7 @@
                </view>
            </view>
        </up-transition></up-popup>
        <!-- é™„件列表选择 -->
        <up-action-sheet v-model="showFileSheet" :actions="fileActions" cancel-text="取消" close-on-click-action @select="onSelectFile">
            <view class="up-action-sheet__cancel" @click="showFileSheet = false">
@@ -530,165 +530,15 @@
</script>
<style scoped lang="scss">
.u-divider {
    margin: 0 !important;
}
.sales-account {
    min-height: 100vh;
    background: #f8f9fa;
    position: relative;
}
@import '@/styles/sales-common.scss';
.search-filter-section {
    padding: 10px 20px;
    background: #ffffff;
}
.search-bar {
    display: flex;
    align-items: center;
    gap: 12px;
}
.search-input {
    flex: 1;
    background: #f5f5f5;
    border-radius: 24px;
    padding: 10px 16px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.search-text {
    flex: 1;
    font-size: 14px;
    color: #333;
    background: transparent;
    border: none;
    outline: none;
}
.search-text::placeholder {
    color: #999;
}
.filter-button {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.ledger-list {
    padding: 20px;
}
.ledger-item {
    background: #ffffff;
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    padding: 0 16px;
}
.item-header {
    padding: 16px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.item-left {
    display: flex;
    align-items: center;
    gap: 8px;
}
.document-icon {
    width: 24px;
    height: 24px;
    background: #2979ff;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.item-id {
    font-size: 14px;
    color: #333;
    font-weight: 500;
}
.item-details {
    padding: 16px 0;
}
.detail-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 8px;
    &:last-child {
        margin-bottom: 0;
    }
}
.detail-label {
    font-size: 12px;
    color: #777777;
    min-width: 60px;
}
.detail-value {
    font-size: 12px;
    color: #000000;
    text-align: right;
    flex: 1;
    margin-left: 16px;
}
.detail-value.highlight {
    color: #2979ff;
    font-weight: 500;
}
.no-data {
    padding: 40px 0;
    text-align: center;
    color: #999;
}
.action-buttons {
    display: flex;
    gap: 12px;
    padding: 0 0 16px 0;
    justify-content: space-between;
}
.action-btn {
    flex: 1;
}
// å¼€ç¥¨å°è´¦ç‰¹æœ‰æ ·å¼
.filter-popup {
    padding: 12px 12px 20px;
}
.switch-row {
    padding: 12px 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.switch-label {
    font-size: 14px;
    color: #333;
}
.filter-actions {
@@ -743,6 +593,7 @@
    box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
    z-index: 1000;
}
.cancel-btn {
    font-weight: 400;
    font-size: 1rem;
@@ -752,6 +603,7 @@
    box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
}
.save-btn {
    font-weight: 400;
    font-size: 1rem;
src/pages/sales/invoicingRegistration/index.vue
@@ -4,13 +4,15 @@
        <PageHeader title="开票登记" @back="goBack" />
        
        <!-- æœç´¢å’Œç­›é€‰åŒºåŸŸ -->
        <view class="search-filter-section">
        <view class="search-section">
            <view class="search-bar">
                <view class="search-input">
                    <input
                    <up-input
                        class="search-text"
                        placeholder="请输入销售合同号/客户名称"
                        v-model="searchKeyword"
                        placeholder="请输入客户名称搜索"
                        v-model="customerName"
                        clearable
                        @change="getList"
                    />
                </view>
                <view class="filter-button" @click="getList">
@@ -67,21 +69,21 @@
                    <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
                    <view class="action-buttons">
                        <up-button
            type="primary"
            size="small"
            @click="handleAddInvoice(item)"
            class="action-btn"
            :disabled="item.noInvoiceAmountTotal == 0"
        >
            æ–°å¢žå¼€ç¥¨
        </up-button>
        <up-button
            size="small"
            @click="handleViewDetail(item)"
            class="action-btn"
        >
            æŸ¥çœ‹è¯¦æƒ…
        </up-button>
                            type="primary"
                            size="small"
                            @click="handleAddInvoice(item)"
                            class="action-btn"
                            :disabled="item.noInvoiceAmountTotal == 0"
                        >
                            æ–°å¢žå¼€ç¥¨
                        </up-button>
                        <up-button
                            size="small"
                            @click="handleViewDetail(item)"
                            class="action-btn"
                        >
                            æŸ¥çœ‹è¯¦æƒ…
                        </up-button>
                    </view>
                </view>
            </view>
@@ -100,7 +102,7 @@
const userStore = useUserStore()
// æœç´¢å…³é”®è¯
const searchKeyword = ref('');
const customerName = ref('');
// é”€å”®å°è´¦æ•°æ®
const ledgerList = ref([]);
@@ -116,7 +118,7 @@
        current: -1,
        size: -1
    }
    ledgerListPage({...page}).then((res) => {
    ledgerListPage({...page, customerName: customerName.value}).then((res) => {
        ledgerList.value = res.records;
        total.value = res.total;
    }).catch(() => {
@@ -169,15 +171,9 @@
</script>
<style scoped lang="scss">
.u-divider {
    margin: 0 !important;
}
.sales-account {
    min-height: 100vh;
    background: #f8f9fa;
    position: relative;
}
@import '@/styles/sales-common.scss';
// å¼€ç¥¨ç™»è®°ç‰¹æœ‰æ ·å¼
.nav-icon {
    width: 24px;
    height: 24px;
@@ -230,176 +226,12 @@
    border-radius: 2px;
}
.search-filter-section {
    padding: 10px 20px;
    background: #ffffff;
}
.search-bar {
    display: flex;
    align-items: center;
    gap: 12px;
}
.search-input {
    flex: 1;
    background: #f5f5f5;
    border-radius: 24px;
    padding: 10px 16px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.search-text {
    flex: 1;
    font-size: 14px;
    color: #333;
    background: transparent;
    border: none;
    outline: none;
}
.search-text::placeholder {
    color: #999;
}
.filter-button {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.ledger-list {
    padding: 20px;
}
.ledger-item {
    background: #ffffff;
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    padding: 0 16px;
}
.item-header {
    padding: 16px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.item-left {
    display: flex;
    align-items: center;
    gap: 8px;
}
.document-icon {
    width: 24px;
    height: 24px;
    background: #2979ff;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.item-id {
    font-size: 14px;
    color: #333;
    font-weight: 500;
}
.item-tag {
    background: #4caf50;
    border-radius: 4px;
    padding: 2px 4px;
}
.tag-text {
    font-size: 11px;
    color: #ffffff;
    font-weight: 500;
}
.item-details {
    padding: 16px 0;
}
.detail-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 8px;
    &:last-child {
        margin-bottom: 0;
    }
}
.detail-info {
    margin-top: 10px;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
}
.detail-label {
    font-size: 12px;
    color: #777777;
    min-width: 60px;
}
.detail-value {
    font-size: 12px;
    color: #000000;
    text-align: right;
    flex: 1;
    margin-left: 16px;
}
.detail-value.highlight {
    color: #2979ff;
    font-weight: 500;
}
.detail-value.redlight {
    color: red;
    font-weight: 500;
}
.action-buttons {
    display: flex;
    gap: 12px;
    padding: 0 0 16px 0;
    justify-content: space-between;
}
.action-btn {
    flex: 1;
}
.no-data {
    padding: 40px 0;
    text-align: center;
    color: #999;
}
.fab-button {
    position: fixed;
    bottom: 30px;
    right: 30px;
    width: 56px;
    height: 56px;
    background: #2979ff;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 16px rgba(41, 121, 255, 0.3);
    z-index: 1000;
    bottom: 30px; // ä¸Žå…¶ä»–页面的 calc(30px + env(safe-area-inset-bottom)) ä¸åŒ
}
</style>
src/pages/sales/receiptPayment/index.vue
@@ -2,16 +2,17 @@
    <view class="sales-account">
        <!-- ä½¿ç”¨é€šç”¨é¡µé¢å¤´éƒ¨ç»„ä»¶ -->
        <PageHeader title="回款登记" @back="goBack" />
        <!-- æœç´¢å’Œç­›é€‰åŒºåŸŸ -->
        <view class="search-filter-section">
        <view class="search-section">
            <view class="search-bar">
                <view class="search-input">
                    <input
                    <up-input
                        class="search-text"
                        placeholder="客户名称/合同号/项目名称"
                        v-model="searchForm.searchText"
                        confirm-type="search"
                        placeholder="请输入客户名称搜索"
                        v-model="searchForm.customerName"
                        @change="getList"
                        clearable
                    />
                </view>
                <view class="filter-button" @click="getList">
@@ -25,9 +26,9 @@
                <up-switch v-model="searchForm.status" @change="getList" size="18"/>
            </view>
        </view>
        <!-- åˆ—表区域 -->
        <view class="ledger-list" v-if="tableData.length > 0">
            <view v-for="(item, index) in tableData" :key="index">
@@ -95,7 +96,7 @@
                </view>
            </view>
        </view>
        <!-- æ— æ•°æ®æç¤º -->
        <view class="no-data" v-else>
            <text>暂无回款数据</text>
@@ -145,9 +146,8 @@
// æœç´¢è¡¨å•
const searchForm = ref({
    searchText: '',
    status: true,
    customerName: '',
    status: true,
    customerContractNo: '',
    projectName: ''
})
@@ -193,201 +193,12 @@
</script>
<style scoped lang="scss">
.u-divider {
    margin: 0 !important;
}
@import '@/styles/sales-common.scss';
.sales-account {
    min-height: 100vh;
    background: #f8f9fa;
    position: relative;
}
.search-filter-section {
    padding: 10px 20px;
    background: #ffffff;
}
.search-bar {
    display: flex;
    align-items: center;
    gap: 12px;
}
.search-input {
    flex: 1;
    background: #f5f5f5;
    border-radius: 24px;
    padding: 10px 16px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.search-text {
    flex: 1;
    font-size: 14px;
    color: #333;
    background: transparent;
    border: none;
    outline: none;
}
.search-text::placeholder {
    color: #999;
}
.filter-button {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.switch-row {
    padding: 8px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 8px;
}
.switch-label {
    font-size: 14px;
    color: #333;
}
.ledger-list {
    padding: 20px;
}
.ledger-item {
    background: #ffffff;
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    padding: 0 16px;
}
.item-header {
    padding: 16px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.item-left {
    display: flex;
    align-items: center;
    gap: 8px;
}
.document-icon {
    width: 24px;
    height: 24px;
    background: #2979ff;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.item-id {
    font-size: 14px;
    color: #333;
    font-weight: 500;
}
.item-details {
    padding: 16px 0;
}
.detail-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 8px;
    &:last-child {
        margin-bottom: 0;
    }
}
.detail-label {
    font-size: 12px;
    color: #777777;
    min-width: 60px;
}
// å›žæ¬¾ç™»è®°ç‰¹æœ‰æ ·å¼
.detail-value {
    font-size: 12px;
    color: #000000;
    text-align: right;
    flex: 1;
    margin-left: 16px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
}
.detail-value.highlight {
    color: #2979ff;
    font-weight: 500;
}
.detail-value.danger {
    color: #ee0a24;
    font-weight: 500;
}
.children-list {
    .children-title {
        font-size: 14px;
        font-weight: 500;
        color: #333;
        padding: 12px 0 8px 0;
        border-top: 1px solid #f0f0f0;
    }
}
.child-item {
    .child-details {
        padding: 12px 0;
    }
    .child-actions {
        display: flex;
        gap: 8px;
        padding: 8px 0 16px 0;
        justify-content: flex-end;
    }
}
.action-buttons {
    display: flex;
    gap: 12px;
    padding: 0 0 16px 0;
    justify-content: space-between;
}
.action-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
.no-data {
    padding: 40px 0;
    text-align: center;
    color: #999;
}
</style>
src/pages/sales/receiptPaymentHistory/index.vue
@@ -1,17 +1,18 @@
<template>
    <view class="receipt-payment-history">
        <!-- ä½¿ç”¨é€šç”¨é¡µé¢å¤´éƒ¨ç»„ä»¶ -->
        <PageHeader title="回款历史" @back="goBack" />
        <PageHeader title="回款流水" @back="goBack" />
        
        <!-- æœç´¢åŒºåŸŸ -->
        <view class="search-section">
            <view class="search-bar">
                <view class="search-input">
                    <input
                    <up-input
                        class="search-text"
                        placeholder="请输入客户名称/客户合同号"
                        placeholder="请输入客户名称搜索"
                        v-model="searchForm.searchText"
                        @input="getList"
                        @change="getList"
                        clearable
                    />
                </view>
                <view class="search-button" @click="getList">
@@ -186,118 +187,21 @@
</script>
<style scoped lang="scss">
.u-divider {
    margin: 0 !important;
}
@import '@/styles/sales-common.scss';
// å›žæ¬¾æµæ°´ç‰¹æœ‰æ ·å¼
.receipt-payment-history {
    min-height: 100vh;
    background: #f8f9fa;
    position: relative;
}
.search-section {
    padding: 10px 20px;
    background: #ffffff;
}
.search-bar {
    display: flex;
    align-items: center;
    gap: 12px;
}
.search-input {
    flex: 1;
    background: #f5f5f5;
    border-radius: 24px;
    padding: 10px 16px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.search-text {
    flex: 1;
    font-size: 14px;
    color: #333;
    background: transparent;
    border: none;
    outline: none;
}
.search-text::placeholder {
    color: #999;
}
.search-button {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.history-list {
    padding: 20px;
}
.history-item {
    background: #ffffff;
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    padding: 0 16px;
}
.item-header {
    padding: 16px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.item-left {
    display: flex;
    align-items: center;
    gap: 8px;
}
.action-buttons {
    display: flex;
    gap: 12px;
    padding: 12px 0 0 0;
    justify-content: space-between;
}
.action-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
.document-icon {
    width: 24px;
    height: 24px;
    background: #2979ff;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.item-id {
    font-size: 14px;
    color: #333;
    font-weight: 500;
    padding: 12px 0 0 0; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 0 0 16px 0 ä¸åŒ
}
.item-tag {
    border-radius: 4px;
    padding:  2px 8px;
    padding: 2px 8px; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 2px 4px ä¸åŒ
}
.tag-electric {
@@ -313,90 +217,8 @@
}
.tag-text {
    font-size: 14px;
    font-size: 14px; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 11px ä¸åŒ
    color: #ffffff;
    font-weight: 500;
}
.item-details {
    padding: 16px 0;
}
.detail-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 8px;
    &:last-child {
        margin-bottom: 0;
    }
}
.detail-info {
    margin-top: 10px;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
}
.detail-label {
    font-size: 12px;
    color: #777777;
    min-width: 60px;
}
.detail-value {
    font-size: 12px;
    color: #000000;
    text-align: right;
    flex: 1;
    margin-left: 16px;
}
.detail-value.highlight {
    color: #2979ff;
    font-weight: 500;
}
.no-data {
    padding: 40px 0;
    text-align: center;
    color: #999;
}
.summary-info {
    background: #ffffff;
    margin: 20px 20px 0 20px;
    border-radius: 12px;
    padding: 16px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.summary-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
    &:last-child {
        margin-bottom: 0;
    }
}
.summary-label {
    font-size: 14px;
    color: #666;
}
.summary-value {
    font-size: 14px;
    color: #333;
    font-weight: 500;
}
.summary-value.highlight {
    color: #2979ff;
    font-weight: 600;
}
</style>
src/pages/sales/receiptPaymentLedger/detail.vue
@@ -89,17 +89,16 @@
// è¿”回上一页
const goBack = () => {
    uni.removeStorageSync('customerId')
    uni.navigateBack();
};
// èŽ·å–é¡µé¢å‚æ•°
const getPageParams = () => {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    const options = currentPage.options;
    if (options.customerId) {
        customerId.value = options.customerId;
    // ä»Žæœ¬åœ°å­˜å‚¨èŽ·å–å®¢æˆ·ID
    const storedCustomerId = uni.getStorageSync('customerId');
    if (storedCustomerId) {
        customerId.value = storedCustomerId;
    }
};
src/pages/sales/receiptPaymentLedger/index.vue
@@ -1,67 +1,68 @@
<template>
  <view class="receipt-payment-ledger">
    <!-- ä½¿ç”¨é€šç”¨é¡µé¢å¤´éƒ¨ç»„ä»¶ -->
    <PageHeader title="客户往来" @back="goBack" />
    <!-- æœç´¢åŒºåŸŸ -->
    <view class="search-section">
      <view class="search-bar">
        <view class="search-input">
          <input
            class="search-text"
            placeholder="请输入客户名称"
            v-model="searchForm.searchText"
            @input="handleQuery"
          />
        </view>
        <view class="search-button" @click="handleQuery">
          <up-icon name="search" size="24" color="#999"></up-icon>
        </view>
      </view>
    </view>
    <!-- å®¢æˆ·åˆ—表 -->
    <view class="customer-list-container">
      <view class="customer-list" v-if="tableData.length > 0">
        <view
          v-for="(item, index) in tableData"
          :key="item.id"
          class="customer-item"
          @click="rowClickMethod(item)"
        >
          <view class="item-header">
            <view class="item-left">
              <view class="customer-icon">
    <view class="sales-account">
        <!-- ä½¿ç”¨é€šç”¨é¡µé¢å¤´éƒ¨ç»„ä»¶ -->
        <PageHeader title="客户往来" @back="goBack" />
        <!-- æœç´¢åŒºåŸŸ -->
        <view class="search-section">
            <view class="search-bar">
                <view class="search-input">
                    <up-input
                        class="search-text"
                        placeholder="请输入客户名称"
                        v-model="searchForm.customerName"
                        @change="handleQuery"
                        clearable
                    />
                </view>
                <view class="search-button" @click="handleQuery">
                    <up-icon name="search" size="24" color="#999"></up-icon>
                </view>
            </view>
        </view>
        <!-- å®¢æˆ·åˆ—表 -->
        <view class="customer-list-container">
            <view class="customer-list" v-if="tableData.length > 0">
                <view
                    v-for="(item, index) in tableData"
                    :key="item.id"
                    class="customer-item"
                    @click="rowClickMethod(item)"
                >
                    <view class="item-header">
                        <view class="item-left">
                            <view class="customer-icon">
                                <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
              </view>
              <text class="customer-name">{{ item.customerName }}</text>
            </view>
            <view class="item-right">
              <up-icon name="arrow-right" size="16" color="#999"></up-icon>
            </view>
          </view>
          <up-divider></up-divider>
          <view class="item-details">
            <view class="detail-row">
              <text class="detail-label">开票金额(元)</text>
              <text class="detail-value">{{ formattedNumber(item.invoiceTotal) }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">回款金额(元)</text>
              <text class="detail-value">{{ formattedNumber(item.receiptPaymentAmount) }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">应收金额(元)</text>
              <text class="detail-value highlight danger">{{ formattedNumber(item.unReceiptPaymentAmount) }}</text>
            </view>
          </view>
        </view>
      </view>
      <view v-else class="no-data">
        <text>暂无客户数据</text>
      </view>
    </view>
  </view>
                            </view>
                            <text class="customer-name">{{ item.customerName }}</text>
                        </view>
                        <view class="item-right">
                            <up-icon name="arrow-right" size="16" color="#999"></up-icon>
                        </view>
                    </view>
                    <up-divider></up-divider>
                    <view class="item-details">
                        <view class="detail-row">
                            <text class="detail-label">开票金额(元)</text>
                            <text class="detail-value">{{ formattedNumber(item.invoiceTotal) }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">回款金额(元)</text>
                            <text class="detail-value">{{ formattedNumber(item.receiptPaymentAmount) }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">应收金额(元)</text>
                            <text class="detail-value highlight danger">{{ formattedNumber(item.unReceiptPaymentAmount) }}</text>
                        </view>
                    </view>
                </view>
            </view>
            <view v-else class="no-data">
                <text>暂无客户数据</text>
            </view>
        </view>
    </view>
</template>
<script setup>
@@ -73,228 +74,73 @@
const tableData = ref([]);
const page = reactive({
  current: -1,
  size: -1,
    current: -1,
    size: -1,
});
const data = reactive({
  searchForm: {
    searchText: "",
    invoiceDate: "",
  },
    searchForm: {
        customerName: "",
        invoiceDate: "",
    },
});
const { searchForm } = toRefs(data);
// è¿”回上一页
const goBack = () => {
  uni.navigateBack();
    uni.navigateBack();
};
// æŸ¥è¯¢åˆ—表
const handleQuery = () => {
  getList();
    getList();
};
const getList = () => {
  invoiceLedgerSalesAccount({ ...searchForm.value, ...page }).then((res) => {
    tableData.value = res.data.records;
  }).catch(() => {
    uni.showToast({
      title: '查询失败',
      icon: 'error'
    });
  });
    invoiceLedgerSalesAccount({ ...searchForm.value, ...page }).then((res) => {
        tableData.value = res.data.records;
    }).catch(() => {
        uni.showToast({
            title: '查询失败',
            icon: 'error'
        });
    });
};
const formattedNumber = (value) => {
  return parseFloat(value || 0).toFixed(2);
    return parseFloat(value || 0).toFixed(2);
};
const rowClickMethod = (row) => {
  // è·³è½¬åˆ°å›žæ¬¾è®°å½•明细页面
  uni.navigateTo({
    url: `/pages/sales/receiptPaymentLedger/detail?customerId=${row.id}`
  });
    // ä½¿ç”¨ uni.setStorageSync å­˜å‚¨å®¢æˆ·ä¿¡æ¯
    uni.setStorageSync('customerId', row.id);
    // è·³è½¬åˆ°å›žæ¬¾è®°å½•明细页面
    uni.navigateTo({
        url: '/pages/sales/receiptPaymentLedger/detail'
    });
};
onShow(() => {
  // é¡µé¢æ˜¾ç¤ºæ—¶åˆ·æ–°åˆ—表
  getList();
    // é¡µé¢æ˜¾ç¤ºæ—¶åˆ·æ–°åˆ—表
    getList();
});
onMounted(() => {
  getList();
    getList();
});
</script>
<style scoped lang="scss">
.u-divider {
  margin: 0 !important;
}
@import '@/styles/sales-common.scss';
.receipt-payment-ledger {
  min-height: 100vh;
  background: #f8f9fa;
  position: relative;
}
.search-section {
  padding: 10px 20px;
  background: #ffffff;
}
.search-bar {
  display: flex;
  align-items: center;
  gap: 12px;
}
.search-input {
  flex: 1;
  background: #f5f5f5;
  border-radius: 24px;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.search-text {
  flex: 1;
  font-size: 14px;
  color: #333;
  background: transparent;
  border: none;
  outline: none;
}
.search-text::placeholder {
  color: #999;
}
.search-button {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.customer-list-container {
  padding: 20px;
}
.customer-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.customer-item {
  background: #ffffff;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  padding: 0 16px;
  transition: all 0.3s ease;
  &:active {
    transform: scale(0.98);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  }
}
.item-header {
  padding: 16px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.item-left {
  display: flex;
  align-items: center;
  gap: 8px;
}
.item-right {
  display: flex;
  align-items: center;
  gap: 8px;
}
.customer-icon {
  width: 24px;
  height: 24px;
  background: #2979ff;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.customer-name {
  font-size: 14px;
  color: #333;
  font-weight: 500;
}
.item-index {
  font-size: 12px;
  color: #999;
  background: #f5f5f5;
  padding: 2px 8px;
  border-radius: 12px;
}
.item-details {
  padding: 16px 0;
}
.detail-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 8px;
  &:last-child {
    margin-bottom: 0;
  }
}
.detail-label {
  font-size: 12px;
  color: #777777;
  min-width: 60px;
}
.detail-value {
  font-size: 12px;
  color: #000000;
  text-align: right;
  flex: 1;
  margin-left: 16px;
}
.detail-value.highlight {
  color: #2979ff;
  font-weight: 500;
}
// å®¢æˆ·å¾€æ¥ç‰¹æœ‰æ ·å¼
.detail-value.danger {
  color: #ff4757;
  font-weight: 500;
}
.no-data {
  padding: 40px 0;
  text-align: center;
  color: #999;
    color: #ff4757; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ #ee0a24 ä¸åŒ
    font-weight: 500;
}
</style>
src/pages/sales/salesAccount/index.vue
@@ -4,13 +4,15 @@
        <PageHeader title="销售台账" @back="goBack" />
        
        <!-- æœç´¢å’Œç­›é€‰åŒºåŸŸ -->
        <view class="search-filter-section">
        <view class="search-section">
            <view class="search-bar">
                <view class="search-input">
                    <input
                    <up-input
                        class="search-text"
                        placeholder="请输入销售合同号/客户名称"
                        v-model="searchKeyword"
                        placeholder="请输入销售合同号搜索"
                        v-model="salesContractNo"
                        @change="getList"
                        clearable
                    />
                </view>
                <view class="filter-button" @click="getList">
@@ -109,7 +111,7 @@
}
// æœç´¢å…³é”®è¯
const searchKeyword = ref('');
const salesContractNo = ref('');
// é”€å”®å°è´¦æ•°æ®
const ledgerList = ref([]);
@@ -126,7 +128,7 @@
        current: -1,
        size: -1
    }
    ledgerListPage({...page}).then((res) => {
    ledgerListPage({...page, salesContractNo: salesContractNo.value}).then((res) => {
        ledgerList.value = res.records;
        total.value = res.total;
        closeToast()
@@ -137,227 +139,59 @@
// å¤„理台账信息操作(查看/编辑/新增)
const handleInfo = (type, row) => {
  try {
    // è®¾ç½®æ“ä½œç±»åž‹
    uni.setStorageSync('operationType', type);
    // å¦‚果是查看或编辑操作
    if (type !== 'add') {
      // éªŒè¯è¡Œæ•°æ®æ˜¯å¦å­˜åœ¨
      if (!row) {
        uni.showToast({
          title: '数据不存在',
          icon: 'error'
        });
        return;
      }
      // æ£€æŸ¥æƒé™ï¼šåªæœ‰å½•入人才能编辑
      if (row.entryPerson != userStore.id) {
        // éžå½•入人跳转到只读详情页面
        uni.setStorageSync('editData', JSON.stringify(row));
        uni.navigateTo({
          url: '/pages/sales/salesAccount/view'
        });
        return;
      }
      // å½•入人编辑:存储数据并跳转到编辑页面
      uni.setStorageSync('editData', JSON.stringify(row));
      uni.navigateTo({
        url: '/pages/sales/salesAccount/detail'
      });
      return;
    }
    // æ–°å¢žæ“ä½œï¼šç›´æŽ¥è·³è½¬åˆ°ç¼–辑页面
    uni.navigateTo({
      url: '/pages/sales/salesAccount/detail'
    });
  } catch (error) {
    console.error('处理台账信息操作失败:', error);
    uni.showToast({
      title: '操作失败,请重试',
      icon: 'error'
    });
  }
    try {
        // è®¾ç½®æ“ä½œç±»åž‹
        uni.setStorageSync('operationType', type);
        // å¦‚果是查看或编辑操作
        if (type !== 'add') {
            // éªŒè¯è¡Œæ•°æ®æ˜¯å¦å­˜åœ¨
            if (!row) {
                uni.showToast({
                    title: '数据不存在',
                    icon: 'error'
                });
                return;
            }
            // æ£€æŸ¥æƒé™ï¼šåªæœ‰å½•入人才能编辑
            if (row.entryPerson != userStore.id) {
                // éžå½•入人跳转到只读详情页面
                uni.setStorageSync('editData', JSON.stringify(row));
                uni.navigateTo({
                    url: '/pages/sales/salesAccount/view'
                });
                return;
            }
            // å½•入人编辑:存储数据并跳转到编辑页面
            uni.setStorageSync('editData', JSON.stringify(row));
            uni.navigateTo({
                url: '/pages/sales/salesAccount/detail'
            });
            return;
        }
        // æ–°å¢žæ“ä½œï¼šç›´æŽ¥è·³è½¬åˆ°ç¼–辑页面
        uni.navigateTo({
            url: '/pages/sales/salesAccount/detail'
        });
    } catch (error) {
        console.error('处理台账信息操作失败:', error);
        uni.showToast({
            title: '操作失败,请重试',
            icon: 'error'
        });
    }
};
onShow(() => {
    // é¡µé¢æ˜¾ç¤ºæ—¶åˆ·æ–°åˆ—表
    getList();
    // é¡µé¢æ˜¾ç¤ºæ—¶åˆ·æ–°åˆ—表
    getList();
});
</script>
<style scoped lang="scss">
.u-divider {
    margin: 0 !important;
}
.sales-account {
    min-height: 100vh;
    background: #f8f9fa;
    position: relative;
}
.search-filter-section {
    padding: 10px 20px;
    background: #ffffff;
}
.search-bar {
    display: flex;
    align-items: center;
    gap: 12px;
}
.search-input {
    flex: 1;
    background: #f5f5f5;
    border-radius: 24px;
    padding: 10px 16px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.search-text {
    flex: 1;
    font-size: 14px;
    color: #333;
    background: transparent;
    border: none;
    outline: none;
}
.search-text::placeholder {
    color: #999;
}
.filter-button {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.ledger-list {
    padding: 20px;
}
.ledger-item {
    background: #ffffff;
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    padding: 0 16px;
}
.item-header {
    padding: 16px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.item-left {
    display: flex;
    align-items: center;
    gap: 8px;
}
.document-icon {
    width: 24px;
    height: 24px;
    background: #2979ff;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.item-id {
    font-size: 14px;
    color: #333;
    font-weight: 500;
}
.item-tag {
    background: #4caf50;
    border-radius: 4px;
    padding: 2px 4px;
}
.tag-text {
    font-size: 11px;
    color: #ffffff;
    font-weight: 500;
}
.item-details {
    padding: 16px 0;
}
.detail-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 8px;
    &:last-child {
        margin-bottom: 0;
    }
}
.detail-info {
    margin-top: 10px;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
}
.detail-label {
    font-size: 12px;
    color: #777777;
    min-width: 60px;
}
.detail-value {
    font-size: 12px;
    color: #000000;
    text-align: right;
    flex: 1;
    margin-left: 16px;
}
.detail-value.highlight {
    color: #2979ff;
    font-weight: 500;
}
.no-data {
    padding: 40px 0;
    text-align: center;
    color: #999;
}
.fab-button {
    position: fixed;
    bottom: calc(30px + env(safe-area-inset-bottom));
    right: 30px;
    width: 56px;
    height: 56px;
    background: #2979ff;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 16px rgba(41, 121, 255, 0.3);
    z-index: 1000;
    /* ç¡®ä¿æµ®åŠ¨æŒ‰é’®ä¸è¢«åº•éƒ¨å®‰å…¨åŒºåŸŸé®æŒ¡ */
}
@import '@/styles/sales-common.scss';
</style>
src/styles/sales-common.scss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,337 @@
// é”€å”®æ¨¡å—公共样式
// ç”¨äºŽç»Ÿä¸€é”€å”®ç›¸å…³é¡µé¢çš„æ ·å¼é£Žæ ¼
// é¡µé¢å®¹å™¨æ ·å¼
.sales-account {
    min-height: 100vh;
    background: #f8f9fa;
    position: relative;
}
.receipt-payment-ledger {
    min-height: 100vh;
    background: #f8f9fa;
    position: relative;
}
// æœç´¢å’Œç­›é€‰åŒºåŸŸæ ·å¼
.search-filter-section,
.search-section {
    padding: 10px 20px;
    background: #ffffff;
}
.search-bar {
    display: flex;
    align-items: center;
    gap: 12px;
}
.search-input {
    flex: 1;
    background: #f5f5f5;
    border-radius: 24px;
    padding: 0 16px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.search-text {
    flex: 1;
    font-size: 14px;
    color: #333;
    background: transparent;
    border: none;
    outline: none;
    &::placeholder {
        color: #999;
    }
}
.filter-button,
.search-button {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}
// å¼€å…³è¡Œæ ·å¼
.switch-row {
    padding: 8px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 8px;
}
.switch-label {
    font-size: 14px;
    color: #333;
}
// åˆ—表容器样式
.ledger-list,
.history-list,
.customer-list-container {
    padding: 20px;
}
.customer-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
}
// åˆ—表项样式
.ledger-item,
.history-item,
.customer-item {
    background: #ffffff;
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    padding: 0 16px;
    &:active {
        transform: scale(0.98);
        box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
    }
}
.customer-item {
    transition: all 0.3s ease;
    margin-bottom: 0;
}
// é¡¹ç›®å¤´éƒ¨æ ·å¼
.item-header {
    padding: 16px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.item-left {
    display: flex;
    align-items: center;
    gap: 8px;
}
.item-right {
    display: flex;
    align-items: center;
    gap: 8px;
}
// å›¾æ ‡æ ·å¼
.document-icon,
.customer-icon {
    width: 24px;
    height: 24px;
    background: #2979ff;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}
// æ–‡æœ¬æ ·å¼
.item-id,
.customer-name {
    font-size: 14px;
    color: #333;
    font-weight: 500;
}
.item-index {
    font-size: 12px;
    color: #999;
    background: #f5f5f5;
    padding: 2px 8px;
    border-radius: 12px;
}
// æ ‡ç­¾æ ·å¼
.item-tag {
    border-radius: 4px;
    padding: 2px 4px;
    &.tag-electric {
        background: #4caf50;
    }
    &.tag-acceptance {
        background: #ff9800;
    }
    &.tag-unknown {
        background: #9e9e9e;
    }
}
.tag-text {
    font-size: 11px;
    color: #ffffff;
    font-weight: 500;
}
// è¯¦æƒ…区域样式
.item-details {
    padding: 16px 0;
}
.detail-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 8px;
    &:last-child {
        margin-bottom: 0;
    }
}
.detail-info {
    margin-top: 10px;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
}
.detail-label {
    font-size: 12px;
    color: #777777;
    min-width: 60px;
}
.detail-value {
    font-size: 12px;
    color: #000000;
    text-align: right;
    flex: 1;
    margin-left: 16px;
    &.highlight {
        color: #2979ff;
        font-weight: 500;
    }
    &.danger {
        color: #ee0a24;
        font-weight: 500;
    }
}
// å­åˆ—表样式
.children-list {
    .children-title {
        font-size: 14px;
        font-weight: 500;
        color: #333;
        padding: 12px 0 8px 0;
        border-top: 1px solid #f0f0f0;
    }
}
.child-item {
    .child-details {
        padding: 12px 0;
    }
    .child-actions {
        display: flex;
        gap: 8px;
        padding: 8px 0 16px 0;
        justify-content: flex-end;
    }
}
// æ“ä½œæŒ‰é’®æ ·å¼
.action-buttons {
    display: flex;
    gap: 12px;
    padding: 0 0 16px 0;
    justify-content: space-between;
    &.action-buttons-top {
        padding: 12px 0 0 0;
    }
}
.action-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
// æµ®åŠ¨æŒ‰é’®æ ·å¼
.fab-button {
    position: fixed;
    bottom: calc(30px + env(safe-area-inset-bottom));
    right: 30px;
    width: 56px;
    height: 56px;
    background: #2979ff;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 16px rgba(41, 121, 255, 0.3);
    z-index: 1000;
}
// æ— æ•°æ®æç¤ºæ ·å¼
.no-data {
    padding: 40px 0;
    text-align: center;
    color: #999;
}
// æ±‡æ€»ä¿¡æ¯æ ·å¼
.summary-info {
    background: #ffffff;
    margin: 20px 20px 0 20px;
    border-radius: 12px;
    padding: 16px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.summary-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
    &:last-child {
        margin-bottom: 0;
    }
}
.summary-label {
    font-size: 14px;
    color: #666;
}
.summary-value {
    font-size: 14px;
    color: #333;
    font-weight: 500;
    &.highlight {
        color: #2979ff;
        font-weight: 600;
    }
}
// uView组件样式重置
.u-divider {
    margin: 0 !important;
}