confirm_list.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. <template>
  2. <view class="confirms">
  3. <nav-bar title="确认订单"></nav-bar>
  4. <view class="contents">
  5. <!-- <view > -->
  6. <view v-for="(item, index) in goodsList" :key="item.id">
  7. <view class="item">
  8. <view style="display: flex; justify-content: space-between">
  9. <image
  10. :src="$method.splitImgHost(item.coverUrl)"
  11. style="height: 120rpx; width: 204rpx; border-radius: 16rpx"
  12. >
  13. </image>
  14. <view class="right_con" style="margin-left: 20rpx">
  15. <view style="color: #333333; font-size: 30rpx; font-weight: bold">
  16. {{ item.goodsName }}
  17. <text v-if="item.sevenYear"> ({{ item.sevenYear }}) </text>
  18. </view>
  19. <view class="priceTag"> ¥ {{ item.standPrice }} </view>
  20. <view
  21. class="input_c"
  22. v-if="item.templateType != null && item.goodsType == 1"
  23. >
  24. <view
  25. v-if="item.templateType == 'class'"
  26. style="
  27. display: flex;
  28. justify-content: space-between;
  29. align-items: center;
  30. height: 56rpx;
  31. padding: 8rpx;
  32. border-radius: 8rpx;
  33. "
  34. @click="openPopup(0, item)"
  35. >
  36. <view style="color: #666666; font-size: 24rpx">{{
  37. item.gradObj ? item.gradObj.className : "选择班级"
  38. }}</view>
  39. <view
  40. ><u-icon
  41. name="arrow-down"
  42. color="#999999"
  43. size="28"
  44. ></u-icon
  45. ></view>
  46. </view>
  47. <view
  48. v-if="item.templateType == 'apply'"
  49. style="
  50. display: flex;
  51. justify-content: space-between;
  52. align-items: center;
  53. height: 56rpx;
  54. padding: 8rpx;
  55. border-radius: 8rpx;
  56. "
  57. @click="openPopup(1, item)"
  58. >
  59. <view
  60. v-if="item.applyAreas"
  61. style="color: #666666; font-size: 24rpx"
  62. >{{
  63. item.examDate.examineName +
  64. "-" +
  65. item.applyAreas.areaName +
  66. "-" +
  67. item.applyAreas.cityName
  68. }}</view
  69. >
  70. <view v-else style="color: #666666; font-size: 24rpx">
  71. 报考地区
  72. </view>
  73. <view
  74. ><u-icon
  75. name="arrow-down"
  76. color="#999999"
  77. size="28"
  78. ></u-icon
  79. ></view>
  80. </view>
  81. </view>
  82. </view>
  83. </view>
  84. </view>
  85. </view>
  86. <!-- </view> -->
  87. </view>
  88. <view class="bottomBox safeArea">
  89. <view class="sums">
  90. <text class="all_sum">订单金额:</text>
  91. <text class="priceTag">¥ {{ totalPrice }}</text>
  92. </view>
  93. <view style="display: flex; color: #ffffff; align-items: center">
  94. <view class="btn2" :class="{ able: isAble() }" @click="goBuy()"
  95. >确认购买</view
  96. >
  97. </view>
  98. </view>
  99. <u-popup v-model="show1" mode="bottom" border-radius="40">
  100. <view class="popup_box">
  101. <view class="check_head">
  102. <view class="grade">选择考期/地区</view>
  103. <u-icon
  104. name="close"
  105. color="#CFCFCF"
  106. size="30"
  107. @click="closePop(1)"
  108. ></u-icon>
  109. </view>
  110. <view style="display: flex; height: 550rpx">
  111. <view style="width: 50%">
  112. <view class="topTxt">考期</view>
  113. <view>
  114. <picker-view
  115. :indicator-style="indicatorStyle"
  116. :value="value"
  117. @change="bindChangeE"
  118. class="picker-view"
  119. >
  120. <picker-view-column>
  121. <view
  122. class="picker-item"
  123. v-for="(item, index) in examine"
  124. :key="index"
  125. >{{ item.examineName }}</view
  126. >
  127. </picker-view-column>
  128. </picker-view>
  129. </view>
  130. </view>
  131. <view style="width: 50%">
  132. <view class="topTxt">地区</view>
  133. <view>
  134. <picker-view
  135. :indicator-style="indicatorStyle"
  136. :value="value"
  137. @change="bindChange"
  138. class="picker-view"
  139. >
  140. <picker-view-column>
  141. <view
  142. class="picker-item"
  143. v-for="(item, index) in provinceList"
  144. :key="index"
  145. >{{ item.areaName }}</view
  146. >
  147. </picker-view-column>
  148. <picker-view-column>
  149. <view
  150. class="picker-item"
  151. v-for="(item, index) in cityList"
  152. :key="index"
  153. >{{ item.areaName }}</view
  154. >
  155. </picker-view-column>
  156. </picker-view>
  157. </view>
  158. </view>
  159. </view>
  160. <view class="confrim-btn">
  161. <view class="okBtn" @click="okPopup">确定</view>
  162. </view>
  163. </view>
  164. </u-popup>
  165. <select-grade-box ref="grade" @submit="submitSelect" />
  166. </view>
  167. </template>
  168. <script>
  169. import ClassTimeTip from "../../components/common/ClassTimeTip.vue";
  170. import selectGradeBox from "@/components/common/selectGradeBox.vue";
  171. import { mapGetters } from "vuex";
  172. export default {
  173. components: { ClassTimeTip, selectGradeBox },
  174. data() {
  175. return {
  176. gradeValue: 0,
  177. gradeIndex: 0,
  178. id: 0,
  179. indicatorStyle: `height: 50px;`,
  180. showArea: true,
  181. show1: false,
  182. value: "",
  183. show: false,
  184. detail: {},
  185. provinceList: [],
  186. cityList: [],
  187. pAreaIndex: 0,
  188. cAreaIndex: 0,
  189. examine: [],
  190. examIndex: 0,
  191. applyAreas: {},
  192. examDate: {},
  193. applyObj: {
  194. applyAreasJson: null,
  195. examDateJson: null,
  196. },
  197. fromCart: "",
  198. isBK: "", //是不是补考商品
  199. goodsList: [],
  200. gradeListObj: {},
  201. activeItem: {},
  202. };
  203. },
  204. onPullDownRefresh() {},
  205. async onLoad(option) {
  206. this.id = option.id;
  207. this.isBK = option.isBK;
  208. if (option.fromCart) {
  209. this.fromCart = option.fromCart;
  210. }
  211. this.options = option;
  212. if (this.id) {
  213. this.goodsList = this.disCode
  214. ? await this.getFxDetail()
  215. : await this.getDetail();
  216. } else {
  217. this.goodsList = this.shoppingCartList;
  218. }
  219. this.goodsList.forEach((e, i) => {
  220. if (e.templateType == "class") {
  221. this.$set(e, "gradObj", {});
  222. this.goodsGradeList(e);
  223. }
  224. });
  225. },
  226. onShow() {},
  227. methods: {
  228. getExamine(id) {
  229. let self = this;
  230. this.$api.getExamine({ projectId: id }).then((res) => {
  231. if (res.data.code == 200) {
  232. self.examine = res.data.rows;
  233. }
  234. });
  235. },
  236. getCityList(id) {
  237. let self = this;
  238. this.$api.getCityList({ parentId: id }).then((res) => {
  239. if (res.data.code == 200) {
  240. self.cityList = res.data.rows;
  241. }
  242. });
  243. },
  244. getProvinceList() {
  245. let self = this;
  246. if (self.provinceList.length > 0) {
  247. return;
  248. }
  249. this.$api.getProvinceList().then((res) => {
  250. if (res.data.code == 200) {
  251. self.provinceList = res.data.rows;
  252. if (self.provinceList.length > 0) {
  253. self.getCityList(self.provinceList[0].areaId);
  254. }
  255. }
  256. });
  257. },
  258. submitSelect(gradObj) {
  259. this.$set(this.activeItem, "gradObj", gradObj);
  260. },
  261. //弹出框确定
  262. okPopup(index) {
  263. if (!this.checkAreaData()) {
  264. return;
  265. }
  266. this.examDate = this.examine[this.examIndex];
  267. let pData = this.provinceList[this.pAreaIndex];
  268. let cData = this.cityList[this.cAreaIndex];
  269. this.applyAreas = {
  270. areaName: pData.areaName,
  271. areaId: pData.areaId,
  272. cityId: cData.areaId,
  273. cityName: cData.areaName,
  274. };
  275. this.applyObj.applyAreasJson = JSON.stringify(this.applyAreas);
  276. this.applyObj.examDateJson = JSON.stringify(this.examDate);
  277. this.activeItem.examDate = this.examDate;
  278. this.activeItem.applyAreas = this.applyAreas;
  279. this.show1 = false;
  280. },
  281. checkAreaData() {
  282. if (this.examine.length == 0) {
  283. uni.showModal({
  284. title: "提示",
  285. content: "请选择考期",
  286. showCancel: false,
  287. });
  288. return false;
  289. }
  290. return true;
  291. },
  292. isAble() {
  293. if (this.detail.templateType == "class" && this.detail.goodsType == 1) {
  294. if (this.gradeValue < 0) {
  295. return false;
  296. }
  297. } else if (
  298. this.detail.templateType == "apply" &&
  299. this.detail.goodsType == 1
  300. ) {
  301. /* if(!this.applyObj.examDateJson){
  302. uni.showModal({
  303. title: "提示",
  304. content: '请选择考期',
  305. showCancel: false
  306. })
  307. return false
  308. } */
  309. }
  310. return true;
  311. },
  312. checkData() {
  313. if (this.goodsList.length == 0) {
  314. uni.showModal({
  315. title: "提示",
  316. content: "请选择商品",
  317. showCancel: false,
  318. });
  319. return false;
  320. }
  321. return this.goodsList.some((item) => {
  322. if (item.templateType == "class" && item.goodsType == 1) {
  323. if (!item.gradObj.className) {
  324. uni.showModal({
  325. title: "提示",
  326. content: "请选择班级",
  327. showCancel: false,
  328. });
  329. return false;
  330. }
  331. }
  332. if (item.templateType == "apply" && item.goodsType == 1) {
  333. // if (!item.applyAreas.areaName) {
  334. // uni.showModal({
  335. // title: '提示',
  336. // content: '请选择报考地区',
  337. // showCancel: false
  338. // });
  339. // return false;
  340. // }
  341. }
  342. return true;
  343. });
  344. },
  345. radioGroupChange(e) {
  346. console.log(e);
  347. },
  348. goodsGradeList(item) {
  349. this.$api.goodsGradeList({ goodsId: item.goodsId }).then((res) => {
  350. let { code, rows } = res.data;
  351. if (code == 200) {
  352. let gradeList = rows;
  353. if (gradeList.length == 0) {
  354. gradeList.push({
  355. className: "系统分班",
  356. gradeId: 0,
  357. });
  358. } else {
  359. let isGradeFull = gradeList.every(
  360. (item) =>
  361. item.studentNum > 0 && item.studentNum == item.studentUpper
  362. );
  363. //所有班级都满了
  364. if (isGradeFull) {
  365. let item = {
  366. className: "系统分班",
  367. gradeId: 0,
  368. };
  369. gradeList.unshift(item);
  370. }
  371. }
  372. this.$set(item, "gradObj", gradeList[0]);
  373. this.gradeListObj[item.goodsId] = gradeList;
  374. }
  375. });
  376. },
  377. goBuy() {
  378. if (!this.checkData()) {
  379. return;
  380. }
  381. this.$store.commit("setShoppingCartList", {
  382. shoppingCartList: this.goodsList,
  383. });
  384. if (this.isBK == "1") {
  385. this.$navTo.togo("/pages2/order/confirm_pay", {
  386. isBK: "1",
  387. ...this.addParam(),
  388. });
  389. } else {
  390. this.$navTo.togo("/pages2/order/confirm_pay", {
  391. ...this.addParam(),
  392. });
  393. }
  394. },
  395. addParam() {
  396. let data = { fromCart: this.fromCart };
  397. if (this.disCode) {
  398. data.distributionCode = this.disCode;
  399. }
  400. if (this.options.linkCode) {
  401. data.linkCode = this.options.linkCode;
  402. }
  403. return data;
  404. },
  405. getDetail() {
  406. return this.$api.commonGoodsDetail(this.id).then((res) => {
  407. let { code, data } = res.data;
  408. if (code == 200) {
  409. this.detail = data;
  410. this.goodsList = [data];
  411. return Promise.resolve([data]);
  412. }
  413. });
  414. },
  415. getFxDetail() {
  416. return this.$api
  417. .fxGoodsDetail({
  418. goodsId: this.id,
  419. disCode: this.disCode,
  420. })
  421. .then((res) => {
  422. let { code, data } = res.data;
  423. if (code == 200) {
  424. this.goodsList = [data];
  425. // self.getExamine(self.detail.projectId);
  426. return Promise.resolve([data]);
  427. }
  428. });
  429. },
  430. bindChangeE(e) {
  431. console.log(e.detail.value);
  432. this.examIndex = e.detail.value[0];
  433. },
  434. bindChange(e) {
  435. const val = e.detail.value;
  436. if (this.pAreaIndex != val[0]) {
  437. this.pAreaIndex = val[0];
  438. this.getCityList(this.provinceList[this.pAreaIndex].areaId);
  439. }
  440. if (this.cAreaIndex != val[1]) {
  441. this.cAreaIndex = val[1];
  442. }
  443. },
  444. openPopup(index, item) {
  445. this.activeItem = item || {};
  446. if (index == 0) {
  447. this.$refs["grade"].open(
  448. this.gradeListObj[item.goodsId],
  449. item.gradObj.gradeId
  450. );
  451. } else {
  452. this.getExamine(100);
  453. this.getProvinceList();
  454. this.show1 = true;
  455. }
  456. },
  457. closePop(index) {
  458. if (index == 0) {
  459. this.show = false;
  460. } else {
  461. this.show1 = false;
  462. }
  463. },
  464. },
  465. onReachBottom() {},
  466. computed: {
  467. ...mapGetters(["userInfo", "shoppingCartList"]),
  468. disCode() {
  469. return this.options.distributionCode;
  470. },
  471. totalPrice() {
  472. return this.goodsList.reduce((a, b) => a + Number(b.standPrice), 0);
  473. },
  474. },
  475. };
  476. </script>
  477. <style>
  478. page {
  479. background-color: #eaeef1;
  480. }
  481. </style>
  482. <style scoped lang="scss">
  483. .confirms {
  484. width: 100%;
  485. height: 100vh;
  486. // background: #fff;
  487. .contents {
  488. padding: 32rpx 32rpx 132rpx 32rpx;
  489. }
  490. .right_con {
  491. width: 450rpx;
  492. }
  493. }
  494. .picker-item {
  495. height: 50px;
  496. align-items: center;
  497. justify-content: center;
  498. text-align: center;
  499. }
  500. .picker-view {
  501. width: 100%;
  502. height: 420rpx;
  503. text-align: center;
  504. }
  505. .topTxt {
  506. font-size: 30rpx;
  507. color: #666666;
  508. text-align: center;
  509. padding: 20rpx 0;
  510. }
  511. .blackTxt {
  512. font-size: 30rpx;
  513. font-family: PingFang SC;
  514. font-weight: bold;
  515. color: #333333;
  516. }
  517. .blue-box {
  518. background: #ebf5ff;
  519. }
  520. .white-box {
  521. width: 646rpx;
  522. border-radius: 24rpx;
  523. align-items: center;
  524. display: flex;
  525. padding-left: 15rpx;
  526. }
  527. .okBtn {
  528. width: 232rpx;
  529. height: 92rpx;
  530. line-height: 92rpx;
  531. background: #fc3f3f;
  532. border-radius: 120rpx;
  533. color: #ffffff;
  534. text-align: center;
  535. font-size: 32rpx;
  536. font-weight: 500;
  537. }
  538. .confrim-btn {
  539. // border-top:1px solid #eee;
  540. height: 98rpx;
  541. width: 100%;
  542. display: flex;
  543. align-items: center;
  544. justify-content: center;
  545. }
  546. .grade {
  547. // height: 23rpx;
  548. font-size: 32rpx;
  549. color: #222;
  550. // margin: 0 auto;
  551. // margin-top: 15rpx;
  552. font-weight: 500;
  553. text-align: center;
  554. }
  555. .line1 {
  556. width: 80rpx;
  557. height: 8rpx;
  558. background: #999999;
  559. border-radius: 4rpx;
  560. margin: 0 auto;
  561. margin-top: 15rpx;
  562. }
  563. .popup_box {
  564. height: 824rpx;
  565. box-shadow: 0rpx 0rpx 16rpx 4rpx rgba(145, 156, 178, 0.1);
  566. border-radius: 28rpx 28rpx 0rpx 0rpx;
  567. .check_head {
  568. padding: 0rpx 32rpx;
  569. display: flex;
  570. align-items: center;
  571. justify-content: space-between;
  572. height: 104rpx;
  573. background: #f2f2f2;
  574. }
  575. .items_c {
  576. padding: 0rpx 32rpx;
  577. }
  578. .border_c {
  579. display: flex;
  580. align-items: center;
  581. padding: 20rpx 0rpx;
  582. border-bottom: 1rpx solid #f2f2f2;
  583. }
  584. }
  585. .item {
  586. width: 100%;
  587. background: #ffffff;
  588. border-radius: 24rpx;
  589. margin-bottom: 20rpx;
  590. padding: 15rpx;
  591. }
  592. .priceTag {
  593. font-size: 28rpx;
  594. font-family: PingFang SC;
  595. font-weight: bold;
  596. color: #fc3f3f;
  597. margin-top: 6rpx;
  598. margin-bottom: 16rpx;
  599. }
  600. .input_c {
  601. background: #f8f8f8;
  602. }
  603. .btn2 {
  604. width: 232rpx;
  605. height: 92rpx;
  606. background: #fc3f3f;
  607. border-radius: 120rpx;
  608. // width: 200rpx;
  609. // height: 64rpx;
  610. // background: linear-gradient(0deg, #015EEA, #00C0FA);
  611. text-align: center;
  612. line-height: 92rpx;
  613. &.able {
  614. opacity: 1;
  615. }
  616. }
  617. .bottomBox {
  618. position: fixed;
  619. bottom: 0;
  620. width: 100%;
  621. left: 0;
  622. height: 132rpx;
  623. background-color: #ffffff;
  624. display: flex;
  625. justify-content: space-between;
  626. align-items: center;
  627. box-sizing: unset;
  628. box-shadow: 0px -2px 6px 0px rgba(0, 0, 0, 0.1);
  629. > view {
  630. margin: 0 30rpx;
  631. }
  632. .sums {
  633. display: flex;
  634. }
  635. .all_sum {
  636. font-size: 28rpx;
  637. font-weight: 500;
  638. color: #303030;
  639. }
  640. }
  641. </style>