JDUserPanel.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <template>
  2. <div class="user-panel">
  3. <!-- 顶部极淡粉色渐变背景 -->
  4. <div class="top-bg"></div>
  5. <!-- 用户信息区 -->
  6. <div class="u-auth flex">
  7. <div class="avatar">
  8. <img :src="logo2" />
  9. </div>
  10. <div class="u-info">
  11. <p class="name">{{ userInfo.nickName }}</p>
  12. <!-- <p @click="onPath('/breg')" class="links">切换企业账号<span class="divider">|</span>注册</p> -->
  13. </div>
  14. </div>
  15. <!-- 会员卡片 -->
  16. <div class="member-card">
  17. <div class="c-tag">企业会员</div>
  18. <div class="c-main flex-between">
  19. <div class="c-left">
  20. <div class="c-h">授信余额</div>
  21. <p class="credit-num">{{ salesInfo.creditAmount || '0.00' }}元</p>
  22. </div>
  23. </div>
  24. </div>
  25. <!-- 订单状态统计 -->
  26. <div class="order-stats">
  27. <div class="stat-item">
  28. <div class="num">{{ countData.pendingapprovalCount || 0 }}</div>
  29. <div class="label">待审批</div>
  30. </div>
  31. <div class="stat-item">
  32. <div class="num">{{ countData.pendingPaymentCount || 0 }}</div>
  33. <div class="label">待付款</div>
  34. </div>
  35. <div class="stat-item">
  36. <div class="num">{{ countData.pendingShipmentCount || 0 }}</div>
  37. <div class="label">待发货</div>
  38. </div>
  39. <div class="stat-item">
  40. <div class="num">{{ countData.pendingReceiptCount || 0 }}</div>
  41. <div class="label">待收货</div>
  42. </div>
  43. </div>
  44. <!-- 企业工作台 -->
  45. <div class="tools-sec relative">
  46. <div class="t-h flex-between" @click="onPath(dataInfo.jumpLink)">
  47. <span>{{ dataInfo.moduleName }}</span>
  48. <i class="icon-more">&gt;</i>
  49. </div>
  50. <!-- 滑动翻页组件 -->
  51. <div class="t-slider-wrap">
  52. <div class="t-track" :style="{ transform: `translateX(-${currentPage * 100}%)` }">
  53. <div class="t-page" v-for="(item1, index1) in dataList" :key="index1">
  54. <div class="t-grid">
  55. <div class="t-i" v-for="(item2, index2) in item1" :key="index2" @click="onPath(item2.jumpLink)">
  56. <el-image class="t-icon" :src="item2.iconUrl" />
  57. <span>{{ item2.name }}</span>
  58. </div>
  59. </div>
  60. </div>
  61. </div>
  62. <!-- 滑动按钮 -->
  63. <div class="flip-btn prev-btn" v-show="currentPage > 0" @click="currentPage--">
  64. <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
  65. <polyline points="15 18 9 12 15 6"></polyline>
  66. </svg>
  67. </div>
  68. <div class="flip-btn next-btn" v-show="currentPage < 1 && dataList.length > 1" @click="currentPage++">
  69. <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
  70. <polyline points="9 18 15 12 9 6"></polyline>
  71. </svg>
  72. </div>
  73. </div>
  74. </div>
  75. </div>
  76. </template>
  77. <script setup lang="ts">
  78. import { currentQuickEntryModule } from '@/api/home/index-enterprise';
  79. import { getEnterpriseInfo } from '@/api/pc/enterprise';
  80. import { getInfo } from '@/api/login';
  81. import { onPath } from '@/utils/siteConfig';
  82. import { countOrder } from '@/api/home/index';
  83. import logo2 from '@/assets/images/pcdiy/logo2.png';
  84. const dataList = ref<any>([]);
  85. const dataInfo = ref<any>({});
  86. const userInfo = ref<any>({});
  87. const countData = ref<any>({});
  88. const salesInfo = ref<any>({});
  89. getEnterpriseInfo().then((res) => {
  90. if (res.code == 200) {
  91. salesInfo.value = res.data.customerSalesInfoVo || {};
  92. }
  93. });
  94. currentQuickEntryModule({}).then((res) => {
  95. if (res.code == 200) {
  96. dataInfo.value = res.data;
  97. if (res.data && res.data.items.length > 0) {
  98. dataList.value = chunkArray(res.data.items, 8);
  99. }
  100. }
  101. });
  102. const chunkArray = (arr, size) => {
  103. const result = [];
  104. for (let i = 0; i < arr.length; i += size) {
  105. result.push(arr.slice(i, i + size));
  106. }
  107. return result;
  108. };
  109. getInfo().then((res) => {
  110. if (res.code == 200) {
  111. userInfo.value = res.data.user;
  112. }
  113. });
  114. countOrder({}).then((res) => {
  115. if (res.code == 200) {
  116. countData.value = res.data || {};
  117. }
  118. });
  119. const currentPage = ref(0);
  120. </script>
  121. <style scoped>
  122. .user-panel {
  123. background: #fff;
  124. height: 100%;
  125. border-radius: 12px;
  126. position: relative;
  127. overflow: hidden;
  128. display: flex;
  129. flex-direction: column;
  130. }
  131. /* 顶部极淡粉色渐变背景 */
  132. .top-bg {
  133. position: absolute;
  134. top: 0;
  135. left: 0;
  136. right: 0;
  137. height: 120px;
  138. background: linear-gradient(to bottom, #fff5ee, #ffffff);
  139. z-index: 0;
  140. }
  141. /* 内容提升层级 */
  142. .u-auth,
  143. .member-card,
  144. .card-benefits,
  145. .small-ad,
  146. .tools-sec {
  147. position: relative;
  148. z-index: 1;
  149. }
  150. .u-auth {
  151. padding: 16px 16px 0;
  152. align-items: center;
  153. margin-bottom: 12px;
  154. }
  155. .avatar img {
  156. width: 48px;
  157. height: 48px;
  158. border-radius: 50%;
  159. border: 2px solid #fff;
  160. box-shadow: 0 2px 6px rgba(255, 182, 193, 0.3);
  161. margin-right: 12px;
  162. }
  163. .name {
  164. font-weight: bold;
  165. font-size: 14px;
  166. color: #000;
  167. }
  168. .links {
  169. font-size: 11px;
  170. color: #666;
  171. margin-top: 4px;
  172. cursor: pointer;
  173. }
  174. .divider {
  175. margin: 0 6px;
  176. color: #e0e0e0;
  177. }
  178. .member-card {
  179. margin: 0 16px;
  180. background: linear-gradient(to right, #fdf0de, #fce3c5);
  181. border-radius: 8px;
  182. position: relative;
  183. padding: 22px 12px 12px; /* 增加顶部边距,避开标签 */
  184. }
  185. .c-tag {
  186. position: absolute;
  187. top: 0;
  188. left: 0;
  189. background: #11366f;
  190. color: #f8d9a8;
  191. font-size: 10px;
  192. padding: 2px 8px;
  193. border-radius: 8px 0 8px 0;
  194. font-weight: bold;
  195. }
  196. .c-h {
  197. font-weight: 800;
  198. font-size: 13px;
  199. color: #11366f; /* 使用标签背景色 */
  200. letter-spacing: 0.3px;
  201. }
  202. .c-left p.credit-num {
  203. font-size: 20px;
  204. font-weight: 900;
  205. color: #e1251b; /* 使用红色 */
  206. margin-top: 4px;
  207. letter-spacing: 0.5px;
  208. }
  209. .order-stats {
  210. margin: 12px 16px 18px;
  211. background: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(254, 242, 242, 0.8) 100%);
  212. border: 1px solid rgba(225, 37, 27, 0.1);
  213. border-radius: 10px;
  214. display: flex;
  215. justify-content: space-around;
  216. padding: 14px 0;
  217. box-shadow: 0 4px 15px rgba(225, 37, 27, 0.04);
  218. }
  219. .stat-item {
  220. text-align: center;
  221. flex: 1;
  222. position: relative;
  223. }
  224. .stat-item:not(:last-child)::after {
  225. content: '';
  226. position: absolute;
  227. right: 0;
  228. top: 20%;
  229. height: 60%;
  230. width: 1px;
  231. background: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.05), transparent);
  232. }
  233. .stat-item .num {
  234. font-size: 16px;
  235. font-weight: 800;
  236. color: #e1251b;
  237. font-family: Arial, sans-serif;
  238. }
  239. .stat-item .label {
  240. font-size: 11px;
  241. color: #666;
  242. margin-top: 5px;
  243. }
  244. .tools-sec {
  245. padding: 0 16px;
  246. flex: 1;
  247. }
  248. .t-h {
  249. font-weight: bold;
  250. font-size: 14px;
  251. color: #000;
  252. margin-bottom: 15px;
  253. }
  254. .icon-more {
  255. font-size: 12px;
  256. color: #999;
  257. font-style: normal;
  258. cursor: pointer;
  259. }
  260. .t-slider-wrap {
  261. position: relative;
  262. overflow: hidden;
  263. width: 100%;
  264. }
  265. .t-track {
  266. display: flex;
  267. transition: transform 0.3s ease-in-out;
  268. }
  269. .t-page {
  270. width: 100%;
  271. flex-shrink: 0;
  272. }
  273. .flip-btn {
  274. position: absolute;
  275. top: 50%;
  276. transform: translateY(-50%);
  277. width: 20px;
  278. height: 20px;
  279. background: #fff;
  280. border-radius: 50%;
  281. display: flex;
  282. align-items: center;
  283. justify-content: center;
  284. cursor: pointer;
  285. box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
  286. z-index: 10;
  287. transition: background 0.2s;
  288. }
  289. .flip-btn:hover {
  290. background: #f4f4f4;
  291. }
  292. .prev-btn {
  293. left: 4px;
  294. }
  295. .next-btn {
  296. right: 4px;
  297. }
  298. .t-grid {
  299. display: grid;
  300. grid-template-columns: repeat(4, 1fr);
  301. grid-template-rows: repeat(2, 1fr);
  302. gap: 16px 0;
  303. }
  304. .t-i {
  305. text-align: center;
  306. font-size: 11px;
  307. color: #333;
  308. position: relative;
  309. display: flex;
  310. flex-direction: column;
  311. align-items: center;
  312. cursor: pointer;
  313. }
  314. .t-icon {
  315. width: 24px;
  316. height: 24px;
  317. margin-bottom: 6px;
  318. opacity: 0.8;
  319. }
  320. .badge {
  321. position: absolute;
  322. top: -8px;
  323. right: -2px;
  324. background: #ff5a5f;
  325. color: #fff;
  326. font-size: 9px;
  327. padding: 1px 4px;
  328. border-radius: 8px 8px 8px 0;
  329. z-index: 2;
  330. border: 1px solid #fff;
  331. transform: scale(0.9);
  332. }
  333. </style>