goods-category.vue 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064
  1. <template>
  2. <view>
  3. <view :class="(is_single_page == 1 ? 'margin-top-xxxl single-page-top' : '')">
  4. <!-- 搜索框 -->
  5. <block v-if="is_single_page == 0">
  6. <view class="nav-search padding-horizontal-main bg-white" :style="'padding-top:'+(status_bar_height+8)+'px;'">
  7. <component-search @onsearch="search_button_event" :propIsOnEvent="true" :propIsRequired="false" propPlaceholder="输入商品名称搜索"></component-search>
  8. </view>
  9. </block>
  10. <!-- 分类内容 -->
  11. <view v-if="category_list.length > 0" :class="'category-content pr bs-bb '+(category_show_level == 0 ? 'goods-model' : '')" :style="'height:calc(100vh - '+(status_bar_height+48)+'px);'">
  12. <block v-if="category_show_level == 1">
  13. <!-- 一级模式 -->
  14. <view class="model-one padding-sm oh">
  15. <block v-for="(item, index) in category_list" :key="index">
  16. <view class="content-item padding-sm tc cp" :data-value="item.id" @tap="category_event">
  17. <view class="content auto bg-white wh-auto border-radius-main">
  18. <image v-if="(item.icon || null) != null" :src="item.icon" mode="aspectFit" class="icon radius"></image>
  19. <view class="text single-text">{{item.name}}</view>
  20. </view>
  21. </view>
  22. </block>
  23. </view>
  24. </block>
  25. <block v-else>
  26. <!-- 商品列表模式 -->
  27. <block v-if="category_show_level == 0">
  28. <!-- 一级导航 -->
  29. <view class="top-nav bg-white wh-auto pa br-b scroll-view-horizontal">
  30. <scroll-view :scroll-x="true" :scroll-with-animation="true" :scroll-into-view="'one-nav-item-'+nav_active_index" class="ht-auto">
  31. <block v-for="(item, index) in category_list" :key="index">
  32. <view :class="'text-size-sm item tc cr-base cp dis-inline-block ' + (nav_active_index == index ? 'cr-main border-color-main fw-b' : '')" :id="'one-nav-item-'+index" :data-index="index" :data-itemtwoindex="-1" :data-itemthreeindex="-1" @tap="nav_event">
  33. <view :class="'icon-content circle br auto ' + (nav_active_index == index ? 'border-color-main' : '')">
  34. <image :src="((item[category_goods_model_icon_field] || null) == null) ? common_static_url+'images.png' : item[category_goods_model_icon_field]" mode="aspectFit" class="icon dis-block auto wh-auto ht-auto circle"></image>
  35. </view>
  36. <view class="margin-top-xs">{{item.name}}</view>
  37. </view>
  38. </block>
  39. </scroll-view>
  40. </view>
  41. <!-- 二级导航 -->
  42. <view class="left-nav bg-white ht-auto">
  43. <scroll-view :scroll-y="true" class="ht-auto">
  44. <view :class="((common_site_type != 1) ? 'left-content-actual' : '')">
  45. <view :class="'text-size-sm item tc cr-base cp oh ' + (nav_active_item_two_index == -1 ? 'nav-active cr-main border-color-main' : '')" :data-index="nav_active_index" :data-itemtwoindex="-1" :data-itemthreeindex="-1" @tap="nav_event">
  46. <text>全部</text>
  47. </view>
  48. <block v-if="(data_content || null) != null && (data_content.items || null) != null && data_content.items.length > 0">
  49. <block v-for="(item, index) in data_content.items" :key="index">
  50. <view :class="'text-size-sm item tc cr-base cp oh ' + (nav_active_item_two_index == index ? 'nav-active cr-main border-color-main' : '')" :data-index="nav_active_index" :data-itemtwoindex="index" :data-itemthreeindex="-1" @tap="nav_event">
  51. <text>{{item.name}}</text>
  52. </view>
  53. </block>
  54. </block>
  55. </view>
  56. </scroll-view>
  57. </view>
  58. <!-- 商品列表 -->
  59. <view class="goods-right-content pa bs-bb padding-top-main padding-horizontal-main">
  60. <scroll-view :scroll-y="true" class="ht-auto goods-list" :scroll-top="scroll_top" @scroll="scroll_event" @scrolltolower="scroll_lower" lower-threshold="60">
  61. <view :class="((common_site_type != 1) ? 'right-content-actual' : '')+' pr'">
  62. <!-- 三级导航 -->
  63. <view v-if="(data_three_content || null) != null && (data_three_content.items || null) != null && data_three_content.items.length > 0" class="word-list scroll-view-horizontal">
  64. <scroll-view :scroll-x="true" :scroll-with-animation="true" :scroll-into-view="'three-nav-item-'+nav_active_item_three_index">
  65. <view :class="'word-icon dis-inline-block text-size-sm round padding-top-xs padding-bottom-xs padding-left padding-right '+((nav_active_item_three_index == -1) ? 'bg-main-light br-main-light cr-main' : 'br-gray cr-gray')" :data-index="nav_active_index" :data-itemtwoindex="nav_active_item_two_index" :data-itemthreeindex="-1" @tap="nav_event">全部</view>
  66. <block v-for="(item, index) in data_three_content.items" :key="index">
  67. <view :class="'word-icon dis-inline-block text-size-sm round padding-top-xs padding-bottom-xs padding-left padding-right '+((nav_active_item_three_index == index) ? 'bg-main-light br-main-light cr-main' : 'br-gray cr-gray')" :id="'three-nav-item-'+index" :data-index="nav_active_index" :data-itemtwoindex="nav_active_item_two_index" :data-itemthreeindex="index" @tap="nav_event">{{item.name}}</view>
  68. </block>
  69. </scroll-view>
  70. </view>
  71. <!-- 右侧商品列表 -->
  72. <view v-if="(data_list || null) != null && data_list.length > 0" class="oh">
  73. <view v-for="(item, index) in data_list" :key="index" class="item bg-white border-radius-main oh pr spacing-mb">
  74. <view :data-value="item.goods_url+'&is_opt_back=1'" @tap="url_event">
  75. <image :src="item.images" mode="widthFix" class="goods-img radius fl"></image>
  76. <view class="goods-base padding-top-sm padding-right-sm fr">
  77. <view class="goods-base-content">
  78. <view class="goods-title text-size-sm multi-text">{{item.title}}</view>
  79. <view v-if="(item.simple_desc || null) != null" class="simple-desc cr-red text-size-xs margin-top-sm single-text">{{item.simple_desc}}</view>
  80. </view>
  81. <view class="margin-top-sm oh">
  82. <view class="sales-price text-size-sm single-text pa">{{currency_symbol}}{{item.min_price}}</view>
  83. <view v-if="common_site_type != 1" class="buy-opt tc pa">
  84. <block v-if="(item.is_error || 0) == 0">
  85. <view v-if="(item.buy_number || 0) > 0" class="dis-inline-block va-m cp" :data-index="index" data-type="0" @tap.stop="buy_number_event">
  86. <uni-icons type="minus" size="22" color="#f00"></uni-icons>
  87. </view>
  88. <view v-if="(item.buy_number || 0) > 0" class="buy-number dis-inline-block cr-base text-size-sm padding-left-xs padding-right-xs va-m">{{item.buy_number}}</view>
  89. <view class="dis-inline-block va-m cp" :data-index="index" data-type="1" @tap.stop="buy_number_event">
  90. <uni-icons type="plus" size="22" color="#1AAD19"></uni-icons>
  91. </view>
  92. </block>
  93. <block v-else>
  94. <text class="cr-grey text-size-xs">{{item.error_msg}}</text>
  95. </block>
  96. </view>
  97. </view>
  98. </view>
  99. </view>
  100. </view>
  101. </view>
  102. <block v-else>
  103. <component-no-data :propStatus="data_list_loding_status" :propMsg="data_list_loding_msg"></component-no-data>
  104. </block>
  105. </view>
  106. </scroll-view>
  107. </view>
  108. </block>
  109. <block v-else>
  110. <!-- 一级导航 -->
  111. <view class="left-nav bg-white ht-auto">
  112. <scroll-view :scroll-y="true" class="ht-auto">
  113. <block v-for="(item, index) in category_list" :key="index">
  114. <view :class="'text-size-sm item tc cr-base cp oh ' + (nav_active_index == index ? 'nav-active cr-main border-color-main' : '')" :data-index="index" :data-itemindex="-1" @tap="nav_event">
  115. <text>{{item.name}}</text>
  116. </view>
  117. </block>
  118. </scroll-view>
  119. </view>
  120. <view class="right-container pa">
  121. <scroll-view :scroll-y="true" class="ht-auto">
  122. <!-- 一级内容基础容 -->
  123. <view v-if="(data_content || null) != null" class="padding-top-main padding-horizontal-main oh">
  124. <!-- 一级基础信息 -->
  125. <view v-if="(data_content.vice_name || null) != null || (data_content.describe || null) != null" class="one-content bg-white padding-main border-radius-main cp spacing-mb" :data-value="data_content.id" @tap="category_event">
  126. <view v-if="(data_content.vice_name || null) != null" class="text-size fw-b" :style="'color:' + data_content.bg_color + ';'">{{data_content.vice_name}}</view>
  127. <view v-if="(data_content.describe || null) != null" class="cr-grey margin-top-sm">{{data_content.describe}}</view>
  128. </view>
  129. <!-- 一二级数据渲染 -->
  130. <block v-if="(data_content.items || null) != null && data_content.items.length > 0">
  131. <!-- 二级模式 -->
  132. <block v-if="category_show_level == 2">
  133. <view class="two-content bg-white oh padding-main border-radius-main spacing-mb">
  134. <block v-for="(v, index) in data_content.items" :key="index">
  135. <view class="content-item padding-sm tc cp" :data-value="v.id" @tap="category_event">
  136. <view class="content wh-auto">
  137. <image v-if="(v.icon || null) != null" :src="v.icon" mode="aspectFit" class="icon radius"></image>
  138. <view class="text single-text">{{v.name}}</view>
  139. </view>
  140. </view>
  141. </block>
  142. </view>
  143. </block>
  144. <!-- 三级模式 -->
  145. <block v-if="category_show_level == 3">
  146. <block v-for="(v, index) in data_content.items" :key="index">
  147. <view class="spacing-nav-title">
  148. <text class="text-wrapper text-size-md">{{v.name}}</text>
  149. <text v-if="(v.describe || null) != null" class="vice-name margin-left-lg cr-gray">{{v.describe}}</text>
  150. <view :data-value="v.id" @tap="category_event" class="arrow-right padding-right-xxxl cr-gray fr cp">更多</view>
  151. </view>
  152. <view v-if="(v.items || null) != null && v.items.length > 0" class="bg-white oh padding-main border-radius-main spacing-mb">
  153. <block v-for="(vs, index2) in v.items" :key="index2">
  154. <view class="content-item padding-sm tc cp" :data-value="vs.id" @tap="category_event">
  155. <view class="content wh-auto">
  156. <image v-if="(vs.icon || null) != null" :src="vs.icon" mode="aspectFit" class="icon radius"></image>
  157. <view class="text single-text">{{vs.name}}</view>
  158. </view>
  159. </view>
  160. </block>
  161. </view>
  162. </block>
  163. </block>
  164. </block>
  165. <block v-else>
  166. <!-- 提示信息 -->
  167. <component-no-data propStatus="0" propMsg="没有子分类数据"></component-no-data>
  168. </block>
  169. </view>
  170. <view v-else>
  171. <!-- 提示信息 -->
  172. <component-no-data propStatus="0" propMsg="没有子分类数据"></component-no-data>
  173. </view>
  174. </scroll-view>
  175. </view>
  176. </block>
  177. </block>
  178. </view>
  179. <view v-if="category_list.length == 0 && data_list_loding_status != 0">
  180. <!-- 提示信息 -->
  181. <component-no-data :propStatus="data_list_loding_status"></component-no-data>
  182. </view>
  183. <!-- 仅商品模式展示购物车和规格选择 -->
  184. <block v-if="common_site_type != 1 && category_show_level == 0">
  185. <!-- 购物车列表 -->
  186. <block v-if="cart_status">
  187. <view class="cart-mask wh-auto ht-auto pf" @tap="cart_event"></view>
  188. <view class="cart-content bg-white border-radius-main pa oh">
  189. <block v-if="(cart || null) != null && (cart.data || null) != null && cart.data.length > 0">
  190. <view class="oh br-b padding-vertical-main padding-horizontal-main">
  191. <text class="va-m text-size-xs cr-base">已选商品</text>
  192. <view class="fr cp" @tap="cart_all_delete_event">
  193. <view class="dis-inline-block va-m">
  194. <uni-icons type="trash" size="12" color="#f00"></uni-icons>
  195. </view>
  196. <text class="cr-red va-m text-size-xs margin-left-xs">清空</text>
  197. </view>
  198. </view>
  199. <scroll-view :scroll-y="true" class="cart-list goods-list">
  200. <view v-for="(goods, index) in cart.data" :key="index" class="item padding-main oh spacing-mb">
  201. <navigator :url="goods.goods_url" hover-class="none">
  202. <image :src="goods.images" mode="widthFix" class="goods-img radius fl br"></image>
  203. <view class="goods-base fr">
  204. <view class="goods-base-content">
  205. <view class="goods-title text-size-sm single-text">{{goods.title}}</view>
  206. <view v-if="goods.spec != null" class="text-size-xs cr-grey margin-top-sm">
  207. <block v-for="(sv, si) in goods.spec" :key="si">
  208. <text v-if="si > 0" class="padding-left-xs padding-right-xs">;</text>
  209. <text>{{sv.value}}</text>
  210. </block>
  211. </view>
  212. </view>
  213. <view class="margin-top-sm oh">
  214. <view class="sales-price text-size-sm single-text dis-inline-block va-m">{{currency_symbol}}{{goods.price}}</view>
  215. <view class="tc fr">
  216. <block v-if="goods.is_error == 0">
  217. <view v-if="(goods.stock || 0) > 0" class="dis-inline-block va-m cp" :data-index="index" data-type="0" @tap.stop="cart_buy_number_event">
  218. <uni-icons type="minus" size="22" color="#f00"></uni-icons>
  219. </view>
  220. <view v-if="(goods.stock || 0) > 0" class="buy-number dis-inline-block cr-base text-size-sm padding-left-xs padding-right-xs va-m">{{goods.stock}}</view>
  221. <view class="dis-inline-block va-m cp" :data-index="index" data-type="1" @tap.stop="cart_buy_number_event">
  222. <uni-icons type="plus" size="22" color="#1AAD19"></uni-icons>
  223. </view>
  224. </block>
  225. <block v-else>
  226. <text class="cr-red">{{goods.error_msg}}</text>
  227. </block>
  228. </view>
  229. </view>
  230. </view>
  231. </navigator>
  232. </view>
  233. </scroll-view>
  234. </block>
  235. <block v-else>
  236. <component-no-data propStatus="0" propMsg="请先选购商品"></component-no-data>
  237. </block>
  238. </view>
  239. </block>
  240. <!-- 购物车底部导航 -->
  241. <view class="botton-nav round pa bg-main-pair oh">
  242. <view class="cart dis-inline-block va-m margin-left-xxl pr cp" @tap="cart_event">
  243. <uni-icons type="cart" size="32rpx" color="#fff"></uni-icons>
  244. <view v-if="(cart || null) != null && (cart.buy_number || 0) != 0" class="badge-icon pa">
  245. <component-badge :propNumber="cart.buy_number"></component-badge>
  246. </view>
  247. </view>
  248. <view class="cart-total-price single-text dis-inline-block fw-b cr-white va-m margin-left-xl">
  249. <text class="text-size-sm">{{currency_symbol}}</text>
  250. <text class="text-size-lg">{{(cart || null) == null ? 0 : (cart.total_price || 0)}}</text>
  251. </view>
  252. <button type="default" size="mini" hover-class="none" @tap="buy_submit_event" class="text-size-sm pa radius-0 bg-main cr-white">去结算</button>
  253. </view>
  254. </block>
  255. <!-- 购物车抛物线 -->
  256. <component-cart-para-curve ref="cart_para_curve"></component-cart-para-curve>
  257. <!-- 商品购买 -->
  258. <component-goods-buy ref="goods_buy" v-on:CartSuccessEvent="goods_cart_back_event"></component-goods-buy>
  259. <!-- 快捷导航 -->
  260. <component-quick-nav :propIsNav="true" :propIsBar="true"></component-quick-nav>
  261. </view>
  262. </view>
  263. </template>
  264. <script>
  265. const app = getApp();
  266. import base64 from '../../common/js/lib/base64.js';
  267. import componentGoodsBuy from "../../components/goods-buy/goods-buy";
  268. import componentSearch from "../../components/search/search";
  269. import componentQuickNav from "../../components/quick-nav/quick-nav";
  270. import componentNoData from "../../components/no-data/no-data";
  271. import componentPopup from "../../components/popup/popup";
  272. import componentBadge from "../../components/badge/badge";
  273. import componentCartParaCurve from '../../components/cart-para-curve/cart-para-curve';
  274. var common_static_url = app.globalData.get_static_url('common');
  275. // 状态栏高度
  276. var bar_height = parseInt(app.globalData.get_system_info('statusBarHeight', 0));
  277. // #ifdef MP-TOUTIAO
  278. bar_height = 0;
  279. // #endif
  280. export default {
  281. data() {
  282. return {
  283. common_static_url: common_static_url,
  284. status_bar_height: bar_height,
  285. data_bottom_line_status: false,
  286. data_list_loding_status: 1,
  287. data_list_loding_msg: '',
  288. user: null,
  289. tabbar_params: null,
  290. common_site_type: 0,
  291. category_list: [],
  292. data_content: null,
  293. data_three_content: null,
  294. cart: null,
  295. data_list: [],
  296. data_total: 0,
  297. data_page_total: 0,
  298. data_page: 1,
  299. currency_symbol: app.globalData.data.currency_symbol,
  300. is_first: 1,
  301. search_keywords_value: '',
  302. nav_active_index: 0,
  303. nav_active_item_two_index: -1,
  304. nav_active_item_three_index: -1,
  305. scroll_top: 0,
  306. scroll_top_old: 0,
  307. cart_status: false,
  308. goods_choose_data: {},
  309. // 基础配置
  310. category_show_level: 0,
  311. // 自定义分享信息
  312. share_info: {},
  313. // 是否单页预览
  314. is_single_page: app.globalData.is_current_single_page() || 0,
  315. // 商品列表模式一级分类图标类型
  316. category_goods_model_icon_field: app.globalData.data.category_goods_model_icon_type == 0 ? 'big_images' : 'icon',
  317. // 临时操作数据
  318. temp_opt_data: null,
  319. };
  320. },
  321. components: {
  322. componentGoodsBuy,
  323. componentSearch,
  324. componentQuickNav,
  325. componentNoData,
  326. componentPopup,
  327. componentBadge,
  328. componentCartParaCurve
  329. },
  330. props: {},
  331. onShow() {
  332. // 基础参数
  333. this.setData({
  334. user: app.globalData.get_user_cache_info(),
  335. tabbar_params: app.globalData.get_page_tabbar_switch_params()
  336. });
  337. // 数据加载
  338. this.init();
  339. // 初始化配置
  340. this.init_config();
  341. // 清除tab参数
  342. app.globalData.remove_page_tabbar_switch_params();
  343. },
  344. // 下拉刷新
  345. onPullDownRefresh() {
  346. this.init();
  347. },
  348. methods: {
  349. // 初始化配置
  350. init_config(status) {
  351. if ((status || false) == true) {
  352. this.setData({
  353. common_site_type: app.globalData.get_config('config.common_site_type'),
  354. currency_symbol: app.globalData.get_config('currency_symbol'),
  355. category_show_level: app.globalData.get_config('config.category_show_level')
  356. });
  357. } else {
  358. app.globalData.is_config(this, 'init_config');
  359. }
  360. },
  361. // 获取数据
  362. init() {
  363. if(this.is_first == 1) {
  364. this.setData({
  365. data_list_loding_status: 1
  366. });
  367. }
  368. uni.request({
  369. url: app.globalData.get_request_url("category", "goods"),
  370. method: 'POST',
  371. data: {},
  372. dataType: 'json',
  373. success: res => {
  374. uni.stopPullDownRefresh();
  375. if (res.data.code == 0) {
  376. var index = this.nav_active_index;
  377. var temp_category = res.data.data.category || [];
  378. // 是否指定分类
  379. var tabbar_params = this.tabbar_params;
  380. if(temp_category.length > 0 && (tabbar_params || null) != null && (tabbar_params.id || null) != null) {
  381. for(var i in temp_category) {
  382. if(temp_category[i]['id'] == tabbar_params.id) {
  383. index = i;
  384. break;
  385. }
  386. }
  387. }
  388. // 设置分类及右侧数据和及基础数据
  389. var upd_data = {
  390. category_list: temp_category,
  391. data_content: temp_category[index] || null,
  392. nav_active_index: index,
  393. }
  394. // 指定分类则重新读取列表数据
  395. if(tabbar_params != null && this.nav_active_index != index) {
  396. upd_data['is_first'] = 1;
  397. upd_data['data_page'] = 1;
  398. upd_data['data_list'] = [];
  399. upd_data['data_list_loding_status'] = 1;
  400. upd_data['nav_active_item_two_index'] = -1;
  401. upd_data['nav_active_item_three_index'] = -1;
  402. }
  403. // 非商品列表模式
  404. if(this.category_show_level != 0) {
  405. upd_data['data_list_loding_status'] = temp_category.length == 0 ? 0 : 3;
  406. upd_data['data_bottom_line_status'] = true;
  407. }
  408. this.setData(upd_data);
  409. // 商品列表模式
  410. if(this.category_show_level == 0) {
  411. // 商品列表模式获取购物车数据
  412. this.get_cart_data();
  413. // 获取商品列表、仅首次请求商品列表
  414. if(this.is_first == 1) {
  415. this.get_goods_list(1);
  416. }
  417. } else {
  418. // 分类模式下、仅首次请求购物车接口和商品模式下
  419. if(this.is_first == 1 && this.category_show_level == 0) {
  420. this.get_cart_data();
  421. }
  422. }
  423. // 是否首次记录
  424. this.setData({is_first: 0});
  425. } else {
  426. this.setData({
  427. data_list_loding_status: 2,
  428. data_list_loding_msg: res.data.msg
  429. });
  430. }
  431. // 基础自定义分享
  432. this.setData({
  433. share_info: {
  434. path: '/pages/goods-category/goods-category'
  435. }
  436. });
  437. // 分享菜单处理、延时执行,确保基础数据已加载完成
  438. setTimeout(function() {
  439. app.globalData.page_share_handle(this.share_info);
  440. }, 3000);
  441. },
  442. fail: () => {
  443. uni.stopPullDownRefresh();
  444. this.setData({
  445. data_list_loding_status: 2,
  446. data_list_loding_msg: '服务器请求出错'
  447. });
  448. app.globalData.showToast('服务器请求出错');
  449. }
  450. });
  451. },
  452. // 获取商品列表
  453. get_goods_list(is_mandatory) {
  454. // 分页是否还有数据
  455. if ((is_mandatory || 0) == 0) {
  456. if (this.data_bottom_line_status == true) {
  457. uni.stopPullDownRefresh();
  458. return false;
  459. }
  460. }
  461. // 请求参数
  462. var data = {
  463. page: this.data_page,
  464. wd: this.search_keywords_value || ''
  465. };
  466. // 分类id
  467. if((this.data_content || null) != null) {
  468. // 主分类id
  469. data['category_id'] = this.data_content['id'];
  470. // 是否选中了二级分类
  471. if(this.nav_active_item_two_index != -1) {
  472. data['category_id'] = this.data_content['items'][this.nav_active_item_two_index]['id'];
  473. }
  474. // 是否选中了三级分类
  475. if(this.data_three_content != null && this.nav_active_item_three_index != -1) {
  476. data['category_id'] = this.data_three_content['items'][this.nav_active_item_three_index]['id'];
  477. }
  478. }
  479. // 获取数据
  480. uni.request({
  481. url: app.globalData.get_request_url("datalist", "search"),
  482. method: 'POST',
  483. data: data,
  484. dataType: 'json',
  485. success: res => {
  486. if (res.data.code == 0) {
  487. var data = res.data.data;
  488. if (data.data.length > 0) {
  489. if (this.data_page <= 1) {
  490. var temp_data_list = data.data;
  491. } else {
  492. var temp_data_list = this.data_list || [];
  493. var temp_data = data.data;
  494. for (var i in temp_data) {
  495. temp_data_list.push(temp_data[i]);
  496. }
  497. }
  498. this.setData({
  499. data_list: temp_data_list,
  500. data_total: data.total,
  501. data_page_total: data.page_total,
  502. data_list_loding_status: 3,
  503. data_page: this.data_page + 1
  504. });
  505. // 是否还有数据
  506. this.setData({
  507. data_bottom_line_status: (this.data_page > 1 && this.data_page > this.data_page_total)
  508. });
  509. // 购物车数据处理
  510. this.cart_data_list_handle();
  511. } else {
  512. this.setData({
  513. data_list_loding_status: 0,
  514. data_total: 0
  515. });
  516. if (this.data_page <= 1) {
  517. this.setData({
  518. data_list: [],
  519. data_bottom_line_status: false
  520. });
  521. }
  522. }
  523. } else {
  524. this.setData({
  525. data_list_loding_status: 0,
  526. data_list_loding_msg: res.data.msg
  527. });
  528. app.globalData.showToast(res.data.msg);
  529. }
  530. },
  531. fail: () => {
  532. this.setData({
  533. data_list_loding_status: 2,
  534. data_list_loding_msg: '服务器请求出错'
  535. });
  536. app.globalData.showToast('服务器请求出错');
  537. }
  538. });
  539. },
  540. // 重置滑动位置
  541. reset_scroll() {
  542. this.setData({
  543. scroll_top: this.scroll_top_old
  544. });
  545. this.$nextTick(() => {
  546. this.setData({
  547. scroll_top: 0
  548. });
  549. });
  550. },
  551. // 滑动事件位置记录
  552. scroll_event(e) {
  553. this.setData({
  554. scroll_top_old: e.detail.scrollTop
  555. });
  556. },
  557. // 滚动加载
  558. scroll_lower(e) {
  559. this.get_goods_list();
  560. },
  561. // 导航事件
  562. nav_event(e) {
  563. var index = e.currentTarget.dataset.index;
  564. var two_index = e.currentTarget.dataset.itemtwoindex;
  565. var three_index = e.currentTarget.dataset.itemthreeindex;
  566. var temp_data_content = this.category_list[index] || null;
  567. var temp_data_three_content = null;
  568. if(two_index != -1 && temp_data_content != null) {
  569. temp_data_three_content = temp_data_content['items'][two_index];
  570. }
  571. this.setData({
  572. nav_active_index: index,
  573. nav_active_item_two_index: two_index,
  574. nav_active_item_three_index: three_index,
  575. data_content: temp_data_content,
  576. data_three_content: temp_data_three_content,
  577. data_page: 1,
  578. data_list_loding_status: 1,
  579. data_list: []
  580. });
  581. // 商品模式则读取商品
  582. if(this.category_show_level == 0) {
  583. this.reset_scroll();
  584. this.get_goods_list(1);
  585. }
  586. },
  587. // 分类事件
  588. category_event(e) {
  589. uni.navigateTo({
  590. url: '/pages/goods-search/goods-search?category_id=' + e.currentTarget.dataset.value
  591. });
  592. },
  593. // 搜索事件
  594. search_button_event(e) {
  595. // 商品列表模式
  596. if(this.category_show_level == 0) {
  597. this.setData({
  598. search_keywords_value: e || '',
  599. data_page: 1,
  600. data_list_loding_status: 1,
  601. data_list: []
  602. });
  603. this.get_goods_list(1);
  604. } else {
  605. // 进入搜索页面
  606. uni.navigateTo({
  607. url: '/pages/goods-search/goods-search'+(((e || null) == null) ? '' : '?keywords='+e)
  608. });
  609. }
  610. },
  611. // url事件
  612. url_event(e) {
  613. app.globalData.url_event(e);
  614. },
  615. // 列表数据操作
  616. buy_number_event(e) {
  617. if(!app.globalData.is_single_page_check()) {
  618. return false;
  619. }
  620. var user = app.globalData.get_user_info(this);
  621. if (user != false) {
  622. // 用户未绑定用户则转到登录页面
  623. if (app.globalData.user_is_need_login(user)) {
  624. uni.navigateTo({
  625. url: "/pages/login/login?event_callback=buy_number_event"
  626. });
  627. return false;
  628. } else {
  629. var index = e.currentTarget.dataset.index;
  630. var type = parseInt(e.currentTarget.dataset.type) || 0;
  631. var temp_goods = this.data_list[index];
  632. this.setData({goods_choose_data: temp_goods});
  633. // 是否存在多规格
  634. if((temp_goods.is_exist_many_spec || 0) != 0) {
  635. // 是否购物车中操作
  636. if(type == 0) {
  637. this.setData({
  638. cart_status: true
  639. });
  640. app.globalData.showToast('不同规格的商品需在购物车减购');
  641. } else {
  642. if((this.$refs.goods_buy || null) != null) {
  643. this.$refs.goods_buy.init(temp_goods, {buy_event_type: 'cart'});
  644. }
  645. }
  646. return false;
  647. }
  648. // 数据操作处理
  649. this.buy_number_event_handle(e, type, temp_goods);
  650. }
  651. }
  652. },
  653. // 加入购物车成功回调
  654. goods_cart_back_event(e) {
  655. // 重新获取购物车数据
  656. this.get_cart_data();
  657. },
  658. // 列表数量事件处理
  659. buy_number_event_handle(e, type, goods, spec = '') {
  660. var res = this.buy_number_handle(type, goods, 'buy_number');
  661. if(res === false) {
  662. return false;
  663. }
  664. // 为0或减操作则查询
  665. var cart_item = null;
  666. if(type == 0 || (type == 1 && goods['buy_number'] > 0)) {
  667. var cart_data = this.cart.data;
  668. var params_spec = ((spec || null) == null || typeof(spec) != 'object') ? '' : JSON.stringify(spec);
  669. for(var i in cart_data) {
  670. if(goods['id'] == cart_data[i]['goods_id']) {
  671. var cart_spec = ((cart_data[i]['spec'] || null) == null || typeof(cart_data[i]['spec']) != 'object') ? '' : JSON.stringify(cart_data[i]['spec']);
  672. if(type == 0 || (type == 1 && cart_spec == params_spec)) {
  673. cart_item = cart_data[i];
  674. }
  675. break;
  676. }
  677. }
  678. }
  679. // 数据临时记录
  680. this.setData({
  681. temp_opt_data: {
  682. pos: e,
  683. goods: goods,
  684. type: type,
  685. }
  686. });
  687. // 操作类型
  688. if(res == 0) {
  689. if(cart_item == null) {
  690. app.globalData.showToast('购物车id有误');
  691. return false;
  692. }
  693. this.cart_delete(cart_item.id);
  694. } else if(cart_item == null) {
  695. this.cart_save(goods['id'], res, spec);
  696. } else {
  697. var number = (type == 0) ? parseInt(cart_item['stock'])-res : res+parseInt(cart_item['stock']);
  698. this.cart_update(cart_item.id, goods['id'], number);
  699. }
  700. return true;
  701. },
  702. // 购物车抛物线动画
  703. cart_para_curve_handle() {
  704. if((this.temp_opt_data || null) != null && (this.temp_opt_data.type || 0) == 1) {
  705. if((this.$refs.cart_para_curve || null) != null) {
  706. var self = this;
  707. uni.createSelectorQuery().select('.botton-nav .cart').boundingClientRect().exec(function(res) {
  708. self.$refs.cart_para_curve.init(res, self.temp_opt_data.pos, self.temp_opt_data.goods.images);
  709. });
  710. }
  711. }
  712. },
  713. // 购物车数量操作
  714. cart_buy_number_event(e) {
  715. if(!app.globalData.is_single_page_check()) {
  716. return false;
  717. }
  718. var user = app.globalData.get_user_info(this);
  719. if (user != false) {
  720. // 用户未绑定用户则转到登录页面
  721. if (app.globalData.user_is_need_login(user)) {
  722. uni.navigateTo({
  723. url: "/pages/login/login?event_callback=cart_buy_number_event"
  724. });
  725. return false;
  726. } else {
  727. var index = e.currentTarget.dataset.index;
  728. var type = parseInt(e.currentTarget.dataset.type) || 0;
  729. var temp_data = this.cart.data;
  730. var temp_goods = temp_data[index];
  731. // 数据操作处理
  732. var res = this.buy_number_handle(type, temp_goods, 'stock');
  733. if(res === false) {
  734. return false;
  735. }
  736. // 数据临时记录
  737. this.setData({
  738. temp_opt_data: {
  739. pos: e,
  740. goods: temp_goods,
  741. type: type,
  742. }
  743. });
  744. // 操作类型
  745. if(res == 0) {
  746. this.cart_delete(temp_goods['id']);
  747. } else {
  748. var number = (type == 0) ? parseInt(temp_goods['stock'])-res : res+parseInt(temp_goods['stock']);
  749. this.cart_update(temp_goods['id'], temp_goods['goods_id'], number);
  750. }
  751. }
  752. }
  753. },
  754. // 数量操作处理
  755. buy_number_handle(type, goods, buy_number_field) {
  756. // 加减处理
  757. var buy_number = parseInt(goods[buy_number_field]) || 0;
  758. if(type == 0) {
  759. buy_number -= 1;
  760. } else {
  761. buy_number += 1;
  762. }
  763. if(buy_number < 0) {
  764. buy_number = 0;
  765. }
  766. // 数据校验
  767. var buy_min_number = parseInt(goods['buy_min_number']) || 1;
  768. var buy_max_number = parseInt(goods['buy_max_number']) || 0;
  769. var spec_buy_min_number = parseInt(goods['spec_buy_min_number']) || 0;
  770. var spec_buy_max_number = parseInt(goods['spec_buy_max_number']) || 0;
  771. var inventory = parseInt(goods['inventory']);
  772. var inventory_unit = goods['inventory_unit'];
  773. // 最小起购数量
  774. var min = (spec_buy_min_number > 0) ? spec_buy_min_number : buy_min_number;
  775. if (min > 0) {
  776. if(type == 0) {
  777. if(buy_number < min) {
  778. buy_number = 0;
  779. }
  780. } else {
  781. if(buy_number < min) {
  782. buy_number = min;
  783. }
  784. }
  785. }
  786. // 最大购买数量
  787. var max = (spec_buy_max_number > 0) ? spec_buy_max_number : buy_max_number;
  788. if (max > 0 && buy_number > max) {
  789. buy_number = max;
  790. app.globalData.showToast('限购' + max + inventory_unit);
  791. return false;
  792. }
  793. // 数量是否改变
  794. if (goods[buy_number_field] == buy_number) {
  795. app.globalData.showToast('数量未改变');
  796. return false;
  797. }
  798. // 操作数量
  799. var opt_number = 1;
  800. if(type == 0) {
  801. if(buy_number <= 0) {
  802. opt_number = 0;
  803. }
  804. } else {
  805. if(buy_number > goods['buy_number']) {
  806. opt_number = buy_number-goods['buy_number'];
  807. }
  808. }
  809. return opt_number;
  810. },
  811. // 购物车添加
  812. cart_save(goods_id, buy_number, spec = '') {
  813. uni.request({
  814. url: app.globalData.get_request_url('save', 'cart'),
  815. method: 'POST',
  816. data: {
  817. "goods_id": goods_id,
  818. "stock": buy_number,
  819. "spec": spec
  820. },
  821. dataType: 'json',
  822. success: res => {
  823. if (res.data.code == 0) {
  824. this.cart_para_curve_handle();
  825. this.get_cart_data();
  826. } else {
  827. if (app.globalData.is_login_check(res.data)) {
  828. app.globalData.showToast(res.data.msg);
  829. }
  830. }
  831. },
  832. fail: () => {
  833. app.globalData.showToast('服务器请求出错');
  834. }
  835. });
  836. },
  837. // 购物车更新
  838. cart_update(cart_id, goods_id, buy_number) {
  839. uni.request({
  840. url: app.globalData.get_request_url("stock", "cart"),
  841. method: 'POST',
  842. data: {
  843. "id": cart_id,
  844. "goods_id": goods_id,
  845. "stock": buy_number
  846. },
  847. dataType: 'json',
  848. success: res => {
  849. if (res.data.code == 0) {
  850. this.cart_para_curve_handle();
  851. this.get_cart_data();
  852. } else {
  853. if (app.globalData.is_login_check(res.data)) {
  854. app.globalData.showToast(res.data.msg);
  855. } else {
  856. app.globalData.showToast('提交失败,请重试!');
  857. }
  858. }
  859. },
  860. fail: () => {
  861. app.globalData.showToast('服务器请求出错');
  862. }
  863. });
  864. },
  865. // 购物车删除
  866. cart_delete(cart_id) {
  867. uni.request({
  868. url: app.globalData.get_request_url('delete', 'cart'),
  869. method: 'POST',
  870. data: {
  871. "id": cart_id
  872. },
  873. dataType: 'json',
  874. success: res => {
  875. if (res.data.code == 0) {
  876. this.get_cart_data();
  877. } else {
  878. if (app.globalData.is_login_check(res.data)) {
  879. app.globalData.showToast(res.data.msg);
  880. } else {
  881. app.globalData.showToast('提交失败,请重试!');
  882. }
  883. }
  884. },
  885. fail: () => {
  886. app.globalData.showToast('服务器请求出错');
  887. }
  888. });
  889. },
  890. // 获取购物车数据
  891. get_cart_data() {
  892. if(this.user != null) {
  893. uni.request({
  894. url: app.globalData.get_request_url("index", "cart"),
  895. method: 'POST',
  896. data: {},
  897. dataType: 'json',
  898. success: res => {
  899. if (res.data.code == 0) {
  900. var data = res.data.data;
  901. var temp_cart = data.data || [];
  902. this.setData({
  903. cart: res.data.data
  904. });
  905. this.cart_data_list_handle();
  906. // 导航购物车处理
  907. if (data.buy_number <= 0) {
  908. app.globalData.set_tab_bar_badge(2, 0);
  909. } else {
  910. app.globalData.set_tab_bar_badge(2, 1, data.buy_number);
  911. }
  912. }
  913. },
  914. fail: () => {
  915. app.globalData.showToast('服务器请求出错');
  916. }
  917. });
  918. }
  919. },
  920. // 购物车更新列表数据处理
  921. cart_data_list_handle() {
  922. var temp_cart = this.cart || null;
  923. if(temp_cart != null) {
  924. var temp_data_list = this.data_list;
  925. if(temp_data_list.length > 0) {
  926. for(var i in temp_data_list) {
  927. temp_data_list[i]['buy_number'] = 0;
  928. if(temp_cart.data.length > 0) {
  929. for(var k in temp_cart.data) {
  930. if(temp_cart.data[k]['goods_id'] == temp_data_list[i]['id']) {
  931. temp_data_list[i]['buy_number'] += parseInt(temp_cart.data[k]['stock']);
  932. }
  933. }
  934. }
  935. }
  936. }
  937. this.setData({
  938. data_list: temp_data_list
  939. });
  940. }
  941. },
  942. // 批量删除操作
  943. cart_all_delete_event(e) {
  944. uni.showModal({
  945. title: '温馨提示',
  946. content: '挑了这么久,真的要清空吗?',
  947. confirmText: '确认',
  948. cancelText: '暂不',
  949. success: result => {
  950. if (result.confirm) {
  951. var ids = [];
  952. var temp_data = this.cart.data;
  953. for (var i in temp_data) {
  954. ids.push(temp_data[i]['id']);
  955. }
  956. this.cart_delete(ids.join(','));
  957. }
  958. }
  959. });
  960. },
  961. // 购物车状态
  962. cart_event(e) {
  963. this.setData({
  964. cart_status: !this.cart_status
  965. });
  966. },
  967. // 购物车结算
  968. buy_submit_event(e) {
  969. if(!app.globalData.is_single_page_check()) {
  970. return false;
  971. }
  972. // 获取购物车数据
  973. var ids = [];
  974. if((this.cart || null) != null) {
  975. var temp_data = this.cart.data || [];
  976. for (var i in temp_data) {
  977. if(temp_data[i]['is_error'] == 0) {
  978. ids.push(temp_data[i]['id']);
  979. }
  980. }
  981. }
  982. if (ids.length <= 0) {
  983. app.globalData.showToast('请先选购商品');
  984. return false;
  985. }
  986. // 进入订单确认页面
  987. var data = {
  988. "buy_type": "cart",
  989. "ids": ids.join(',')
  990. };
  991. uni.navigateTo({
  992. url: '/pages/buy/buy?data=' + encodeURIComponent(base64.encode(JSON.stringify(data)))
  993. });
  994. }
  995. }
  996. };
  997. </script>
  998. <style>
  999. @import './goods-category.css';
  1000. </style>