cb-biz-ui 1.7.5 → 1.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <view class="goods-card bottom-border" @tap="itemTap">
3
3
  <view class="goods-card_image">
4
- <ui-lazyload-img
4
+ <!-- <ui-lazyload-img
5
5
  :width="imgWidth"
6
6
  :height="imgHeight"
7
7
  radius="8rpx"
@@ -11,7 +11,7 @@
11
11
  :mode="imageMode"
12
12
  :src="goodsImage"
13
13
  sizeType="previewImage"
14
- ></ui-lazyload-img>
14
+ ></ui-lazyload-img> -->
15
15
  <!-- <view
16
16
  :style="{
17
17
  width: imgWidth,
@@ -21,77 +21,59 @@
21
21
  class="goods-status_error"
22
22
  >{{ errStatusText }}</view
23
23
  > -->
24
+ <image
25
+ :mode="imageMode"
26
+ :draggable="false"
27
+ :src="goodsImage"
28
+ :style="{ width: imgWidth, height: imgHeight, borderRadius: '8rpx' }"
29
+ />
24
30
  </view>
25
31
  <view class="goods-card_info">
26
32
  <view class="goods-card_info_title">
27
33
  <ui-overflow-hidden size="24rpx">
28
- <text class="text" :style="{ fontSize: textFontSize.title }"
29
- >{{ entity.name }}
34
+ <text class="text" :style="{ fontSize: textFontSize.title }">{{ entity.name }}
30
35
  </text>
31
36
  </ui-overflow-hidden>
32
37
  </view>
33
38
  <view class="rebate-box" v-if="entity.rebateGold">
34
39
  <view class="rebate-box_title"> 购买返利 </view>
35
40
  <view class="rebate-box_content">
36
- <text class="rebate-box_content_text"
37
- >约¥{{ entity.rebateMoney || 0 }}</text
38
- >
41
+ <text class="rebate-box_content_text">约¥{{ entity.rebateMoney || 0 }}</text>
39
42
  <view class="rebate-box_content_icon">
40
43
  (
41
44
  <text class="rebate-box_content_icon_text">{{
42
45
  entity.rebateGold
43
46
  }}</text>
44
- <image
45
- class="rebate-icon"
46
- src="https://shop-cdn.cbyzx.com/shop23n05y18abcd/img/21f285a66453412e8cd0046ed31aa222@.png"
47
- />
47
+ <image class="rebate-icon"
48
+ src="https://shop-cdn.cbyzx.com/shop23n05y18abcd/img/21f285a66453412e8cd0046ed31aa222@.png" />
48
49
  )
49
50
  </view>
50
51
  </view>
51
52
  </view>
52
53
  <view class="goods-card_info_sales-specification" v-if="entity.attrValue && entity.attrUnitValue">
53
- <text
54
- class="goods-card_info_sales-specification_text"
55
- :style="{ fontSize: '22rpx' }"
56
- >{{ entity.attrValue + '/' + entity.attrUnitValue }}
54
+ <text class="goods-card_info_sales-specification_text" :style="{ fontSize: '22rpx' }">{{ entity.attrValue + '/'
55
+ + entity.attrUnitValue }}
57
56
  </text>
58
57
  </view>
59
58
  <view class="goods-card_info_sales-volume" v-if="entity.saleCnt">
60
- <text
61
- class="goods-card_info_sales-volume_text"
62
- :style="{ fontSize: textFontSize.salesVolume }"
63
- >销量{{ ` ` }}{{ entity.saleCnt || 0 }}
59
+ <text class="goods-card_info_sales-volume_text" :style="{ fontSize: textFontSize.salesVolume }">销量{{ ` ` }}{{
60
+ entity.saleCnt || 0 }}
64
61
  </text>
65
62
  </view>
66
63
  <view class="goods-card_info_tag" v-if="entity.hasDiscount">
67
- <ui-tag
68
- type="danger"
69
- padding="6rpx 10rpx"
70
- :size="textFontSize.tag"
71
- plain
72
- >
64
+ <ui-tag type="danger" padding="6rpx 10rpx" :size="textFontSize.tag" plain>
73
65
  <view class="tag-box">
74
- <image
75
- class="icon icon_yh"
76
- src="https://shop-cdn.cbyzx.com/shop23n05y18abcd/img/5131a04c08bf4c80b73291f82186ce46.png"
77
- />
66
+ <image class="icon icon_yh"
67
+ src="https://shop-cdn.cbyzx.com/shop23n05y18abcd/img/5131a04c08bf4c80b73291f82186ce46.png" />
78
68
 
79
69
  <text>{{ getDiscount(entity.discount) }}</text>
80
70
  </view>
81
71
  </ui-tag>
82
72
  <view v-if="entity.purchaseLimitNum > 0" style="margin-left: 10rpx">
83
- <ui-tag
84
- type="danger"
85
- padding="6rpx 10rpx"
86
- :size="textFontSize.tag"
87
- plain
88
- >
73
+ <ui-tag type="danger" padding="6rpx 10rpx" :size="textFontSize.tag" plain>
89
74
  <view class="tag-box">
90
- <image
91
- class="icon icon_yh"
92
- style="width: 28rpx"
93
- src="https://shop-cdn.cbyzx.com/shop23n05y18abcd/img/0eb08f3800884600bde0cd670aecc869@.png@.webp"
94
- />
75
+ <image class="icon icon_yh" style="width: 28rpx"
76
+ src="https://shop-cdn.cbyzx.com/shop23n05y18abcd/img/0eb08f3800884600bde0cd670aecc869@.png@.webp" />
95
77
 
96
78
  <text>每人限{{ entity.purchaseLimitNum }}份</text>
97
79
  </view>
@@ -99,17 +81,10 @@
99
81
  </view>
100
82
  </view>
101
83
  <view class="goods-card_info_price">
102
- <text
103
- class="goods-card_info_price_preferential-price"
104
- :style="{ fontSize: textFontSize.preferentialPrice }"
105
- >
84
+ <text class="goods-card_info_price_preferential-price" :style="{ fontSize: textFontSize.preferentialPrice }">
106
85
  ¥{{ price }}
107
86
  </text>
108
- <text
109
- class="goods-card_info_price_price"
110
- v-if="entity.hasDiscount"
111
- :style="{ fontSize: textFontSize.price }"
112
- >
87
+ <text class="goods-card_info_price_price" v-if="entity.hasDiscount" :style="{ fontSize: textFontSize.price }">
113
88
  ¥{{ entity.marketPriceShow }}
114
89
  </text>
115
90
  </view>
@@ -117,14 +92,10 @@
117
92
  <text class="goods-card_info_status_text">{{ errStatusText }}</text>
118
93
  </view>
119
94
  <view class="goods-card_info_add" v-else>
120
- <view
121
- @tap.stop="addClick"
122
- v-if="!goodsCount"
123
- class="goods-card_info_add_icon"
124
- >
95
+ <view @tap.stop="addClick" v-if="!goodsCount" class="goods-card_info_add_icon">
125
96
  <ui-icon name="add" :size="19" :color="addBtnBgColor"></ui-icon>
126
97
  </view>
127
- <view v-else class="number-box" @tap.stop="() => {}">
98
+ <view v-else class="number-box" @tap.stop="() => { }">
128
99
  <!-- <uni-number-box
129
100
  :value="goodsCount"
130
101
  :min="0"
@@ -137,37 +108,15 @@
137
108
  @change="change"
138
109
  ></uni-number-box> -->
139
110
 
140
- <ui-numberbox
141
- :value="goodsCount"
142
- :min="0"
143
- :max="
144
- entity.unlimitedInventory
145
- ? 99999
146
- : entity.inventoryCapacity || 100
147
- "
148
- @change="change"
149
- @triggerMax="triggerMax"
150
- :border="true"
151
- :width="65"
152
- :iconSize="19"
153
- :size="22"
154
- :step="1"
155
- :backgroundColor="textFontSize.numberBoxBg"
156
- iconColor="#C7C7CC"
157
- ></ui-numberbox>
111
+ <ui-numberbox :value="goodsCount" :min="0" :max="entity.unlimitedInventory
112
+ ? 99999
113
+ : entity.inventoryCapacity || 100
114
+ " @change="change" @triggerMax="triggerMax" :border="true" :width="65" :iconSize="19" :size="22" :step="1"
115
+ :backgroundColor="textFontSize.numberBoxBg" iconColor="#C7C7CC"></ui-numberbox>
158
116
  </view>
159
- <ui-cubic-bezier
160
- v-if="bezier"
161
- right="0"
162
- bottom="0"
163
- :backgroundColor="addBtnBgColor"
164
- :windowWidth="state.windowWidth"
165
- :windowHeight="state.windowHeight"
166
- :position="{ right: 110, bottom: 15 }"
167
- direction="down"
168
- :index="0"
169
- @click="addClick"
170
- ></ui-cubic-bezier>
117
+ <ui-cubic-bezier v-if="bezier" right="0" bottom="0" :backgroundColor="addBtnBgColor"
118
+ :windowWidth="state.windowWidth" :windowHeight="state.windowHeight" :position="{ right: 110, bottom: 15 }"
119
+ direction="down" :index="0" @click="addClick"></ui-cubic-bezier>
171
120
  </view>
172
121
  </view>
173
122
  </view>
@@ -176,6 +125,7 @@
176
125
  <script setup lang="ts">
177
126
  import { onMounted, reactive, computed } from 'vue';
178
127
  import type { GoodsDataType, changeValueType } from '../interface/types';
128
+ import imageJSsdk from './new-sdk';
179
129
 
180
130
  interface IProps {
181
131
  entity: GoodsDataType;
@@ -186,19 +136,19 @@ interface IProps {
186
136
  goodMin?: number;
187
137
  imagePlaceholder?: string;
188
138
  imageMode?:
189
- | 'scaleToFill'
190
- | 'aspectFit'
191
- | 'aspectFill'
192
- | 'widthFix'
193
- | 'top'
194
- | 'bottom'
195
- | 'center'
196
- | 'left'
197
- | 'right'
198
- | 'top left'
199
- | 'top right'
200
- | 'bottom left'
201
- | 'bottom right';
139
+ | 'scaleToFill'
140
+ | 'aspectFit'
141
+ | 'aspectFill'
142
+ | 'widthFix'
143
+ | 'top'
144
+ | 'bottom'
145
+ | 'center'
146
+ | 'left'
147
+ | 'right'
148
+ | 'top left'
149
+ | 'top right'
150
+ | 'bottom left'
151
+ | 'bottom right';
202
152
  textFontSize?: {
203
153
  title: string;
204
154
  tag: string;
@@ -210,6 +160,7 @@ interface IProps {
210
160
  addBtnBgColor: string;
211
161
  }
212
162
 
163
+
213
164
  const props = withDefaults(defineProps<IProps>(), {
214
165
  imgWidth: '225rpx',
215
166
  imgHeight: '225rpx',
@@ -260,7 +211,7 @@ const goodsImage = computed(() => {
260
211
  if (props?.entity?.image?.includes('static.tanshuapi.com')) {
261
212
  return urlConversion(props?.entity?.image || '');
262
213
  }
263
- return props?.entity?.image || '';
214
+ return imageJSsdk.getWebpUrl(props?.entity?.image || '', 'previewImage');
264
215
  });
265
216
 
266
217
  function urlConversion(path) {
@@ -0,0 +1,126 @@
1
+ class ImageJSsdk {
2
+ // 支持的图片扩展名
3
+ imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp'];
4
+
5
+ // 图片尺寸映射表
6
+ imageSizeMap = {
7
+ listImage: '@h240',
8
+ previewImage: '@h480',
9
+ detailsImage: ''
10
+ };
11
+
12
+ /**
13
+ * 手动解析URL为协议和路径(适配微信小程序)
14
+ * @param url 完整URL字符串
15
+ * @returns 包含协议和路径的对象,无效URL返回null
16
+ */
17
+ parseUrl(url) {
18
+ if (!url) return null;
19
+
20
+ try {
21
+ // 匹配协议部分 (http:, https: 等)
22
+ const protocolMatch = url.match(/^([a-zA-Z]+:)/);
23
+ if (!protocolMatch) {
24
+ console.error('URL缺少协议部分');
25
+ return null;
26
+ }
27
+ const protocol = protocolMatch[1];
28
+
29
+ // 移除协议部分后处理路径
30
+ const pathStart =
31
+ url.indexOf('//') === -1 ? protocol.length : url.indexOf('//') + 2;
32
+ const pathname = url.substring(pathStart);
33
+
34
+ return { protocol, pathname };
35
+ } catch (err) {
36
+ console.error('URL解析错误:', err);
37
+ return null;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * 判断URL是否为图片
43
+ * @param urlObj 解析后的URL对象
44
+ * @returns 是否为图片的布尔值
45
+ */
46
+ isImageUrl(urlObj) {
47
+ if (!urlObj) return false;
48
+
49
+ try {
50
+ const lastDotIndex = urlObj.pathname.lastIndexOf('.');
51
+ if (lastDotIndex === -1) return false;
52
+
53
+ // 提取并转换为小写扩展名
54
+ const extension = urlObj.pathname.slice(lastDotIndex + 1).toLowerCase();
55
+ return this.imageExtensions.includes(extension);
56
+ } catch (err) {
57
+ console.error('判断图片类型错误:', err);
58
+ return false;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * 获取URL信息
64
+ * @param urlObj 解析后的URL对象
65
+ * @returns 包含路径、扩展名和是否为新URL格式的对象
66
+ */
67
+ getUrlInfo(urlObj) {
68
+ // 处理无效URL情况
69
+ if (!urlObj || !this.isImageUrl(urlObj)) {
70
+ return { pathname: '', ext: '', isNewUrl: false };
71
+ }
72
+
73
+ const lastDotIndex = urlObj.pathname.lastIndexOf('.');
74
+ const ext =
75
+ lastDotIndex !== -1
76
+ ? urlObj.pathname.slice(lastDotIndex + 1).toLowerCase()
77
+ : '';
78
+ const atSymbolCount = (urlObj.pathname.match(/@/g) || []).length;
79
+
80
+ return {
81
+ pathname: urlObj.pathname,
82
+ ext,
83
+ isNewUrl: urlObj.pathname.includes('@.') && atSymbolCount === 1
84
+ };
85
+ }
86
+
87
+ /**
88
+ * 获取WebP格式的图片URL
89
+ * @param url 原始图片URL
90
+ * @param sizeType 尺寸类型,对应imageSizeMap
91
+ * @returns 处理后的WebP图片URL
92
+ */
93
+ getWebpUrl(url, sizeType = 'detailsImage') {
94
+ if (!url) return '';
95
+
96
+ const urlObj = this.parseUrl(url);
97
+ if (!urlObj) return url;
98
+
99
+ const urlInfo = this.getUrlInfo(urlObj);
100
+ const sizeStr = this.imageSizeMap[sizeType] || '';
101
+
102
+ if (!urlInfo.isNewUrl) {
103
+ return url;
104
+ }
105
+ // 处理已为webp格式的URL
106
+ if (urlInfo.ext === 'webp') {
107
+ // 避免重复添加尺寸参数
108
+ return url.includes(sizeStr) ? url : `${url}${sizeStr}.webp`;
109
+ }
110
+
111
+ if (!this.imageExtensions.includes(urlInfo.ext)) {
112
+ return url;
113
+ }
114
+
115
+ // 处理其他格式转换为webp
116
+ const hasSize = sizeStr && !url.includes(sizeStr);
117
+ return hasSize
118
+ ? `${url}${sizeStr}.webp`
119
+ : `${url}${sizeStr ? '' : '@'}.webp`;
120
+ }
121
+
122
+ }
123
+
124
+ // 单例导出
125
+ const imageJSsdk = new ImageJSsdk();
126
+ export default imageJSsdk;
@@ -34,6 +34,7 @@
34
34
  </view>
35
35
  </template>
36
36
  <script setup lang="ts">
37
+ import { computed } from 'vue';
37
38
  import type { priceDataType, cartItemListType } from '../interface/types';
38
39
  interface IProps {
39
40
  list: cartItemListType[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cb-biz-ui",
3
- "version": "1.7.5",
3
+ "version": "1.7.7",
4
4
  "description": "cb-biz-ui",
5
5
  "main": "index.js",
6
6
  "keywords": [