Goods.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. <template>
  2. <div>
  3. <div v-if="!shop_com" class="right-main clearfix">
  4. <div class="float_left h-goods-div">
  5. <el-input
  6. ref="barCodeInput"
  7. v-model="shop"
  8. :placeholder="'请输入' + goods_key_sel"
  9. clearable
  10. class="input-with-select"
  11. style="width: 88%; margin-left: 20px"
  12. @keyup.enter.native="searchGoods"
  13. >
  14. <el-select
  15. slot="prepend"
  16. v-model="goods_key_sel"
  17. style="width: 120px"
  18. placeholder="请选择"
  19. >
  20. <el-option label="条形码" value="商品条形码"></el-option>
  21. <el-option label="商品名称" value="商品名称"></el-option>
  22. </el-select>
  23. <!-- @click="pageChange(1)"-->
  24. <el-button
  25. slot="append"
  26. icon="el-icon-search"
  27. @click="searchGoods"
  28. ></el-button>
  29. </el-input>
  30. <ul v-if="allShop === true">
  31. <li
  32. v-for="(item, index) in shop_shop"
  33. :key="index"
  34. class="shop_info clearfix"
  35. @click="selGoods(item.id)"
  36. >
  37. <div class="float_left">
  38. <img :src="item.images[0]" alt="" />
  39. </div>
  40. <div class="float_left goods-info">
  41. <p>{{ item.title }}</p>
  42. <div>
  43. <span class="price-color" style="margin-right: 8px">
  44. ¥{{ item.minSalePrice }}
  45. </span>
  46. <span style="font-size: 12px; color: #999">
  47. 库存:{{ item.inventorTotal }}
  48. </span>
  49. </div>
  50. </div>
  51. </li>
  52. </ul>
  53. <FooterPage
  54. :page-size="pageSize"
  55. :total-page.sync="total"
  56. :current-page.sync="page"
  57. @pageChange="pageChange"
  58. @sizeChange="sizeChange"
  59. ></FooterPage>
  60. </div>
  61. <!-- 商品分类-->
  62. <div class="cate-div">
  63. <p
  64. class="cate-li"
  65. :class="[!cate_id ? 'cate-on' : '']"
  66. @click="changeCate()"
  67. >
  68. 全部
  69. </p>
  70. <p
  71. v-for="(item, index) in classify_list"
  72. :key="index"
  73. class="cate-li"
  74. :class="[cate_id === item.id ? 'cate-on' : '']"
  75. @click="changeCate(item)"
  76. >
  77. {{ item.title }}
  78. </p>
  79. </div>
  80. </div>
  81. <div v-else class="right-main">
  82. <div>
  83. <div class="head_back">
  84. <i class="el-icon-back"></i>
  85. <span style="margin-left: 6px" @click="goShop">返回</span>
  86. <span class="head_line"></span>
  87. <span class="head-back-tit">选择规格</span>
  88. </div>
  89. <div class="shop_info clearfix">
  90. <div class="float_left">
  91. <img :src="shop_all.images[0]" alt="" />
  92. </div>
  93. <div class="float_right goods-info">
  94. <p>
  95. {{ shop_all.title }}
  96. </p>
  97. <div v-if="now_sku_data.id">
  98. <span class="price-color" style="margin-right: 10px">
  99. ¥{{ now_sku_data.salePrice }}
  100. </span>
  101. <span style="font-size: 12px; color: #999">
  102. 库存:{{ now_sku_data.inventory }}
  103. </span>
  104. </div>
  105. <div v-else>
  106. <span class="price-color" style="margin-right: 10px">
  107. ¥{{ shop_all.minSalePrice }}
  108. </span>
  109. <span style="font-size: 12px; color: #999">
  110. 库存:{{ shop_all.inventorTotal }}
  111. </span>
  112. </div>
  113. </div>
  114. </div>
  115. <div style="color: #333333">
  116. <p style="margin-left: 10px">单位</p>
  117. <ul>
  118. <li
  119. v-for="(item, index) in shop_all.unitData"
  120. :key="index"
  121. class="shop_color"
  122. :class="
  123. parseInt(spec_id_group[1]) === parseInt(item.unitId)
  124. ? 'shop_color_li'
  125. : 'shop_color'
  126. "
  127. @click="bindPickerChange(item.unitId, 1)"
  128. >
  129. {{ item.unitName }}
  130. </li>
  131. </ul>
  132. </div>
  133. <div
  134. v-for="(item, index) in shop_all.specGroup"
  135. :key="index"
  136. style="color: #333333"
  137. >
  138. <p style="margin-left: 10px">
  139. {{ item.groupSpec.specName }}
  140. </p>
  141. <ul>
  142. <li
  143. v-for="(res, resIndex) in item.params"
  144. :key="resIndex"
  145. class="shop_color"
  146. :class="
  147. parseInt(spec_id_group[index + 2]) === parseInt(res.specValueId)
  148. ? 'shop_color_li'
  149. : 'shop_color'
  150. "
  151. @click="
  152. bindPickerChange(
  153. res.specValueId,
  154. index + 2,
  155. item.groupSpec.specId,
  156. res
  157. )
  158. "
  159. >
  160. {{ res.specValueName }}
  161. </li>
  162. </ul>
  163. </div>
  164. <div style="color: #333333">
  165. <p style="margin-left: 10px">
  166. {{
  167. ["KG", "kg"].includes(now_sku_data.unitName) ? "重量/kg" : "数量"
  168. }}
  169. </p>
  170. <el-popover v-model="keyboard_visible" placement="bottom">
  171. <keyboard :lb-num="false" @click="numFnThree"></keyboard>
  172. <div slot="reference" style="width: 200px">
  173. <el-input v-model="num2"></el-input>
  174. </div>
  175. </el-popover>
  176. </div>
  177. <div
  178. v-if="['KG', 'kg'].includes(now_sku_data.unitName)"
  179. style="color: #333333"
  180. >
  181. <p style="margin-left: 10px">皮重/kg</p>
  182. <el-input
  183. v-model="pack_weight"
  184. style="width: 200px"
  185. readonly
  186. ></el-input>
  187. </div>
  188. </div>
  189. <div style="text-align: right; padding-right: 40px">
  190. <div
  191. v-if="['KG', 'kg'].includes(now_sku_data.unitName)"
  192. style="display: inline-block; padding-right: 10px"
  193. >
  194. <el-button @click="clearPack">去皮</el-button>
  195. <el-button @click="plusPack">清皮</el-button>
  196. </div>
  197. <el-button type="primary" @click="addCart">确定</el-button>
  198. </div>
  199. </div>
  200. </div>
  201. </template>
  202. <script>
  203. import { getAllCategory, getGoodsByBarCode } from "@/api/goods";
  204. import Keyboard from "./Keyboard";
  205. import {
  206. addCartCashier,
  207. getCartByUser,
  208. getGoodsDetail,
  209. GoodsByCategory,
  210. updateBuyNumCashier,
  211. } from "@/api/Cashier";
  212. export default {
  213. name: "Goods",
  214. components: {
  215. Keyboard,
  216. },
  217. props: {
  218. shopCom: {
  219. type: Boolean,
  220. default: false,
  221. },
  222. allShop: {
  223. type: Boolean,
  224. default: false,
  225. },
  226. userCenterId: {
  227. type: [String, Number],
  228. default: 0,
  229. },
  230. numList: {
  231. type: Array,
  232. default: () => {
  233. return [];
  234. },
  235. },
  236. nowSelShop: {
  237. type: Object,
  238. default: () => {
  239. return {};
  240. },
  241. },
  242. },
  243. data() {
  244. return {
  245. shop: "",
  246. goods_key_sel: "商品条形码",
  247. shop_shop: [],
  248. total: 0,
  249. page: 1,
  250. pageSize: 10,
  251. goodsId: "",
  252. spec_id_group: [],
  253. shop_all: {
  254. images: [],
  255. },
  256. goodsBasicId: "",
  257. shopId: 1,
  258. now_sku_data: {},
  259. input_key_num: "",
  260. num2: "1",
  261. pack_weight: 0, // 商品皮重
  262. keyboard_visible: false, // 商品数量输入弹窗
  263. cate_id: "", // 当前已选择分类id
  264. add_cart_lodaing: false, // 加入购物车按钮加载中
  265. discount_list: [], // 优惠活动
  266. classify_list: [],
  267. shop_com: false,
  268. };
  269. },
  270. mounted() {
  271. this.shop_com = this.shopCom;
  272. // 获取焦点
  273. this.$nextTick(() => {
  274. this.$refs["barCodeInput"].focus();
  275. });
  276. this.getAllCategory();
  277. this.GoodsByCategory();
  278. },
  279. methods: {
  280. pageChange(val) {
  281. this.page = val;
  282. this.GoodsByCategory();
  283. },
  284. // 每页数据大小改变
  285. sizeChange(val) {
  286. this.pageSize = val;
  287. this.pageChange(1);
  288. },
  289. numFnThree(e, num) {
  290. if (!["x", "清除", "确定"].includes(num)) {
  291. this.numList.push(num);
  292. }
  293. if (num === "x") {
  294. this.num2 = this.num2.substring(0, this.num2.length - 1);
  295. } else if (num === "清除") {
  296. this.num2 = "";
  297. this.numList = [];
  298. } else if (num === "确定") {
  299. this.keyboard_visible = false;
  300. } else {
  301. this.num2 += num;
  302. }
  303. },
  304. // 去皮
  305. clearPack() {
  306. this.pack_weight = this.num2;
  307. this.num2 = 0;
  308. },
  309. // 清皮
  310. plusPack() {
  311. this.num2 = this.$NP.plus(this.num2, this.pack_weight);
  312. this.pack_weight = 0;
  313. },
  314. // 搜索商品
  315. searchGoods() {
  316. if (this.goods_key_sel === "商品条形码") {
  317. this.getGoodsByBarCode();
  318. } else {
  319. this.pageChange(1);
  320. }
  321. },
  322. // 根据条码获取商品
  323. async getGoodsByBarCode() {
  324. if (!this.shop) {
  325. this.$message.warning("请输入条形码");
  326. return;
  327. }
  328. const { data } = await getGoodsByBarCode({
  329. barCode: this.shop,
  330. userCenterId: this.userCenterId,
  331. });
  332. this.goodsId = data.goodsId;
  333. this.spec_id_group = data.index.split(":");
  334. this.shop_all = data.detail;
  335. this.goodsBasicId = data.detail.basicGoodsId;
  336. this.shopId = data.detail.shopId;
  337. this.now_sku_data = data.detail.specMultiple.find((item) => {
  338. return item.id === data.skuId;
  339. });
  340. // 选择商品后清除key
  341. this.shop = "";
  342. this.$refs["barCodeInput"].focus();
  343. if (["KG"].includes(this.now_sku_data.unitName)) {
  344. //打开输入弹窗
  345. this.$emit("openKeyboard", "-2");
  346. this.input_key_num = data.setNum || 1;
  347. this.$emit("inputKey", this.input_key_num);
  348. } else {
  349. this.num2 = data.setNum || 1;
  350. await this.addCart();
  351. }
  352. },
  353. // 切换分类
  354. changeCate(cate) {
  355. this.cate_id = cate ? cate.id : "";
  356. this.page = 1;
  357. this.GoodsByCategory();
  358. },
  359. // 商品列表
  360. async GoodsByCategory() {
  361. if(!this.nowSelShop.id || this.nowSelShop.id<=0){
  362. return;
  363. }
  364. const data = await GoodsByCategory({
  365. page: this.page,
  366. pageSize: this.pageSize,
  367. categoryId: this.cate_id,
  368. keyword: this.shop,
  369. userCenterId: this.userCenterId,
  370. shopId: this.nowSelShop.id,
  371. });
  372. this.shop_shop = data.data;
  373. this.total = data.pageTotal;
  374. },
  375. // 选择商品
  376. selGoods(id) {
  377. // this.now_sku_data = {}
  378. this.goodsId = id;
  379. this.$emit("goodsId", this.goodsId);
  380. this.getGoodsDetail(id);
  381. },
  382. // 商品详情
  383. async getGoodsDetail(id) {
  384. // 选择商品后清除商品数量
  385. this.num2 = 1;
  386. const data = await getGoodsDetail(id, {
  387. userCenterId: this.userCenterId,
  388. });
  389. this.spec_id_group[0] = id;
  390. this.shop_all = data.data;
  391. this.goodsBasicId = data.data.basicGoodsId;
  392. this.shopId = data.data.shopId;
  393. if (["KG", "kg"].includes(this.shop_all.unitData.unitName)) {
  394. this.num2 = 0;
  395. }
  396. if (this.shop_all.specMultiple.length === 1) {
  397. this.num2 = 1;
  398. this.now_sku_data = this.shop_all.specMultiple[0];
  399. this.addCart();
  400. } else {
  401. this.shop_com = true;
  402. }
  403. },
  404. // 选择规格
  405. bindPickerChange(id, index, specId) {
  406. this.$set(this.spec_id_group, index, parseInt(id));
  407. // console.log(this.spec_id_group);
  408. if (this.spec_id_group.every((item) => !!item)) {
  409. const indexGroup = this.spec_id_group.join(":");
  410. // console.log(indexGroup);
  411. const nowSkuData = this.shop_all.specMultiple.find(
  412. (item) => item.index === indexGroup
  413. );
  414. if (nowSkuData) {
  415. this.now_sku_data = nowSkuData;
  416. }
  417. // console.log("now_sku_data:", this.now_sku_data);
  418. }
  419. },
  420. // 加入购物车
  421. async addCart() {
  422. console.log()
  423. if (!this.now_sku_data.id) {
  424. this.$message.warning("请选择规格");
  425. return;
  426. }
  427. if (!Number(this.num2) || Number(this.num2) <= 0) {
  428. this.$message.warning("请输入正确的商品数量");
  429. return;
  430. }
  431. const data = await addCartCashier({
  432. goodsData: [
  433. {
  434. skuId: this.now_sku_data.id,
  435. goodsId: this.goodsId,
  436. buyNum: this.num2,
  437. shopId: this.shopId,
  438. source: "4",
  439. goodsBasicId: this.goodsBasicId,
  440. warehouseId:this.shop_all.warehouseId
  441. },
  442. ],
  443. userCenterId: this.userCenterId,
  444. });
  445. this.$message.success("已选择");
  446. this.goShop();
  447. this.$emit("getCartByUser");
  448. },
  449. // 商品详情返回按钮
  450. goShop() {
  451. // 点击返回按钮重置数据
  452. this.now_sku_data = {};
  453. this.spec_id_group = [];
  454. this.shop_com = false;
  455. },
  456. // 获取分类列表
  457. async getAllCategory() {
  458. const { data } = await getAllCategory();
  459. if (JSON.stringify(data) === "{}") {
  460. this.classify_list = [];
  461. } else {
  462. this.classify_list = data;
  463. }
  464. },
  465. },
  466. };
  467. </script>
  468. <style scoped>
  469. .right-main {
  470. height: calc(99vh - 166px);
  471. overflow: auto;
  472. }
  473. .h-goods-div {
  474. width: 89.8%;
  475. height: 100%;
  476. overflow: auto;
  477. }
  478. .cate-div {
  479. float: right;
  480. overflow: auto;
  481. width: 10%;
  482. height: 100%;
  483. border-left: 1px solid #f2f2f2;
  484. text-align: center;
  485. color: #333333;
  486. }
  487. .shop_info {
  488. display: inline-block;
  489. width: 276px;
  490. border-radius: 4px;
  491. border: 1px solid #ededed;
  492. margin: 20px 10px 15px 10px;
  493. padding: 12px 12px 12px 10px;
  494. cursor: pointer;
  495. color: #333333;
  496. line-height: 18px;
  497. }
  498. .shop_info img {
  499. border: 1px solid #f4f4f4;
  500. border-radius: 4px;
  501. width: 68px;
  502. height: 68px;
  503. }
  504. .shop_info .goods-info {
  505. width: calc(100% - 80px);
  506. margin-left: 10px;
  507. }
  508. .goods-info > p {
  509. padding-bottom: 5px;
  510. color: #333333;
  511. height: 36px;
  512. overflow: hidden;
  513. text-overflow: ellipsis;
  514. display: -webkit-box;
  515. -webkit-box-orient: vertical;
  516. -webkit-line-clamp: 2;
  517. }
  518. .price-color {
  519. color: #f56c6c;
  520. }
  521. .cate-li {
  522. height: auto;
  523. line-height: 16px;
  524. padding: 16px 6px;
  525. cursor: pointer;
  526. /*background: rgba(32,83,212, 0.1);*/
  527. /*color: #409EFF;*/
  528. }
  529. .cate-on {
  530. background: rgb(236, 245, 255);
  531. color: #409eff;
  532. }
  533. .right-main {
  534. height: calc(99vh - 166px);
  535. overflow: auto;
  536. }
  537. .head_back {
  538. color: #ccc;
  539. font-size: 14px;
  540. cursor: pointer;
  541. height: 50px;
  542. line-height: 50px;
  543. padding-left: 20px;
  544. }
  545. .head_back .head-back-tit {
  546. color: #333333;
  547. }
  548. .head_back .head_line {
  549. height: 20px;
  550. width: 1px;
  551. background-color: #ededed;
  552. display: inline-block;
  553. margin: 4px 10px -6px 10px;
  554. }
  555. .shop_color {
  556. width: 148px;
  557. height: 48px;
  558. line-height: 48px;
  559. background: #f5f6fa;
  560. border: 1px solid #f5f6fa;
  561. border-radius: 4px;
  562. padding: 0 20px;
  563. text-align: center;
  564. margin: 0 14px 14px 0;
  565. cursor: pointer;
  566. display: inline-block;
  567. }
  568. .shop_color_li {
  569. background: rgb(236, 245, 255);
  570. color: #409eff;
  571. border: 1px solid #409eff;
  572. }
  573. </style>