Files
BlackFruit-UI/clientarea/home/hgcloud_home/home.php
yiqiu 53c1cdccb8
All checks were successful
continuous-integration/drone/push Build is passing
redesign: 仪表盘全新高级简约风设计 — 完全重写布局和样式
- home.php: 三行卡片式网格布局(用户+统计/余额+推介/产品+工单)
- home.css: Stripe/Linear风格设计系统(16px圆角/微阴影/渐变头像/色彩标记统计卡)
- 响应式适配 @media 1200px 断点
- Element UI表格样式覆写
2026-03-20 21:39:27 +08:00

292 lines
16 KiB
PHP

<link rel="stylesheet" href="/{$template_catalog_home}/template/{$themes_home}/css/home.css">
<!-- Phosphor Icons -->
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.1/src/regular/style.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.1/src/fill/style.css" />
</head>
<body>
<!-- mounted之前显示 -->
<div id="mainLoading">
<div class="ddr ddr1"></div>
<div class="ddr ddr2"></div>
<div class="ddr ddr3"></div>
<div class="ddr ddr4"></div>
<div class="ddr ddr5"></div>
</div>
<div class="template">
<el-container>
<aside-menu></aside-menu>
<el-container>
<top-menu></top-menu>
<el-main class="home-main">
<div class="dashboard">
<!-- ====== Row 1: 用户信息 + 统计卡片 ====== -->
<div class="row-1">
<!-- 用户信息卡 -->
<div class="card card-user" @click="goUser" v-loading="nameLoading">
<div class="user-header">
<div class="user-avatar" ref="headBoxRef">{{account.firstName}}</div>
<div class="user-meta">
<div class="user-greeting">
{{lang.index_hello}}, <strong>{{account.username}}</strong>
<span v-if="idcsmart_client_level.id" class="user-level"
:style="{'color':idcsmart_client_level.background_color}">{{idcsmart_client_level.name}}</span>
</div>
<div class="user-id">ID: {{account.id}}</div>
</div>
</div>
<div class="user-contacts">
<div class="contact-item">
<i class="ph ph-envelope"></i>
<span>{{account.email ? account.email : '--'}}</span>
</div>
<div class="contact-item">
<i class="ph ph-phone"></i>
<span>{{account.phone ? account.phone : '--'}}</span>
</div>
</div>
</div>
<!-- 统计卡片组 -->
<div class="stats-group">
<div class="card card-stat stat-purple" @click="goProductList('using')">
<i class="ph ph-pulse"></i>
<div class="stat-value">{{account.host_active_num}}</div>
<div class="stat-label">{{lang.index_text6}}</div>
</div>
<div class="card card-stat stat-blue" @click="goProductList()">
<i class="ph ph-cube"></i>
<div class="stat-value">{{account.host_num}}</div>
<div class="stat-label">{{lang.index_text7}}</div>
</div>
<div class="card card-stat stat-amber" @click="goOrderList('Unpaid')">
<i class="ph ph-receipt"></i>
<div class="stat-value">{{account.unpaid_order}}</div>
<div class="stat-label">{{lang.index_text8}}</div>
</div>
</div>
</div>
<!-- ====== Row 2: 余额 + 推介/认证 ====== -->
<div class="row-2">
<!-- 余额卡片 -->
<div class="card card-balance" v-loading="nameLoading">
<div class="balance-header">
<span class="balance-title">{{lang.index_text3}}</span>
<span class="balance-btn" @click="showCz" v-if="commonData.recharge_open == 1">{{lang.index_text2}}</span>
</div>
<div class="balance-amount">
<span class="currency">{{commonData.currency_prefix}}</span>{{account.credit}}
</div>
<div class="balance-extra" v-if="commonData.recharge_open == 1 && coinRecharge.length > 0">
<span class="recharge-link" @click="showCz">{{lang.index_text35}}</span>
</div>
<div class="balance-footer">
<div class="consume-item">
<span class="consume-label">{{lang.index_text4}}</span>
<span class="consume-value">{{commonData.currency_prefix}}{{account.this_month_consume}}</span>
<span :class="Number(account.this_month_consume_percent) >= 0 ? 'trend-up' : 'trend-down'">
{{Number(account.this_month_consume_percent)}}%
</span>
</div>
<div class="consume-divider"></div>
<div class="consume-item">
<span class="consume-label">{{lang.index_text5}}</span>
<span class="consume-value">{{commonData.currency_prefix}}{{account.consume}}</span>
</div>
</div>
<!-- 信用额度 -->
<div class="credit-section" v-if="isShowCredit && creditData.status">
<div class="credit-row">
<span class="credit-label">{{lang.finance_text42}}({{commonData.currency_suffix}})</span>
<span class="credit-val">{{commonData.currency_prefix}}{{creditData.account?.status === 'Repaid' ? '0.00' : creditData.account?.amount}}</span>
</div>
<div class="credit-row">
<span class="credit-label">
{{lang.finance_text38}}
<span class="credit-tag" v-if="creditData.status === 'Expired'">{{lang.finance_text93}}</span>
<span class="credit-tag" v-if="creditData.status === 'Overdue'">{{lang.finance_text94}}</span>
<span class="credit-tag" v-if="creditData.status === 'Active'">{{lang.finance_text95}}</span>
<span class="credit-tag" v-if="creditData.status === 'Suspended'">{{lang.finance_text96}}</span>
</span>
<span class="credit-val">{{commonData.currency_prefix}}{{creditData.remaining_amount}}</span>
</div>
</div>
<!-- 代币 -->
<div class="coin-section" v-plugin="'Coin'" v-if="coinData.name">
<div class="coin-header">
<span>{{coinData.name}}</span>
<a href="/finance.htm?tab=7" target="_blank" class="coin-link">{{lang.index_text34}}</a>
</div>
<div class="coin-amount">{{commonData.currency_prefix}}{{coinData.leave_amount}}</div>
</div>
<div class="voucher-row" v-if="voucherList.length > 0">
{{lang.index_text24}}
<a href="/finance.htm?tab=4" target="_blank" class="voucher-link">{{lang.index_text25}}</a>
</div>
</div>
<!-- 右侧: 认证 + 推介 -->
<div class="card card-side">
<!-- 实名认证 -->
<div class="cert-section" v-plugin="'IdcsmartCertification'" v-if="certificationObj.certification_open === 1">
<div class="cert-item">
<div class="cert-icon"><i class="ph ph-buildings"></i></div>
<div class="cert-info">
<div class="cert-label">{{lang.index_compny}}</div>
<div class="cert-value" v-if="certificationObj.company?.status === 1">{{certificationObj.company.certification_company}}</div>
<div class="cert-action" @click="handelAttestation" v-else>{{lang.index_goAttestation}}</div>
</div>
</div>
<div class="cert-item">
<div class="cert-icon"><i class="ph ph-user"></i></div>
<div class="cert-info">
<div class="cert-label">{{lang.index_name}}</div>
<div class="cert-value" v-if="certificationObj.is_certification">
{{certificationObj.company.status === 1 ? certificationObj.company.card_name : certificationObj.person.card_name}}
</div>
<div class="cert-action" @click="handelAttestation" v-else>{{lang.index_goAttestation}}</div>
</div>
</div>
</div>
<!-- 推介计划(已开启) -->
<div class="referral-open" v-if="showRight && isOpen" v-plugin="'IdcsmartRecommend'">
<div class="referral-title">
<span>{{lang.referral_title1}}</span>
<span class="referral-reward" @click="toReferral"><i class="ph-fill ph-gift"></i> {{lang.referral_text14}}</span>
</div>
<div class="referral-url">
<div class="url-text" :title="promoterData.url">{{promoterData.url}}</div>
<div class="url-copy" @click="copyUrl(promoterData.url)">{{lang.referral_btn2}}</div>
</div>
<div class="referral-stats">
<div class="ref-stat">
<div class="ref-amount">{{commonData.currency_prefix}}{{promoterData.withdrawable_amount}}</div>
<div class="ref-label">{{lang.referral_title2}}</div>
</div>
<div class="ref-stat">
<div class="ref-amount">{{commonData.currency_prefix}}{{promoterData.pending_amount}}</div>
<div class="ref-label">{{lang.referral_title4}}</div>
</div>
</div>
</div>
<!-- 推介计划(未开启) -->
<div class="referral-closed" v-if="!showRight || !isOpen">
<i class="ph ph-megaphone"></i>
<div v-if="showRight">
<h3>{{lang.index_text17}}</h3>
<p>{{lang.index_text18}}</p>
<div class="referral-open-btn" @click="openVisible = true">{{lang.index_text28}}</div>
</div>
<div v-else class="referral-disabled">{{lang.index_text21}}</div>
</div>
</div>
</div>
<!-- ====== Row 3: 产品列表 + 工单/公告 ====== -->
<div class="row-3">
<div class="card card-products">
<h3 class="section-title">{{lang.index_text9}}</h3>
<el-table :data="productList" style="width: 100%" v-if="productList.length !== 0"
v-loading="productListLoading">
<el-table-column prop="product_name" :label="lang.index_text10">
<template slot-scope="{row}">
<a :href="`/productdetail.htm?id=${row.id}`" class="product-link" target="_blank">{{row.product_name}}</a>
</template>
</el-table-column>
<el-table-column prop="name" :label="lang.index_text12"></el-table-column>
<el-table-column prop="due_time" :label="lang.index_text13">
<template slot-scope="{row}">
<span :class="row.isOverdue ? 'text-danger' : ''">{{row.due_time | formateTime}}</span>
</template>
</el-table-column>
<el-table-column prop="client_notes" :label="lang.invoice_text139" show-overflow-tooltip>
<template slot-scope="{row}">
<span>{{row.client_notes || '--'}}</span>
</template>
</el-table-column>
</el-table>
<div v-if="productList.length === 0 && !productListLoading" class="empty-state">
<i class="ph ph-package"></i>
<h3>{{lang.index_text14}}</h3>
<p>{{lang.index_text15}}</p>
<el-button @click="goGoodsList" type="primary" round>{{lang.index_text16}}</el-button>
</div>
</div>
<!-- 工单 + 公告侧栏 -->
<div class="card card-sidebar" v-if="ticketList.length !== 0 || homeNewList.length !== 0">
<!-- 工单 -->
<div class="sidebar-section" v-if="ticketList.length !== 0" v-plugin="'IdcsmartTicket'">
<div class="sidebar-header">
<span>{{lang.index_text22}}</span>
<span class="sidebar-more" @click="goWorkPage">···</span>
</div>
<div class="ticket-list">
<div class="ticket-item" v-for="item in ticketList" :key="item.id" @click="goTickDetail(item.id)">
<span class="ticket-status" :style="{'background': item.color}">{{item.status}}</span>
<div class="ticket-info">
<div class="ticket-title">#{{item.ticket_num}} - {{item.title}}</div>
<div class="ticket-dept">{{item.name}}</div>
</div>
</div>
</div>
</div>
<!-- 公告 -->
<div class="sidebar-section" v-if="homeNewList.length !== 0" v-plugin="'IdcsmartNews'">
<div class="sidebar-header">
<span>{{lang.index_text23}}</span>
<span class="sidebar-more" @click="goNoticePage">···</span>
</div>
<div class="notice-list">
<div class="notice-item" v-for="item in homeNewList" :key="item.id" @click="goNoticeDetail(item.id)">
<div class="notice-info">
<div class="notice-title">{{item.title}}</div>
<div class="notice-meta">{{item.type}} · {{item.create_time | formareDay}}</div>
</div>
<i class="el-icon-arrow-right"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 确认开启弹窗 -->
<el-dialog :title="lang.referral_title8" :visible.sync="openVisible" width="4.8rem"
custom-class="open-dialog">
<span>{{lang.referral_tips7}}</span>
<span slot="footer" class="dialog-footer">
<el-button class="btn-ok" type="primary" @click="openReferral">{{lang.referral_btn6}}</el-button>
<el-button class="btn-no" @click="openVisible = false">{{lang.referral_btn7}}</el-button>
</span>
</el-dialog>
<pay-dialog ref="payDialog" @payok="paySuccess"></pay-dialog>
<credit-notice ref="creditNotice" @success="paySuccess"></credit-notice>
<recharge-dialog ref="rechargeDialog" @success="rechargeSuccess"></recharge-dialog>
<!-- 微信公众号 -->
<div class="wx-code" v-if="hasWxPlugin && conectInfo.is_subscribe === 0">
<el-popover width="200" trigger="hover" @show="getWxcode" placement="left">
<div class="wx-box">
<p class="tit">{{lang.wx_tip1}}</p>
<div class="img" v-loading="codeLoading">
<img :src="wxQrcode" alt="" v-if="wxQrcode">
</div>
</div>
<div class="wx-img" slot="reference"></div>
</el-popover>
</div>
</el-main>
</el-container>
</el-container>
</div>
<!-- =======页面独有======= -->
<script src="/{$template_catalog}/template/{$themes}/components/creditNotice/creditNotice.js"></script>
<script src="/{$template_catalog}/template/{$themes}/components/payDialog/payDialog.js"></script>
<script src="/{$template_catalog}/template/{$themes}/components/rechargeDialog/rechargeDialog.js"></script>
<script src="/{$template_catalog_home}/template/{$themes_home}/api/finance.js"></script>
<script src="/{$template_catalog_home}/template/{$themes_home}/api/home.js"></script>
<script src="/{$template_catalog_home}/template/{$themes_home}/js/home.js"></script>