confirm_list.vue 15 KB

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