discover.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. <template>
  2. <div class="pcPages" :style="warpCss">
  3. <div class="discover-bos" :style="boxCss">
  4. <!-- 头部 -->
  5. <div class="home-title flex-row-between" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
  6. <div @click="onPath(componentData.titleUrl)">
  7. <span :style="titleCss" class="title1 mr-[10px] hover-color">{{ componentData.title }}</span>
  8. <span :style="subtitleCss">{{ componentData.subtitle }}</span>
  9. </div>
  10. <div class="title-more flex-row-start">
  11. <div @click="onPath(item.url)" class="ml-[10px] hover-color" v-for="(item, index) in componentData.labelList" :key="index">
  12. {{ item.title }}
  13. </div>
  14. </div>
  15. </div>
  16. <!-- 中间区域 -->
  17. <div class="discover-box">
  18. <el-image
  19. class="discover-image"
  20. :src="componentData.imageUrl ? componentData.imageUrl : figure"
  21. :fit="componentData.imageUrl ? (componentData.imgType == 1 ? 'fill' : componentData.imgType == 2 ? 'contain' : 'cover') : 'cover'"
  22. :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
  23. />
  24. <div class="plan-bos" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
  25. <div class="plan-head">方案推荐</div>
  26. <div v-for="(item, index) in componentData.planList" :key="index" class="plan-list hover-color" @click="onPath(item.url)">
  27. <el-image
  28. class="plan-image"
  29. :src="item.imageUrl ? item.imageUrl : figure"
  30. :fit="item.imgType == 1 ? 'fill' : item.imgType == 2 ? 'contain' : 'cover'"
  31. :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
  32. />
  33. <div class="plan-box flex-column-between">
  34. <div class="plan-title ellipsis zi-hover">{{ item.title }}</div>
  35. <div class="plan-subtitle">{{ item.subtitle }}</div>
  36. </div>
  37. </div>
  38. </div>
  39. <div class="detect-bos" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
  40. <div class="detect-head">发现</div>
  41. <div class="detect-box">
  42. <div class="detect-two">
  43. <div
  44. @click="onPath(componentData.detectList[0].url)"
  45. class="detect-list hover-color"
  46. :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
  47. >
  48. <div class="detect-item">
  49. <div class="detect-title ellipsis zi-hover">{{ componentData.detectList[0].title }}</div>
  50. <div class="detect-subtitle mt-[6px] h-[32px]">{{ componentData.detectList[0].subtitle }}</div>
  51. <div class="detect-btn" :style="{ backgroundColor: componentData.boxColor }">立即进入</div>
  52. </div>
  53. <el-image
  54. class="detect-image"
  55. :src="componentData.detectList[0].imageUrl ? componentData.detectList[0].imageUrl : figure"
  56. :fit="componentData.detectList[0].imgType == 1 ? 'fill' : componentData.detectList[0].imgType == 2 ? 'contain' : 'cover'"
  57. :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
  58. />
  59. </div>
  60. <div
  61. @click="onPath(componentData.detectList[1].url)"
  62. class="detect-list hover-color"
  63. :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
  64. >
  65. <div class="detect-item">
  66. <div class="detect-title ellipsis zi-hover">{{ componentData.detectList[1].title }}</div>
  67. <div class="detect-subtitle mt-[6px] h-[32px]">{{ componentData.detectList[1].subtitle }}</div>
  68. <div class="detect-btn" :style="{ backgroundColor: componentData.boxColor }">立即进入</div>
  69. </div>
  70. <el-image
  71. class="detect-image"
  72. :src="componentData.detectList[1].imageUrl ? componentData.detectList[1].imageUrl : figure"
  73. :fit="componentData.detectList[1].imgType == 1 ? 'fill' : componentData.detectList[1].imgType == 2 ? 'contain' : 'cover'"
  74. :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
  75. />
  76. </div>
  77. </div>
  78. <div
  79. class="detect-one flex-column-between hover-color"
  80. :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
  81. @click="onPath(componentData.detectList[2].url)"
  82. >
  83. <div>
  84. <div class="detect-title ellipsis zi-hover">{{ componentData.detectList[2].title }}</div>
  85. <div class="detect-subtitle mt-[6px]">{{ componentData.detectList[2].subtitle }}</div>
  86. </div>
  87. <el-image
  88. class="detect-img"
  89. :src="componentData.detectList[2].imageUrl ? componentData.detectList[2].imageUrl : figure"
  90. :fit="componentData.detectList[2].imgType == 1 ? 'fill' : componentData.detectList[2].imgType == 2 ? 'contain' : 'cover'"
  91. :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
  92. />
  93. </div>
  94. </div>
  95. </div>
  96. </div>
  97. <!-- 底部 -->
  98. <div class="discover-foot">
  99. <div class="discover-tab" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
  100. <div class="tab-head" :style="{ color: componentData.boxColor }">采购导航</div>
  101. <div class="tab-bos">
  102. <div @click="onPath(item.url)" v-for="(item, index) in componentData.tabList" :key="index" class="tab-list flex-row-center hover-color">
  103. {{ item.title }}
  104. </div>
  105. </div>
  106. </div>
  107. <template v-for="(item, index) in dataList" :key="index">
  108. <div
  109. v-if="Number(index) < 4"
  110. class="goods-bos flex-column-between hover-color"
  111. :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
  112. @click="onPath('/item?id=' + item.id)"
  113. >
  114. <img
  115. class="goods-img"
  116. :src="item.productImage ? item.productImage : figure"
  117. alt=""
  118. :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
  119. />
  120. <div>
  121. <div class="goods-name zi-hover">{{ item.itemName || '商品名称' }}</div>
  122. <div class="goods-price" :style="{ color: componentData.boxColor }">¥{{ item.memberPrice || '0.00' }}</div>
  123. </div>
  124. </div>
  125. </template>
  126. </div>
  127. </div>
  128. </div>
  129. </template>
  130. <script setup lang="ts">
  131. import { onPath } from '@/utils/siteConfig';
  132. import figure from '@/assets/images/figure.png';
  133. import { getDiyProductPage } from '@/api/home/diy';
  134. interface Props {
  135. row?: any;
  136. }
  137. const props = defineProps<Props>();
  138. const componentData = props.row || {};
  139. const dataList = ref<any>([{}, {}, {}, {}]);
  140. onMounted(() => {
  141. getDataList();
  142. });
  143. const getDataList = () => {
  144. dataList.value = [{}, {}, {}, {}];
  145. if (componentData.goodsIds.length > 0) {
  146. getDiyProductPage({ pageNum: 1, pageSize: 10, ids: componentData.goodsIds.join(',') }).then((res) => {
  147. if (res.code == 200) {
  148. dataList.value = res.rows;
  149. }
  150. });
  151. }
  152. };
  153. const warpCss = computed(() => {
  154. let style = '';
  155. style += 'position:relative;';
  156. //背景颜色
  157. if (componentData.pageStartBgColor) {
  158. if (componentData.pageStartBgColor && componentData.pageEndBgColor)
  159. style += `background:linear-gradient(${componentData.pageGradientAngle},${componentData.pageStartBgColor},${componentData.pageEndBgColor});`;
  160. else if (componentData.pageStartBgColor) style += `background: ${componentData.pageStartBgColor};`;
  161. else if (componentData.pageEndBgColor) style += `background: ${componentData.pageEndBgColor};`;
  162. }
  163. //背景图片
  164. if (componentData.componentBgUrl) {
  165. style += `background-image:url('${componentData.componentBgUrl}');`;
  166. style += 'background-size: cover;background-repeat: no-repeat;';
  167. }
  168. //边距
  169. if (componentData.padding) {
  170. if (componentData.padding.top > 0) {
  171. style += 'padding-top:' + componentData.padding.top + 'px' + ';';
  172. }
  173. if (componentData.padding.bottom > 0) {
  174. style += 'padding-bottom:' + componentData.padding.bottom + 'px' + ';';
  175. }
  176. style += 'padding-right:' + componentData.padding.both + 'px' + ';';
  177. style += 'padding-left:' + componentData.padding.both + 'px' + ';';
  178. }
  179. //圆角
  180. if (componentData.topRounded) style += 'border-top-left-radius:' + componentData.topRounded + 'px;';
  181. if (componentData.topRounded) style += 'border-top-right-radius:' + componentData.topRounded + 'px;';
  182. if (componentData.bottomRounded) style += 'border-bottom-left-radius:' + componentData.bottomRounded + 'px;';
  183. if (componentData.bottomRounded) style += 'border-bottom-right-radius:' + componentData.bottomRounded + 'px;';
  184. //间距
  185. if (componentData.margin) {
  186. if (componentData.margin.top > 0) {
  187. style += 'margin-top:' + componentData.margin.top + 'px' + ';';
  188. }
  189. if (componentData.margin.bottom > 0) {
  190. style += 'margin-bottom:' + componentData.margin.bottom + 'px' + ';';
  191. }
  192. }
  193. return style;
  194. });
  195. //组件样式
  196. const boxCss = computed(() => {
  197. let style = '';
  198. if (componentData.componentStartBgColor && componentData.componentEndBgColor)
  199. style += `background:linear-gradient(${componentData.componentGradientAngle},${componentData.componentStartBgColor},${componentData.componentEndBgColor});`;
  200. else if (componentData.componentStartBgColor) style += 'background-color:' + componentData.componentStartBgColor + ';';
  201. else if (componentData.componentEndBgColor) style += 'background-color:' + componentData.componentEndBgColor + ';';
  202. if (componentData.number) style += 'flex:' + `0 0 calc((100% - ${(componentData.number - 1) * 10}px) / ${componentData.number})` + ';';
  203. return style;
  204. });
  205. // 标题样式
  206. const titleCss = computed(() => {
  207. let style = '';
  208. if (componentData.titleColor) style += 'color:' + componentData.titleColor + ';';
  209. if (componentData.titleSize) style += 'font-size:' + componentData.titleSize + 'px;';
  210. if (componentData.titleWeight) style += 'font-weight:' + componentData.titleWeight + ';';
  211. return style;
  212. });
  213. // 副标题样式
  214. const subtitleCss = computed(() => {
  215. let style = '';
  216. if (componentData.subtitleColor) style += 'color:' + componentData.subtitleColor + ';';
  217. if (componentData.subtitleSize) style += 'font-size:' + componentData.subtitleSize + 'px;';
  218. return style;
  219. });
  220. </script>
  221. <style lang="scss" scoped>
  222. .pcPages {
  223. width: 1200px;
  224. margin: 0 auto;
  225. .discover-bos {
  226. width: 100%;
  227. .home-title {
  228. width: 100%;
  229. background-color: #ffffff;
  230. padding: 15px 20px;
  231. .title-more {
  232. font-size: 14px;
  233. color: #333333;
  234. }
  235. }
  236. }
  237. //中间区域
  238. .discover-box {
  239. height: 340px;
  240. width: 100%;
  241. margin-top: 10px;
  242. display: flex;
  243. gap: 10px;
  244. .discover-image {
  245. width: 230px;
  246. height: 340px;
  247. cursor: pointer;
  248. }
  249. // 方案
  250. .plan-bos {
  251. flex: 1;
  252. height: 340px;
  253. background: #ffffff;
  254. padding: 0px 15px;
  255. display: flex;
  256. flex-direction: column;
  257. min-width: 0;
  258. .plan-head {
  259. font-weight: 600;
  260. font-size: 16px;
  261. color: #101828;
  262. height: 50px;
  263. line-height: 50px;
  264. }
  265. .plan-list {
  266. flex: 1;
  267. display: flex;
  268. border-bottom: 1px solid #e5e7eb;
  269. cursor: pointer;
  270. width: 100%;
  271. margin-bottom: 14px;
  272. &:last-child {
  273. border-bottom: none;
  274. margin-bottom: 0;
  275. }
  276. .plan-image {
  277. width: 72px;
  278. height: 72px;
  279. margin-right: 10px;
  280. }
  281. .plan-box {
  282. height: 72px;
  283. flex: 1;
  284. padding: 8px 0px 8px 5px;
  285. width: 0;
  286. .plan-title {
  287. font-weight: 600;
  288. font-size: 14px;
  289. color: #101828;
  290. }
  291. .plan-subtitle {
  292. height: 34px;
  293. font-weight: 400;
  294. font-size: 12px;
  295. color: #364153;
  296. display: -webkit-box;
  297. -webkit-line-clamp: 2;
  298. line-clamp: 2;
  299. /* 添加标准属性 */
  300. -webkit-box-orient: vertical;
  301. overflow: hidden;
  302. text-overflow: ellipsis;
  303. }
  304. }
  305. }
  306. }
  307. .detect-bos {
  308. width: 470px;
  309. height: 340px;
  310. background: #ffffff;
  311. padding: 0px 15px 15px 15px;
  312. .detect-head {
  313. font-weight: 600;
  314. font-size: 16px;
  315. color: #101828;
  316. height: 50px;
  317. line-height: 50px;
  318. }
  319. .detect-box {
  320. display: flex;
  321. gap: 10px;
  322. .detect-title {
  323. font-weight: 600;
  324. font-size: 14px;
  325. color: #101828;
  326. }
  327. .detect-subtitle {
  328. font-weight: 400;
  329. font-size: 12px;
  330. color: #364153;
  331. display: -webkit-box;
  332. -webkit-line-clamp: 2;
  333. line-clamp: 2;
  334. /* 添加标准属性 */
  335. -webkit-box-orient: vertical;
  336. overflow: hidden;
  337. text-overflow: ellipsis;
  338. }
  339. .detect-two {
  340. flex: 1;
  341. width: 0;
  342. .detect-list {
  343. width: 100%;
  344. height: 132.5px;
  345. border: 1px solid #e5e7eb;
  346. margin-top: 10px;
  347. padding: 25px 10px;
  348. display: flex;
  349. gap: 10px;
  350. &:first-child {
  351. margin-top: 0;
  352. }
  353. .detect-item {
  354. flex: 1;
  355. width: 0;
  356. .detect-btn {
  357. width: 68px;
  358. height: 24px;
  359. text-align: center;
  360. line-height: 24px;
  361. font-size: 12px;
  362. color: #ffffff;
  363. margin-top: 12px;
  364. }
  365. }
  366. .detect-image {
  367. height: 72px;
  368. width: 72px;
  369. }
  370. }
  371. }
  372. .detect-one {
  373. width: 180px;
  374. height: 275px;
  375. border: 1px solid #e5e7eb;
  376. background-color: #ffffff;
  377. padding: 25px 10px;
  378. .detect-img {
  379. height: 124px;
  380. width: 124px;
  381. margin: 0 auto;
  382. }
  383. }
  384. }
  385. }
  386. }
  387. //底部
  388. .discover-foot {
  389. display: flex;
  390. gap: 10px;
  391. margin-top: 10px;
  392. .discover-tab {
  393. width: 230px;
  394. height: 310px;
  395. background: #ffffff;
  396. padding: 0 15px 15px 15px;
  397. .tab-head {
  398. font-weight: 600;
  399. font-size: 16px;
  400. height: 50px;
  401. line-height: 50px;
  402. }
  403. .tab-bos {
  404. display: flex;
  405. flex-wrap: wrap;
  406. justify-content: space-between;
  407. gap: 10px 0;
  408. .tab-list {
  409. width: 94px;
  410. height: 32px;
  411. background: #f4f4f4;
  412. font-size: 14px;
  413. color: #101828;
  414. border-radius: 4px 4px 4px 4px;
  415. }
  416. }
  417. }
  418. .goods-bos {
  419. flex: 0 0 calc((100% - 270px) / 4);
  420. width: 0;
  421. background: #ffffff;
  422. height: 310px;
  423. padding: 15px 20px;
  424. .goods-img {
  425. width: 100%;
  426. height: 190px;
  427. }
  428. .goods-name {
  429. width: 100%;
  430. display: -webkit-box;
  431. -webkit-line-clamp: 3;
  432. line-clamp: 3;
  433. /* 添加标准属性 */
  434. -webkit-box-orient: vertical;
  435. overflow: hidden;
  436. text-overflow: ellipsis;
  437. font-size: 14px;
  438. color: #101828;
  439. height: 57px;
  440. }
  441. .goods-price {
  442. font-size: 16px;
  443. margin-top: 5px;
  444. }
  445. }
  446. }
  447. }
  448. </style>