RecommendList.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. <template>
  2. <div class="recommend-fragment">
  3. <ul class="recommend-list">
  4. <li v-for="commodity in commodities" class="big">
  5. <a :href="commodity.batchCode ? '/store/productDetail/'+ commodity.batchCode : '#'" class="href">
  6. <div class="img">
  7. <img :src="commodity.comImg.startsWith('static')?'/'+commodity.comImg:commodity.comImg"/>
  8. </div>
  9. <div class="content">
  10. <p>{{commodity.comCode | comCodeFilter}}</p>
  11. <!-- <p class="color666" v-text="commodity.brandNameCn">PANFAEFQ</p>-->
  12. <p class="price" v-if="commodity.minPriceRMB">¥ {{commodity.minPriceRMB | currency}}</p>
  13. <!-- <p class="price" v-if="!commodity.minPriceRMB">$ {{commodity.minPriceUSD || 0}}</p>-->
  14. </div>
  15. </a>
  16. <div class="enter-store">
  17. <a @click="buyNow(false, commodity)">加入购物车</a>
  18. <a @click="buyNow(true, commodity)">立即购买</a>
  19. </div>
  20. </li>
  21. <li v-if="!commodities || commodities.length === 0" class="empty-show">
  22. <div class="empty">
  23. <div class="empty-img">
  24. <img src="/images/brandList/empty-cart.jpg">
  25. </div>
  26. <div class="empty-info">
  27. <p class="grey f16"> 暂无展示产品</p>
  28. <i class="iconfont" v-if="emptyShow === false">&#xe610;</i>&nbsp;<a v-if="emptyShow === false" href="/">返回首页</a>
  29. <img v-if="emptyShow === true" src="/images/brandList/upload.png">&nbsp;<a v-if="emptyShow === true" href="/vendor#/store/maintain" target="_blank">马上去上传</a>
  30. </div>
  31. </div>
  32. </li>
  33. </ul>
  34. </div>
  35. </template>
  36. <script>
  37. import Buy from '~components/common/buyOrCar/buyComponent.vue'
  38. import NuxtLink from '../../../.nuxt/components/nuxt-link'
  39. export default {
  40. name: 'recommend-product',
  41. components: {
  42. NuxtLink,
  43. Buy
  44. },
  45. computed: {
  46. commodities () {
  47. return this.$store.state.shop.recommend.products.data
  48. },
  49. storeInfo () {
  50. return this.$store.state.shop.storeInfo.store.data
  51. },
  52. isConsignment () {
  53. return this.storeInfo.type === 'CONSIGNMENT'
  54. },
  55. user() {
  56. return this.$store.state.option.user
  57. },
  58. storeStatus () {
  59. return this.$store.state.option.storeStatus.data
  60. },
  61. emptyShow () {
  62. let loggedStatus = false
  63. if (this.user.logged && this.user.data.enterprise.uu) {
  64. if (this.storeStatus.uuid === this.storeInfo.uuid) {
  65. loggedStatus = true
  66. } else {
  67. loggedStatus = false
  68. }
  69. } else {
  70. loggedStatus = false
  71. }
  72. return loggedStatus
  73. }
  74. },
  75. filters: {
  76. comCodeFilter: function (title) {
  77. if (title === '') {
  78. return title
  79. }
  80. let len = 0
  81. let index = 0
  82. for (let i = 0; i < title.length; i++) {
  83. if (index === 0 && title.charAt(i).charCodeAt(0) > 255) {
  84. len = len + 2
  85. } else {
  86. len++
  87. }
  88. if (len > 18) {
  89. index = i
  90. break
  91. }
  92. }
  93. if (index > 0) {
  94. return title.substring(0, index) + '...'
  95. } else {
  96. return title
  97. }
  98. },
  99. currency: function (num) {
  100. if (typeof num === 'number') {
  101. if (num <= 0.000001) {
  102. num = 0.000001
  103. } else {
  104. if (num.toString().indexOf('.') === -1) {
  105. num += '.00'
  106. } else {
  107. let inputStr = num.toString()
  108. let arr = inputStr.split('.')
  109. let floatNum = arr[1]
  110. if (floatNum.length > 6) {
  111. num = inputStr.substring(0, arr[0].length + 7)
  112. if (Number(floatNum.charAt(6)) > 4) {
  113. num = (Number(num) * 1000000 + 1) / 1000000
  114. }
  115. } else if (floatNum.length === 1) {
  116. num = num + '0'
  117. }
  118. }
  119. }
  120. }
  121. return num
  122. }
  123. },
  124. methods: {
  125. buyNow: function (isBuy, item) {
  126. if (!this.$store.state.option.user.logged) {
  127. this.$http.get('/login/page', {params: {returnUrl: window.location.href}}).then(response => {
  128. if (response.data) {
  129. window.location.href = response.data.content + '&baseUrl=' + encodeURIComponent(window.location.protocol + '//' + window.location.host + response.data.baseUrl)
  130. }
  131. })
  132. } else {
  133. if (item) {
  134. if (isBuy) {
  135. this.$http.post('/trade/order/buyNow', [{
  136. uuid: item.comUuid,
  137. batchCode: item.batchCode,
  138. number: item.minBuyQty,
  139. storeid: item.storeId,
  140. storeUuid: item.storeUuid,
  141. currencyName: item.currency,
  142. minPackQty: item.minPackQty ? item.minPackQty : item.minBuyQty
  143. }])
  144. .then(response => {
  145. if (response.data.success) {
  146. if (response.data.message) {
  147. this.$message({
  148. message: response.data.message,
  149. type: 'success'
  150. })
  151. window.setTimeout(function () {
  152. window.location.href = '/user#/order/pay/' + this.baseUtils.enidfilter(response.data.data.orderid)
  153. }, 1000)
  154. } else {
  155. window.location.href = '/user#/order/pay/' + this.baseUtils.enidfilter(response.data.data.orderid)
  156. }
  157. } else {
  158. if (response.data.data && response.data.data.unvailable === 1) {
  159. this.$message.error('产品信息已失效,请刷新界面')
  160. } else {
  161. this.$message.error(response.data.message)
  162. }
  163. }
  164. }, err => {
  165. console.log(err)
  166. if (item.minBuyQty > item.reserve) {
  167. this.$message.error('商品' + item.code + '的库存已经不满足最小起订量')
  168. }
  169. })
  170. } else {
  171. // this.$store.dispatch('user/addCar', {uuid: item.uuid, batchCode: item.batchCode, number: item.minBuyQty})
  172. this.$http.post('/trade/cart/add', {
  173. uuid: item.comUuid,
  174. batchCode: item.batchCode,
  175. number: item.minBuyQty,
  176. storeid: item.storeId,
  177. storeUuid: item.storeUuid,
  178. currencyName: item.currency,
  179. minPackQty: item.minPackQty ? item.minPackQty : item.minBuyQty
  180. })
  181. .then(response => {
  182. if (response.data.success) {
  183. if (response.data.message) {
  184. this.$message({
  185. message: '添加购物车成功,但商品信息有更新',
  186. type: 'success'
  187. })
  188. } else {
  189. this.$message({
  190. message: '添加购物车成功',
  191. type: 'success'
  192. })
  193. }
  194. } else {
  195. if (response.data.code === 2) {
  196. this.$message.error(response.data.message + ',请刷新页面')
  197. } else {
  198. this.$message.error(response.data.message)
  199. }
  200. }
  201. })
  202. }
  203. }
  204. }
  205. },
  206. enidfilter: function (str) {
  207. if (str) {
  208. let encryptStr = '' // 最终返回的加密后的字符串
  209. // 产生三位随机数
  210. let num = ''
  211. for (let i = 0; i < 3; i++) {
  212. num += Math.floor(Math.random() * 10)
  213. }
  214. encryptStr += num // 产生3位随机数
  215. // 16位加密
  216. let tempspit = ''
  217. let strspit = str.toString().toLowerCase()
  218. if (strspit.match(/^[-+]?\d*$/) === null) { // 非整数字符,对每一个字符都转换成16进制,然后拼接
  219. /**
  220. * Unicode汉字、英文字母、数字的unicode范围
  221. *汉字:[0x4e00,0x9fa5](或十进制[19968,40869])
  222. *数字:[0x30,0x39](或十进制[48, 57])
  223. *小写字母:[0x61,0x7a](或十进制[97, 122])
  224. *大写字母:[0x41,0x5a](或十进制[65, 90]
  225. * 'a'的Unicode编码:'&#97;',charCodeAt()的值是97
  226. * '码'的Unicode编码:'\u7801', new String('码').charCodeAt()的值是30721,30721的16进制表示是7801
  227. */
  228. let s = strspit.split('')
  229. for (let i = 0; i < s.length; i++) {
  230. s[i] = s[i].charCodeAt() // 先转换成Unicode编码
  231. s[i] = s[i].toString(16)
  232. // 因为在服务器是每两位当做一个字符进行解析的,所以这里每个字符的Unicode编码范围必须在0——255之间。数字和大小写满足该要求,特殊字符则不一定,如果后续有特殊字符的要求,需要重写编码器和解码器
  233. if (s[i].length === 1) {
  234. s[i] = '0' + s[i]
  235. }
  236. tempspit = tempspit + s[i]
  237. }
  238. tempspit = tempspit + '{' + 1 // 1代表字符
  239. } else { // 数字直接转换成16进制
  240. strspit = parseInt(strspit)
  241. .toString(16)
  242. tempspit = strspit + '{' + 0 // 0代表纯数字
  243. }
  244. let temp = tempspit.split('{') // 对要加密的字符转换成16进制
  245. let numLength = temp[0].length // 转换后的字符长度
  246. numLength = numLength.toString(16) // 字符长度换算成16进制
  247. if (numLength.length === 1) { // 如果是1,补一个0
  248. numLength = '0' + numLength
  249. } else if (numLength.length > 3) { // 转换后的16进制字符长度如果大于2位数,则返回,不支持
  250. return ''
  251. }
  252. encryptStr += numLength
  253. if (temp[1] === '0') {
  254. encryptStr += 0
  255. } else if (temp[1] === '1') {
  256. encryptStr += 1
  257. }
  258. encryptStr += temp[0]
  259. if (encryptStr.length < 20) { // 如果小于20位,补上随机数
  260. // 产生三位随机数
  261. let numtwo = ''
  262. for (let i = 0; i < 20 - encryptStr.length; i++) {
  263. numtwo += Math.floor(Math.random() * 10)
  264. }
  265. let ran = numtwo // 产生3位随机数
  266. encryptStr += ran
  267. }
  268. return encryptStr
  269. }
  270. }
  271. }
  272. }
  273. </script>
  274. <style lang="scss" scoped>
  275. .recommend-fragment {
  276. width: 100%;
  277. }
  278. .recommend-fragment ul{
  279. width: 100%;
  280. height: 356px;
  281. background: #fff;
  282. /* display: inline-block;*/
  283. -webkit-padding-start: 0;
  284. border-radius: 5px;
  285. padding-left: 2px;
  286. }
  287. .recommend-fragment ul li
  288. .img{
  289. height: 90px;
  290. text-align: center;
  291. line-height: 90px;
  292. img{
  293. max-width: 80px;
  294. max-height: 80px;
  295. }
  296. }
  297. .recommend-fragment ul li .content{
  298. width: 100%;
  299. margin: 0 auto;
  300. font-size: 12px;
  301. p{
  302. width: 100%;
  303. text-align: center;
  304. display: inline-block;
  305. line-height: 22px;
  306. overflow: hidden;
  307. text-overflow: ellipsis;
  308. white-space: nowrap;
  309. margin-bottom: 0;
  310. padding-left: 10px;
  311. color: #666;
  312. &.price{
  313. color: #ff002e;
  314. }
  315. }
  316. }
  317. .recommend-fragment ul li .enter-store {
  318. position: absolute;
  319. top: 178px;
  320. width: 100%;
  321. height: 30px;
  322. line-height: 30px;
  323. text-align: left;
  324. }
  325. .recommend-fragment ul li.big .enter-store a {
  326. width: 74px;
  327. height: 24px;
  328. display: inline-block;
  329. line-height: 24px;
  330. text-align: center;
  331. font-size: 13px;
  332. margin-left: 14px;
  333. border-radius: 3px;
  334. &:first-child {
  335. background-color: #ffa422;
  336. border: 1px solid #ffa422;
  337. color: #fff;
  338. }
  339. &:last-child {
  340. background-color: #be0606;
  341. border: 1px solid #be0606;
  342. color: #fff;
  343. }
  344. /*&:visited{
  345. .enter-store {
  346. top: 140px;
  347. left: 0px;
  348. }
  349. }*/
  350. }
  351. .recommend-fragment ul li.big {
  352. float: left;
  353. width: 190px;
  354. height: 174px;
  355. position: relative;
  356. overflow: hidden;
  357. margin: 2px 3px 0px 0px;
  358. &:nth-child(5n){
  359. margin: 2px 0px 0px 0px;
  360. }
  361. &:hover{
  362. box-shadow: 2px 0px 1px #d9d9d9, -2px 0px 1px #d9d9d9, 0px 2px 1px #d9d9d9, 0px -2px 1px #d9d9d9;
  363. .enter-store {
  364. top: 132px;
  365. left: 0px;
  366. transition: all .3s linear;
  367. }
  368. .img, .content{
  369. transform:translate(0px,-10px);
  370. -ms-transform:translate(0px,-10px); /* IE 9 */
  371. -webkit-transform:translate(0px,-10px); /* Safari and Chrome */
  372. }
  373. }
  374. }
  375. /*.recommend-fragment ul li.small .enter-store a {
  376. width: 74px;
  377. height: 24px;
  378. display: inline-block;
  379. line-height: 22px;
  380. text-align: center;
  381. font-size: 12px;
  382. margin-left: 11px;
  383. border-radius: 3px;
  384. &:first-child {
  385. background-color: #fff;
  386. border: solid 1px #3b7cf4;
  387. color: #3c7df5;
  388. }
  389. &:last-child {
  390. background-color: #ffa422;
  391. border: 1px solid #ffa422;
  392. color: #fff;
  393. }
  394. }
  395. .recommend-fragment ul li.small {
  396. float: left;
  397. width: 180px;
  398. height: 174px;
  399. position: relative;
  400. overflow: hidden;
  401. margin: 2px 8px 0px 0px;
  402. &:nth-child(5n){
  403. margin: 2px 0px 0px 0px;
  404. }
  405. &:hover, &:focus, &:active &:visited{
  406. box-shadow: 2px 0px 1px #d9d9d9, -2px 0px 1px #d9d9d9, 0px 2px 1px #d9d9d9, 0px -2px 1px #d9d9d9;
  407. .enter-store {
  408. top: 140px;
  409. left: 0px;
  410. transition: all .5s;
  411. }
  412. .img, .content{
  413. transform:translate(0px,-10px);
  414. -ms-transform:translate(0px,-10px); !* IE 9 *!
  415. -webkit-transform:translate(0px,-10px); !* Safari and Chrome *!
  416. }
  417. }
  418. }*/
  419. .recommend-fragment ul li.empty-show {
  420. width: 100%;
  421. height: 356px;
  422. padding-top: 150px;
  423. &:hover{
  424. box-shadow: 0px 0px 0px transparent;
  425. }
  426. .empty{
  427. margin: 0 auto;
  428. width: 181px;
  429. .empty-img{
  430. float: left;
  431. }
  432. .empty-info{
  433. float: left;
  434. margin: 5px 0px 0px 20px;
  435. .grey{
  436. color: #999;
  437. font-size: 14px;
  438. }
  439. i{
  440. color: #5078cb;
  441. }
  442. a{
  443. font-size: 14px;
  444. color: #5078cb;
  445. }
  446. }
  447. }
  448. }
  449. </style>