ShopDetail.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <script lang="ts" setup>
  2. /**
  3. * @Name: ShopDetail.vue
  4. * @Description: 店铺详情
  5. * @Author: Cheney
  6. */
  7. import { Edit, Monitor, Picture as IconPicture, RefreshLeft, Timer } from '@element-plus/icons-vue';
  8. import { useResponse } from '/@/utils/useResponse';
  9. import * as api from '/@/views/shop-information/api';
  10. import {
  11. computerColumns,
  12. historyColumns,
  13. shopCurrentColumns,
  14. companySelect
  15. } from '/@/views/shop-information/useColumns';
  16. import { useTableData } from '/@/utils/useTableData';
  17. import { usePagination } from '/@/utils/usePagination';
  18. import EditDrawer from './EditDrawer.vue';
  19. import { getOperator } from '/@/views/shop-information/api';
  20. import { useTableHeight } from '/@/utils/useTableHeight';
  21. const cardContainer: Ref<HTMLElement | null> = useTemplateRef('cardContainer');
  22. const { tableHeight } = useTableHeight(cardContainer );
  23. const route = useRoute();
  24. const platformNumber = route.query.platformNumber as string;
  25. const shopOverview: any = ref([]);
  26. const overviewLoading = ref(false);
  27. const selectedTab = ref('1');
  28. const { tableOptions, handlePageChange } = usePagination(handleTabChange);
  29. const gridOptions: any = reactive({
  30. border: false,
  31. round: true,
  32. stripe: true,
  33. currentRowHighLight: true,
  34. height: '100%',
  35. toolbarConfig: {
  36. custom: true,
  37. slots: {
  38. buttons: 'toolbar_buttons',
  39. tools: 'toolbar_tools'
  40. }
  41. },
  42. rowConfig: {
  43. isHover: true
  44. },
  45. columnConfig: {
  46. resizable: true
  47. },
  48. pagerConfig: {
  49. total: tableOptions.value.total,
  50. page: tableOptions.value.page,
  51. limit: tableOptions.value.limit
  52. },
  53. loading: false,
  54. loadingConfig: {
  55. icon: 'vxe-icon-indicator roll',
  56. text: '正在拼命加载中...'
  57. },
  58. columns: '',
  59. data: ''
  60. });
  61. const isOpen = ref(false);
  62. const formSelect = ref<{ country: string[], line: string[] }>({
  63. country: [],
  64. line: []
  65. });
  66. const operatorOption = ref<{ id: number; name: string }[]>([]);
  67. // const companySelect = ref<{ id: string, company: string }>({
  68. // id: '',
  69. // company: ''
  70. // });
  71. onBeforeMount(() => {
  72. fetchShopDetailOverview();
  73. handleTabChange(selectedTab.value);
  74. fetchSelect();
  75. fetchOperator();
  76. });
  77. async function fetchSelect() {
  78. const res = await useResponse({}, api.getShopSelect);
  79. formSelect.value = res.data;
  80. // const ret = await useResponse({}, api.getCompanySelect);
  81. // companySelect.value = ret.data;
  82. }
  83. async function fetchShopDetailOverview() {
  84. const res = await useResponse({ platformNumber }, api.getShopDetailOverview, overviewLoading);
  85. shopOverview.value = res.data;
  86. }
  87. async function handleTabChange(tabValue: any) {
  88. gridOptions.pagerConfig.page = 1;
  89. gridOptions.pagerConfig.limit = 10;
  90. const query = {
  91. platformNumber,
  92. page: gridOptions.pagerConfig.page,
  93. limit: gridOptions.pagerConfig.limit
  94. };
  95. switch (tabValue) {
  96. case '1':
  97. gridOptions.columns = shopCurrentColumns;
  98. await useTableData(api.getCurrentInfo, query, gridOptions);
  99. break;
  100. case '2':
  101. gridOptions.columns = historyColumns;
  102. await useTableData(api.getHistoryInfo, query, gridOptions);
  103. break;
  104. case '3':
  105. gridOptions.columns = computerColumns;
  106. await useTableData(api.getComputerInfo, query, gridOptions);
  107. break;
  108. }
  109. }
  110. function drawerOpen() {
  111. isOpen.value = true;
  112. }
  113. function handleRefresh() {
  114. handleTabChange(selectedTab.value);
  115. }
  116. async function fetchOperator() {
  117. const res = await useResponse({}, api.getOperator);
  118. operatorOption.value = res.data;
  119. }
  120. </script>
  121. <template>
  122. <div class="p-5 flex flex-col gap-2.5">
  123. <el-card v-loading="overviewLoading" shadow="hover" style="border: none">
  124. <div ref="cardContainer" class="flex items-center gap-10">
  125. <div v-if="platformNumber" class="artistic-text-container mr-7 ">
  126. <div class="artistic-text">
  127. {{ platformNumber }}
  128. </div>
  129. </div>
  130. <el-image v-else class="mr-7 rounded-2xl" src="" style="height: 120px; width: 120px; object-fit: contain">
  131. <template #error>
  132. <div class="mr-3.5 flex items-center justify-center text-5xl"
  133. style="height: 100%; width: 100%; background-color: #f5f5f5">
  134. <el-icon>
  135. <icon-picture />
  136. </el-icon>
  137. </div>
  138. </template>
  139. </el-image>
  140. <div class="text-lg">
  141. <div class="font-semibold">
  142. 平台编号:
  143. <span class="font-medium italic ml-1.5" style="color: #64748b">
  144. {{ shopOverview[0]?.platformNumber ? shopOverview[0]?.platformNumber : '--' }}
  145. </span>
  146. </div>
  147. <div class="font-semibold">
  148. 所属公司:
  149. <span class="font-medium italic ml-1.5" style="color: #64748b">
  150. {{ shopOverview[0]?.company ? shopOverview[0]?.company : '--' }}
  151. </span>
  152. </div>
  153. <div class="font-semibold">
  154. 所属平台:
  155. <span class="font-medium italic ml-1.5" style="color: #64748b">
  156. {{ shopOverview[0]?.platform ? shopOverview[0]?.platform : '--' }}
  157. </span>
  158. </div>
  159. <div class="font-semibold">
  160. 运营:
  161. <span class="font-medium italic ml-1.5" style="color: #64748b">
  162. {{ shopOverview[0]?.operatorName ? shopOverview[0]?.operatorName : '--' }}
  163. </span>
  164. </div>
  165. <div class="font-semibold">
  166. 电脑:
  167. <span class="font-medium italic ml-1.5" style="color: #64748b">
  168. {{ shopOverview[0]?.countComputer === 0 ? '0' : shopOverview[0]?.countComputer || '--' }}
  169. </span>
  170. </div>
  171. </div>
  172. <div class="text-lg">
  173. <div class="font-semibold">
  174. 主账户手机号及归属人:
  175. <span class="font-medium italic ml-1.5" style="color: #64748b">
  176. {{ shopOverview[0]?.shopPhoneAndNameStr ? shopOverview[0]?.shopPhoneAndNameStr : '--' }}
  177. </span>
  178. </div>
  179. <div class="font-semibold">
  180. 主账户Email:
  181. <span class="font-medium italic ml-1.5" style="color: #64748b">
  182. {{ shopOverview[0]?.shopEmail ? shopOverview[0]?.shopEmail : '--' }}
  183. </span>
  184. </div>
  185. <div class="font-semibold">
  186. 子账户手机号及归属人:
  187. <span class="font-medium italic ml-1.5" style="color: #64748b">
  188. {{ shopOverview[0]?.subShopPhoneAndNameStr ? shopOverview[0]?.subShopPhoneAndNameStr : '--' }}
  189. </span>
  190. </div>
  191. <div class="font-semibold">
  192. 子账户Email:
  193. <span class="font-medium italic ml-1.5" style="color: #64748b">
  194. {{ shopOverview[0]?.subShopEmail ? shopOverview[0]?.subShopEmail : '--' }}
  195. </span>
  196. </div>
  197. </div>
  198. </div>
  199. </el-card>
  200. <el-card class="mt-2.5 flex-1" shadow="hover" style="border: none">
  201. <div :style="{ height: tableHeight + 'px' }">
  202. <vxe-grid v-bind="gridOptions">
  203. <template #toolbar_buttons>
  204. <el-radio-group v-model="selectedTab" @change="handleTabChange(selectedTab)">
  205. <el-radio-button label="当前信息" value="1">
  206. <template #default>
  207. <el-icon style="top: 2px;">
  208. <Timer />
  209. </el-icon>
  210. 当前信息
  211. </template>
  212. </el-radio-button>
  213. <el-radio-button label="历史记录" value="2">
  214. <template #default>
  215. <el-icon style="top: 2px;">
  216. <RefreshLeft />
  217. </el-icon>
  218. 历史记录
  219. </template>
  220. </el-radio-button>
  221. <el-radio-button label="电脑信息" value="3">
  222. <template #default>
  223. <el-icon style="top: 2px;">
  224. <Monitor />
  225. </el-icon>
  226. 电脑信息
  227. </template>
  228. </el-radio-button>
  229. </el-radio-group>
  230. </template>
  231. <template #toolbar_tools>
  232. <div class="mr-2.5">
  233. <el-button :disabled="selectedTab != '1'" :icon="Edit" circle plain type="warning"
  234. @click="drawerOpen"></el-button>
  235. </div>
  236. </template>
  237. <template #pager>
  238. <vxe-pager
  239. v-model:currentPage="gridOptions.pagerConfig.page"
  240. v-model:pageSize="gridOptions.pagerConfig.limit"
  241. :total="gridOptions.pagerConfig.total"
  242. @page-change="handlePageChange"
  243. >
  244. </vxe-pager>
  245. </template>
  246. </vxe-grid>
  247. </div>
  248. </el-card>
  249. <EditDrawer
  250. v-if="isOpen"
  251. v-model="isOpen"
  252. :companySelect
  253. :formSelect
  254. :gridOptions="gridOptions"
  255. :operatorOption
  256. :platformNumber
  257. @refresh="handleRefresh"
  258. />
  259. </div>
  260. </template>
  261. <style scoped>
  262. .artistic-text-container {
  263. height: 120px; /* 高度与要求一致 */
  264. width: 120px; /* 宽度与要求一致 */
  265. display: flex;
  266. align-items: center; /* 垂直居中 */
  267. justify-content: center; /* 水平居中 */
  268. background-color: #f5f5f5; /* 背景色 */
  269. border-radius: 12px; /* 圆角 */
  270. overflow: hidden; /* 隐藏溢出部分 */
  271. position: relative; /* 为绝对定位提供参考 */
  272. }
  273. .artistic-text {
  274. font-size: 1rem; /* 初始字体大小 */
  275. font-weight: bold; /* 加粗字体 */
  276. text-align: center; /* 居中对齐 */
  277. background: linear-gradient(90deg, #c86fc9, #3023ae);
  278. -webkit-background-clip: text; /* 背景裁剪 */
  279. -webkit-text-fill-color: transparent; /* 字体颜色透明 */
  280. white-space: nowrap; /* 防止换行 */
  281. overflow: hidden; /* 隐藏溢出部分 */
  282. text-overflow: ellipsis; /* 溢出部分用省略号表示 */
  283. transform: scale(1); /* 默认缩放为 1 */
  284. transition: transform 0.2s ease; /* 动画过渡效果 */
  285. max-width: 100%; /* 最大宽度为 100% */
  286. }
  287. /* 当文本溢出时,缩小文本以适应容器 */
  288. .artistic-text-container:has(.artistic-text) {
  289. /* 计算并缩放文本 */
  290. animation: scale-text 0.2s forwards;
  291. }
  292. /* @keyframes scale-text {
  293. 0% {
  294. transform: scale(1);
  295. }
  296. 100% {
  297. transform: scale(calc(120px / var(--text-width))); !* 根据文本宽度缩放 *!
  298. }
  299. } */
  300. </style>