Commit b67c5310efbf868acfbe907ee10f2099341977a3

Authored by 夏洋涛
1 parent 2934fa95
Exists in master

feat: 修改同步

src/assets/service/select.png 0 → 100644

1.37 KB

src/common/validateIdent.js 0 → 100644
@@ -0,0 +1,159 @@ @@ -0,0 +1,159 @@
  1 +const validateIdent = {
  2 + aIdentityCode_City: { // 城市代码列表
  3 + 11: "北京",
  4 + 12: "天津",
  5 + 13: "河北",
  6 + 14: "山西",
  7 + 15: "内蒙古",
  8 + 21: "辽宁",
  9 + 22: "吉林",
  10 + 23: "黑龙江 ",
  11 + 31: "上海",
  12 + 32: "江苏",
  13 + 33: "浙江",
  14 + 34: "安徽",
  15 + 35: "福建",
  16 + 36: "江西",
  17 + 37: "山东",
  18 + 41: "河南",
  19 + 42: "湖北 ",
  20 + 43: "湖南",
  21 + 44: "广东",
  22 + 45: "广西",
  23 + 46: "海南",
  24 + 50: "重庆",
  25 + 51: "四川",
  26 + 52: "贵州",
  27 + 53: "云南",
  28 + 54: "西藏 ",
  29 + 61: "陕西",
  30 + 62: "甘肃",
  31 + 63: "青海",
  32 + 64: "宁夏",
  33 + 65: "新疆",
  34 + 71: "台湾",
  35 + 81: "香港",
  36 + 82: "澳门",
  37 + 91: "国外 "
  38 + },
  39 + IdentityCode_isCardNo(card) { //检查号码是否符合规范,包括长度,类型
  40 + var reg = /(^\d{15}$)|(^\d{17}(\d|X)$)/; //身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
  41 + if (reg.test(card) === false) {
  42 + return false;
  43 + }
  44 + return true;
  45 + },
  46 + IdentityCode_checkProvince(card) { //取身份证前两位,校验省份
  47 + var province = card.substr(0, 2);
  48 + if (validateIdent.aIdentityCode_City[province] == undefined) {
  49 + return false;
  50 + }
  51 + return true;
  52 + },
  53 + IdentityCode_checkBirthday(card) { //检查生日是否正确,15位以'19'年份来进行补齐。
  54 + var len = card.length;
  55 + //身份证15位时,次序为省(3位)市(3位)年(2位)月(2位)日(2位)校验位(3位),皆为数字
  56 + if (len == '15') {
  57 + var re_fifteen = /^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/;
  58 + var arr_data = card.match(re_fifteen); // 正则取号码内所含出年月日数据
  59 + var year = arr_data[2];
  60 + var month = arr_data[3];
  61 + var day = arr_data[4];
  62 + var birthday = new Date('19' + year + '/' + month + '/' + day);
  63 + return validateIdent.IdentityCode_verifyBirthday('19' + year, month, day, birthday);
  64 + }
  65 + //身份证18位时,次序为省(3位)市(3位)年(4位)月(2位)日(2位)校验位(4位),校验位末尾可能为X
  66 + if (len == '18') {
  67 + var re_eighteen = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/;
  68 + var arr_data = card.match(re_eighteen); // 正则取号码内所含出年月日数据
  69 + var year = arr_data[2];
  70 + var month = arr_data[3];
  71 + var day = arr_data[4];
  72 + var birthday = new Date(year + '/' + month + '/' + day);
  73 + return validateIdent.IdentityCode_verifyBirthday(year, month, day, birthday);
  74 + }
  75 + return false;
  76 + },
  77 + IdentityCode_verifyBirthday(year, month, day, birthday) { //校验日期 ,15位以'19'年份来进行补齐。
  78 + var now = new Date();
  79 + var now_year = now.getFullYear();
  80 + //年月日是否合理
  81 + if (birthday.getFullYear() == year &&
  82 + (birthday.getMonth() + 1) == month &&
  83 + birthday.getDate() == day) {
  84 + //判断年份的范围(3岁到150岁之间)
  85 + var time = now_year - year;
  86 + if (time >= 3 && time <= 150) {
  87 + return true;
  88 + }
  89 + return false;
  90 + }
  91 + return false;
  92 + },
  93 + IdentityCode_checkParity(card) { //校验位的检测
  94 + card = validateIdent.IdentityCode_changeFivteenToEighteen(card); // 15位转18位
  95 + var len = card.length;
  96 + if (len == '18') {
  97 + var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
  98 + var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
  99 + var cardTemp = 0,
  100 + i, valnum;
  101 + for (i = 0; i < 17; i++) {
  102 + cardTemp += card.substr(i, 1) * arrInt[i];
  103 + }
  104 + valnum = arrCh[cardTemp % 11];
  105 + if (valnum == card.substr(17, 1)) {
  106 + return true;
  107 + }
  108 + return false;
  109 + }
  110 + return false;
  111 + },
  112 + IdentityCode_changeFivteenToEighteen(card) { //15位转18位身份证号
  113 + if (card.length == '15') {
  114 + var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
  115 + var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
  116 + var cardTemp = 0,
  117 + i;
  118 + card = card.substr(0, 6) + '19' + card.substr(6, card.length - 6);
  119 + for (i = 0; i < 17; i++) {
  120 + cardTemp += card.substr(i, 1) * arrInt[i];
  121 + }
  122 + card += arrCh[cardTemp % 11];
  123 + return card;
  124 + }
  125 + return card;
  126 + },
  127 + IdentityCodeValid(card) { // 身份证号码检验主入口
  128 + let pass = true;
  129 + let sex = ''
  130 + //是否为空
  131 + if (pass && card === '')
  132 + pass = false;
  133 + //校验长度,类型
  134 + if (pass && validateIdent.IdentityCode_isCardNo(card) === false)
  135 + pass = false;
  136 + //检查省份
  137 + if (pass && validateIdent.IdentityCode_checkProvince(card) === false)
  138 + pass = false;
  139 + //校验生日
  140 + if (pass && validateIdent.IdentityCode_checkBirthday(card) === false)
  141 + pass = false;
  142 + //检验位的检测
  143 + if (pass && validateIdent.IdentityCode_checkParity(card) === false)
  144 + pass = false;
  145 + if (pass) {
  146 + var iCard = validateIdent.IdentityCode_changeFivteenToEighteen(card);
  147 + if (parseInt(iCard.charAt(16)) % 2 == 0) {
  148 + sex = "0"; // 女生
  149 + } else {
  150 + sex = "1"; // 男生
  151 + }
  152 + return true
  153 + } else {
  154 + return false
  155 + }
  156 + }
  157 +}
  158 +
  159 +export default validateIdent.IdentityCodeValid //导出
0 \ No newline at end of file 160 \ No newline at end of file
src/router/index.js
1 import Vue from 'vue' 1 import Vue from 'vue'
2 import VueRouter from 'vue-router' 2 import VueRouter from 'vue-router'
3 import Home from '@/views/Home/Home.vue' 3 import Home from '@/views/Home/Home.vue'
  4 +import HomeUserInfo from '@/views/Home/HomeUserInfo.vue'
4 5
5 import ServiceAbroadDetail from '@/views/Service/AbroadDetail.vue' 6 import ServiceAbroadDetail from '@/views/Service/AbroadDetail.vue'
6 import ServiceAbroadEvaluate from '@/views/Service/AbroadEvaluate.vue' 7 import ServiceAbroadEvaluate from '@/views/Service/AbroadEvaluate.vue'
@@ -55,7 +56,14 @@ const routes = [{ @@ -55,7 +56,14 @@ const routes = [{
55 title: '红色网上游' 56 title: '红色网上游'
56 } 57 }
57 }, 58 },
58 - 59 + {
  60 + path: '/home_user_info',
  61 + name: 'HomeUserInfo',
  62 + component: HomeUserInfo,
  63 + meta: {
  64 + title: '红色网上游'
  65 + }
  66 + },
59 { 67 {
60 path: '/abroad_detail', 68 path: '/abroad_detail',
61 name: 'ServiceAbroadDetail', 69 name: 'ServiceAbroadDetail',
src/views/Home/Home.vue
@@ -17,18 +17,6 @@ @@ -17,18 +17,6 @@
17 </div> 17 </div>
18 <HomeOrder></HomeOrder> 18 <HomeOrder></HomeOrder>
19 <div class="function"> 19 <div class="function">
20 - <!-- <div class="item" @click="handleGroup">  
21 - <div class="left">  
22 - <van-icon class="icon" name="orders-o" />  
23 - <span>集团权限</span>  
24 - </div>  
25 - <div class="pic">  
26 - <img src="@/assets/home/bg2.png"/>  
27 - <span>已认证</span>  
28 - <van-icon name="arrow" />  
29 - </div>  
30 - <van-icon name="arrow" />  
31 - </div> -->  
32 <div class="item" @click="handleMyCard"> 20 <div class="item" @click="handleMyCard">
33 <div class="left"> 21 <div class="left">
34 <van-icon class="icon" name="discount" /> 22 <van-icon class="icon" name="discount" />
@@ -36,6 +24,13 @@ @@ -36,6 +24,13 @@
36 </div> 24 </div>
37 <van-icon name="arrow" /> 25 <van-icon name="arrow" />
38 </div> 26 </div>
  27 + <div class="item" @click="handleMyInfo">
  28 + <div class="left">
  29 + <van-icon class="icon" name="user-circle-o" />
  30 + <span>个人信息</span>
  31 + </div>
  32 + <van-icon name="arrow" />
  33 + </div>
39 <div class="item" @click="handelElder"> 34 <div class="item" @click="handelElder">
40 <div class="left"> 35 <div class="left">
41 <van-icon class="icon" name="friends-o" /> 36 <van-icon class="icon" name="friends-o" />
@@ -122,6 +117,10 @@ export default { @@ -122,6 +117,10 @@ export default {
122 handleMyCard () { 117 handleMyCard () {
123 this.$router.push({ name: 'CardBoxXST' }) 118 this.$router.push({ name: 'CardBoxXST' })
124 }, 119 },
  120 + // 个人信息
  121 + handleMyInfo () {
  122 + this.$router.push({ name: 'HomeUserInfo' })
  123 + },
125 // 合伙人中心 124 // 合伙人中心
126 handlePartner () { 125 handlePartner () {
127 this.$toast('暂未开放,敬请期待!'); 126 this.$toast('暂未开放,敬请期待!');
@@ -164,7 +163,7 @@ export default { @@ -164,7 +163,7 @@ export default {
164 } 163 }
165 }, 164 },
166 // 获取用户信息 165 // 获取用户信息
167 - getUserInfo: function () { 166 + getUserInfo () {
168 this.mgop({ 167 this.mgop({
169 api: 'mgop.sz.hswsy.getPortalUserByNum', // 必须 168 api: 'mgop.sz.hswsy.getPortalUserByNum', // 必须
170 host: 'https://mapi.zjzwfw.gov.cn/', 169 host: 'https://mapi.zjzwfw.gov.cn/',
@@ -196,7 +195,6 @@ export default { @@ -196,7 +195,6 @@ export default {
196 } 195 }
197 } 196 }
198 this.showChildList = true 197 this.showChildList = true
199 -  
200 }, 198 },
201 onFail: err => { 199 onFail: err => {
202 console.log('err', err) 200 console.log('err', err)
@@ -220,6 +218,7 @@ export default { @@ -220,6 +218,7 @@ export default {
220 //集团回调关闭页面 218 //集团回调关闭页面
221 closeJT () { 219 closeJT () {
222 this.showSchool = false 220 this.showSchool = false
  221 + this.getUserInfo()
223 }, 222 },
224 //查看是否有集团认证 223 //查看是否有集团认证
225 getRZ () { 224 getRZ () {
src/views/Home/HomeUserInfo.vue 0 → 100644
@@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
  1 +<template>
  2 + <div class="home_user_info">
  3 + <van-cell-group>
  4 + <van-cell title="姓名" :value="nickName" />
  5 + <!-- <van-popover v-model="showGenderPopover" trigger="click" :actions="actions" @select="onSelect">
  6 + <template #reference>
  7 + <van-cell title="性别">
  8 + {{gender==1?'男':gender==2?'女':'-'}}
  9 + </van-cell>
  10 + </template>
  11 + </van-popover> -->
  12 +
  13 + <van-cell title="身份证" :value="idCard" />
  14 + <van-cell title="手机号" :value="phone" />
  15 + <van-cell title="关注主学校" :value="schoolNamesChoose" />
  16 + </van-cell-group>
  17 +
  18 + </div>
  19 +</template>
  20 +<script>
  21 +export default {
  22 + data () {
  23 + return {
  24 + nickName: '',//姓名
  25 + gender: '',//性别
  26 + idCard: '',//身份证
  27 + phone: '',//手机号
  28 + schoolNamesChoose: '',//学校
  29 + showGenderPopover:false,
  30 + actions: [{ text: '选项一' }, { text: '选项二' }, { text: '选项三' }],
  31 + }
  32 + },
  33 + mounted () {
  34 + this.centerNo = localStorage.getItem('centerNo');
  35 + const userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
  36 + this.nickName = userInfo.nickName
  37 + this.gender = userInfo.gender
  38 + this.idCard = userInfo.idCard || '-'
  39 + this.phone = userInfo.phone
  40 + this.schoolNamesChoose = sessionStorage.getItem('schoolNamesChoose')
  41 + },
  42 + methods: {
  43 + onSelect(action) {
  44 + Toast(action.text);
  45 + },
  46 + // 获取用户信息
  47 + getUserInfo: function () {
  48 + this.$toast.loading({
  49 + message: '加载中...',
  50 + duration: 0,
  51 + forbidClick: true
  52 + })
  53 + this.mgop({
  54 + api: 'mgop.sz.hswsy.getPortalUserByNum', // 必须
  55 + host: 'https://mapi.zjzwfw.gov.cn/',
  56 + dataType: 'JSON',
  57 + type: 'GET',
  58 + appKey: 'fuxgnukl+2001895516+edccpx', // 必须
  59 + headers: {
  60 + // 'isTestUrl': '1'
  61 + },
  62 + data: {
  63 + "userNum": this.centerNo
  64 + },
  65 + onSuccess: res => {
  66 + this.$toast.clear()
  67 + if (res.data.code == 200) {
  68 + const userInfo = res.data.data.userInfo
  69 + sessionStorage.setItem('userInfo', JSON.stringify(userInfo))
  70 + }
  71 + },
  72 + onFail: err => {
  73 + console.log('err', err)
  74 + }
  75 + });
  76 + },
  77 + }
  78 +}
  79 +</script>
  80 +<style lang="scss">
  81 +.home_user_info {
  82 + height: 100%;
  83 + padding-top: 10px;
  84 + box-sizing: border-box;
  85 + background: rgb(247, 245, 251);
  86 + .van-cell {
  87 + padding: 30px 32px;
  88 + }
  89 +}
  90 +</style>
0 \ No newline at end of file 91 \ No newline at end of file
src/views/Service/AbroadDetail.scss 0 → 100644
@@ -0,0 +1,731 @@ @@ -0,0 +1,731 @@
  1 +.abroad_detail {
  2 + padding-bottom: 200px;
  3 + .header {
  4 + img {
  5 + width: 100%;
  6 + }
  7 + }
  8 + .countDown {
  9 + height: 130px;
  10 + width: 100%;
  11 + background-color: #201e2b;
  12 + .countDownTop {
  13 + height: 50%;
  14 + padding: 0 3vw;
  15 + box-sizing: border-box;
  16 + display: flex;
  17 + justify-content: space-between;
  18 + align-items: center;
  19 + color: #ffffff;
  20 + font-size: 32px;
  21 + .countDownTime {
  22 + font-size: 24px;
  23 + .countDownFont {
  24 + line-height: 34px;
  25 + color: #333333;
  26 + border-radius: 5px;
  27 + margin: 0 8px;
  28 + }
  29 + div {
  30 + width: 34px;
  31 + text-align: center;
  32 + display: inline-block;
  33 + background-color: #ffe9b1;
  34 + }
  35 + }
  36 + }
  37 + .countDownBottom {
  38 + height: 50%;
  39 + padding: 0 3vw;
  40 + box-sizing: border-box;
  41 + display: flex;
  42 + justify-content: space-between;
  43 + align-items: center;
  44 + color: #ffffff;
  45 + font-size: 24px;
  46 + .countDownBottomyellow {
  47 + display: inline-block;
  48 + height: 33px;
  49 + margin-right: 12px;
  50 + padding: 0 8px;
  51 + color: #333333;
  52 + font-size: 24px;
  53 + background-color: #ffe9b1;
  54 + border-radius: 4px;
  55 + }
  56 + .countDownBottomTime {
  57 + font-size: 2.8vw;
  58 + color: #ffffff;
  59 + opacity: 0.85;
  60 + }
  61 + .countDownAbout {
  62 + text-decoration: underline;
  63 + }
  64 + }
  65 + }
  66 + .uni_text {
  67 + width: 100%;
  68 + background: #fff;
  69 + padding: 24px 34px;
  70 + box-sizing: border-box;
  71 + .course_price {
  72 + font-size: 38px;
  73 + font-weight: bold;
  74 + color: red;
  75 + .redmini {
  76 + font-size: 25px;
  77 + }
  78 + .tint {
  79 + font-size: 25px;
  80 + font-weight: normal;
  81 + color: #909399;
  82 + margin-left: 2vw;
  83 + text-decoration: line-through;
  84 + }
  85 + }
  86 + .course_price_free {
  87 + font-size: 34px;
  88 + font-weight: bold;
  89 + color: red;
  90 + display: flex;
  91 + justify-content: space-between;
  92 + .des {
  93 + color: #333;
  94 + }
  95 + }
  96 + .course_coupons {
  97 + height: 70px;
  98 + font-size: 27px;
  99 + // color: #4092FF;
  100 + display: flex;
  101 + justify-content: space-between;
  102 + align-items: center;
  103 + .fontBlue {
  104 + color: #4092ff;
  105 + }
  106 + }
  107 + .course_name {
  108 + font-size: 34px;
  109 + font-weight: bold;
  110 + }
  111 + .course_info {
  112 + font-size: 24px;
  113 + color: #999;
  114 + margin-top: 16px;
  115 + }
  116 + .address {
  117 + font-size: 24px;
  118 + color: #999;
  119 + margin-top: 16px;
  120 + .icon {
  121 + color: #000;
  122 + }
  123 + }
  124 + .rate {
  125 + margin-top: 20px;
  126 + display: flex;
  127 + justify-content: space-between;
  128 + div>span {
  129 + font-size: 30px;
  130 + color: #ffcc00;
  131 + margin-left: 30px;
  132 + }
  133 + >span {
  134 + font-size: 26px;
  135 + }
  136 + }
  137 + .tag_box {
  138 + padding-top: 10px;
  139 + .tag {
  140 + display: inline-block;
  141 + margin-top: 10px;
  142 + margin-right: 12px;
  143 + color: #4092ff;
  144 + font-size: 24px;
  145 + border-radius: 8px;
  146 + border: 2px solid #4092ff;
  147 + padding: 2px 10px;
  148 + }
  149 + }
  150 + }
  151 + .custom_made {
  152 + height: 56px;
  153 + display: flex;
  154 + align-items: center;
  155 + justify-content: space-between;
  156 + padding: 0 24px;
  157 + box-sizing: border-box;
  158 + background: #4D9EFF;
  159 + font-size: 28px;
  160 + color: #fff;
  161 + p {
  162 + width: 610px;
  163 + }
  164 + }
  165 + .package {
  166 + padding: 18px 22px;
  167 + .package_title {
  168 + font-size: 28px;
  169 + color: #999;
  170 + }
  171 + .package_box {
  172 + display: flex;
  173 + white-space: nowrap;
  174 + margin-top: 22px;
  175 + .package_item {
  176 + position: relative;
  177 + width: 128px;
  178 + height: 152px;
  179 + border-radius: 12px;
  180 + border: 2px solid #dde3ef;
  181 + box-sizing: border-box;
  182 + display: inline-flex;
  183 + align-content: center;
  184 + justify-content: center;
  185 + flex-wrap: wrap;
  186 + vertical-align: top;
  187 + margin-right: 16px;
  188 + flex-shrink: 0;
  189 + &.active {
  190 + border-color: #3F92FF;
  191 + .select {
  192 + display: block;
  193 + }
  194 + }
  195 + p {
  196 + width: 100%;
  197 + margin: 0;
  198 + text-align: center;
  199 + }
  200 + .more_icon {
  201 + width: 36px;
  202 + margin-top: 10px;
  203 + }
  204 + .more_text {
  205 + font-size: 22px;
  206 + color: #fff;
  207 + margin-top: 22px;
  208 + }
  209 + .date {
  210 + font-size: 32px;
  211 + font-weight: bold;
  212 + }
  213 + .week {
  214 + font-size: 22px;
  215 + color: #999;
  216 + }
  217 + .price {
  218 + font-size: 28px;
  219 + color: #ff2b2b;
  220 + margin-top: 14px;
  221 + span {
  222 + font-size: 20px;
  223 + }
  224 + }
  225 + .index {
  226 + margin-right: 10px;
  227 + font-size: 26px;
  228 + font-weight: bold;
  229 + color: #333;
  230 + }
  231 + .name {
  232 + margin-top: 8px;
  233 + font-size: 26px;
  234 + white-space: nowrap;
  235 + }
  236 + .select {
  237 + display: none;
  238 + position: absolute;
  239 + bottom: 0;
  240 + right: 0;
  241 + width: 46px;
  242 + height: 48px;
  243 + }
  244 + }
  245 + .package_item_more {
  246 + background: #3f92ff;
  247 + border: 2px solid #3f92ff;
  248 + box-shadow: 6px 12px 16px 0px rgba(63, 146, 255, 0.29);
  249 + margin-right: 0;
  250 + }
  251 + .package_item_type {
  252 + width: auto;
  253 + height: 118px;
  254 + padding: 0 34px;
  255 + .price {
  256 + margin-top: 0;
  257 + }
  258 + }
  259 + }
  260 + .package_des {
  261 + margin-top: 28px;
  262 + font-size: 26px;
  263 + line-height: 40px;
  264 + color: #A9A9AA;
  265 + }
  266 + }
  267 + .notime {
  268 + width: 100%;
  269 + }
  270 + .content_box {
  271 + position: relative;
  272 + .content_all {
  273 + overflow: hidden;
  274 + height: 580px;
  275 + // font-size: 26px;
  276 + // line-height: 36px;
  277 + font-size: 31px !important;
  278 + line-height: 40px !important;
  279 + letter-spacing: 1.6px;
  280 + color: #666;
  281 + // padding-bottom: 130px;
  282 + img {
  283 + width: 100%;
  284 + }
  285 + }
  286 + /* 展开 */
  287 + .open {
  288 + height: auto;
  289 + }
  290 + .extend_wrap {
  291 + display: flex;
  292 + align-items: center;
  293 + justify-content: center;
  294 + font-size: 26px;
  295 + padding: 40px 0;
  296 + color: #4092ff;
  297 + margin-top: -40px;
  298 + background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0.8) 30%, rgba(255, 255, 255, 1) 100%);
  299 + width: 100%;
  300 + position: absolute;
  301 + bottom: 0;
  302 + left: 0;
  303 + }
  304 + }
  305 + .tag_item {
  306 + padding: 22px;
  307 + .tag_title {
  308 + font-size: 34px;
  309 + font-weight: bold;
  310 + margin-bottom: 32px;
  311 + }
  312 + .tag_text {
  313 + // font-size: 24px;
  314 + // line-height: 40px;
  315 + font-size: 28px !important;
  316 + line-height: 44px !important;
  317 + padding: 16px 0;
  318 + }
  319 + }
  320 + .cardCont {
  321 + // font-size: 24px;
  322 + font-size: 28px !important;
  323 + table {
  324 + border-radius: 5px;
  325 + width: 100%;
  326 + border: 1px solid #dde3ef;
  327 + td {
  328 + border: 1px solid #dde3ef;
  329 + text-align: center;
  330 + background: rgb(245, 246, 250);
  331 + }
  332 + .td_left {
  333 + width: 132px;
  334 + background: #fff;
  335 + box-sizing: border-box;
  336 + }
  337 + }
  338 + }
  339 + .courseContent {
  340 + li:not(:last-child) {
  341 + border-bottom: 1px solid #eee;
  342 + }
  343 + li:first-child {
  344 + .left {
  345 + color: #fa9b00;
  346 + border: 1px solid #fa9b00;
  347 + background-color: #fef4d9;
  348 + }
  349 + }
  350 + li:nth-child(3n + 1) {
  351 + .left {
  352 + color: #fa9b00;
  353 + border: 1px solid #fa9b00;
  354 + background-color: #fef4d9;
  355 + }
  356 + }
  357 + li:nth-child(3n-1) {
  358 + .left {
  359 + color: #fa008c;
  360 + border: 1px solid #fa008c;
  361 + background-color: #ffeffc;
  362 + }
  363 + }
  364 + li:nth-child(3n) {
  365 + .left {
  366 + color: #0076fa;
  367 + border: 1px solid #0076fa;
  368 + background-color: #efffff;
  369 + }
  370 + }
  371 + li {
  372 + position: relative;
  373 + margin-top: 20px;
  374 + padding-bottom: 10px;
  375 + .left {
  376 + position: absolute;
  377 + top: 0;
  378 + left: 0;
  379 + width: 120px;
  380 + font-size: 26px;
  381 + text-align: center;
  382 + border-radius: 3px;
  383 + padding: 3px;
  384 + box-sizing: border-box;
  385 + font-weight: 600;
  386 + }
  387 + h3 {
  388 + color: #202228;
  389 + // font-size: 32px;
  390 + font-size: 30px !important;
  391 + font-weight: 400;
  392 + margin: 0;
  393 + padding-left: 160px;
  394 + word-break: break-all;
  395 + }
  396 + .item {
  397 + margin-top: 10px;
  398 + img {
  399 + width: 100%;
  400 + }
  401 + p {
  402 + margin: 0;
  403 + margin-top: 10px;
  404 + color: #a7a7aa;
  405 + // font-size: 28px;
  406 + font-size: 31px !important;
  407 + b {
  408 + // font-size: 32px;
  409 + font-size: 35px !important;
  410 + font-weight: 400;
  411 + color: #000000;
  412 + margin-right: 10px;
  413 + }
  414 + span {
  415 + // font-size: 24px;
  416 + font-size: 27px !important;
  417 + }
  418 + }
  419 + }
  420 + }
  421 + }
  422 + .base {
  423 + padding: 28px 24px;
  424 + img {
  425 + width: 98px;
  426 + height: 98px;
  427 + display: inline-block;
  428 + vertical-align: top;
  429 + border-radius: 12px;
  430 + }
  431 + .center {
  432 + width: 550px;
  433 + display: inline-block;
  434 + margin-left: 20px;
  435 + .basename {
  436 + // font-size: 32px;
  437 + font-size: 35px !important;
  438 + font-weight: bold;
  439 + }
  440 + .address {
  441 + // font-size: 24px;
  442 + font-size: 27px !important;
  443 + margin-top: 12px;
  444 + }
  445 + .tag {
  446 + display: inline-block;
  447 + // font-size: 24px;
  448 + font-size: 26px !important;
  449 + margin-top: 14px;
  450 + background: #f5f6fa;
  451 + border-radius: 6px;
  452 + padding: 6px 20px;
  453 + }
  454 + }
  455 + }
  456 + .top_border {
  457 + border-top: 16px solid #f6f7fa;
  458 + ::v-deep.van-tab {
  459 + .van-tab__text {
  460 + font-size: 34px !important;
  461 + }
  462 + }
  463 + }
  464 + .popup_content {
  465 + width: 408px;
  466 + height: 346px;
  467 + overflow: hidden;
  468 + img {
  469 + display: block;
  470 + width: 86px;
  471 + height: 86px;
  472 + margin: 0 auto;
  473 + margin-top: 64px;
  474 + }
  475 + p:first-of-type {
  476 + text-align: center;
  477 + margin-top: 46px;
  478 + // font-size: 36px;
  479 + font-size: 39px !important;
  480 + }
  481 + p:last-of-type {
  482 + text-align: center;
  483 + margin-top: 16px;
  484 + // font-size: 26px;
  485 + font-size: 29px !important;
  486 + color: #999;
  487 + }
  488 + }
  489 + .Collection {
  490 + background-color: white;
  491 + position: fixed;
  492 + bottom: 0;
  493 + left: 0;
  494 + width: 100%;
  495 + padding: 28px 22px;
  496 + box-sizing: border-box;
  497 + padding-bottom: 50px;
  498 + z-index: 500;
  499 + box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.34);
  500 + .box1 {
  501 + width: 40%;
  502 + }
  503 + .box2 {
  504 + width: 60%;
  505 + }
  506 + .box {
  507 + display: inline-block;
  508 + vertical-align: middle;
  509 + color: #666666;
  510 + .icon {
  511 + display: inline-block;
  512 + width: 45%;
  513 + text-align: center;
  514 + // font-size: 24px;
  515 + font-size: 26px !important;
  516 + p {
  517 + // margin: 0;
  518 + color: #999999;
  519 + margin-top: 8px;
  520 + }
  521 + i {
  522 + font-size: 48px;
  523 + color: rgb(45, 45, 45);
  524 + font-weight: bold;
  525 + }
  526 + }
  527 + .icon.active {
  528 + color: 0ce39d;
  529 + i {
  530 + color: #0ce39d;
  531 + }
  532 + }
  533 + span {
  534 + display: inline-block;
  535 + width: 100%;
  536 + line-height: 92px;
  537 + box-sizing: border-box;
  538 + border-radius: 100px;
  539 + color: white;
  540 + // font-size: 32px;
  541 + font-size: 35px !important;
  542 + background: #4092ff;
  543 + text-align: center;
  544 + box-shadow: 0px 10px 40px 0px #a0c9ff;
  545 + b {
  546 + display: inline-block;
  547 + vertical-align: middle;
  548 + margin-left: 20px;
  549 + color: white;
  550 + }
  551 + i {
  552 + vertical-align: middle;
  553 + font-size: 44px;
  554 + font-weight: bold;
  555 + }
  556 + }
  557 + .disabled {
  558 + color: #999;
  559 + background: #edeced;
  560 + box-shadow: none;
  561 + }
  562 + }
  563 + }
  564 + .pintuan_about {
  565 + width: 592px;
  566 + box-sizing: border-box;
  567 + padding: 0 50px;
  568 + .about_img {
  569 + width: 112px;
  570 + margin: 0 auto;
  571 + margin-top: 30px;
  572 + display: block;
  573 + }
  574 + .about_title {
  575 + font-size: 34px;
  576 + font-weight: bold;
  577 + text-align: center;
  578 + }
  579 + .about_content {
  580 + font-size: 30px;
  581 + margin-top: 20px;
  582 + }
  583 + .about_know {
  584 + font-size: 32px;
  585 + text-align: center;
  586 + color: #3385ff;
  587 + margin-top: 60px;
  588 + margin-bottom: 44px;
  589 + }
  590 + }
  591 + .show_tip_title {
  592 + img {
  593 + width: 112px;
  594 + }
  595 + p {
  596 + margin-top: -20px;
  597 + margin-bottom: 20px;
  598 + }
  599 + }
  600 + .show_tip {
  601 + padding: 0 20px;
  602 + font-size: 28px;
  603 + letter-spacing: 1px;
  604 + text-align: left;
  605 + line-height: 64px;
  606 + color: rgb(153, 153, 153);
  607 + b {
  608 + color: #000;
  609 + }
  610 + }
  611 + .tip_checkbox {
  612 + font-size: 26px;
  613 + margin-top: 24px;
  614 + margin-bottom: 60px;
  615 + margin-left: 50px;
  616 + }
  617 +}
  618 +
  619 +.elder {
  620 + .abroad_detail {
  621 + .countDown {
  622 + height: auto;
  623 + .countDownTop {
  624 + display: block;
  625 + font-size: 40px;
  626 + .countDownTime {
  627 + font-size: 40px;
  628 + padding: 10px 0;
  629 + div {
  630 + width: 60px;
  631 + }
  632 + .countDownFont {
  633 + line-height: 60px;
  634 + }
  635 + }
  636 + }
  637 + .countDownBottom {
  638 + display: block;
  639 + font-size: 40px;
  640 + .countDownBottomyellow {
  641 + height: 60px;
  642 + font-size: 40px;
  643 + }
  644 + }
  645 + }
  646 + .uni_text {
  647 + .course_price {
  648 + font-size: 48px;
  649 + .redmini,
  650 + .tint {
  651 + font-size: 36px;
  652 + }
  653 + }
  654 + .course_name {
  655 + font-size: 44px;
  656 + }
  657 + .course_info {
  658 + font-size: 40px;
  659 + }
  660 + .address {
  661 + font-size: 40px;
  662 + }
  663 + .rate>span {
  664 + font-size: 36px;
  665 + }
  666 + .tag_box .tag {
  667 + font-size: 40px;
  668 + }
  669 + }
  670 + .package {
  671 + .package_title {
  672 + font-size: 44px;
  673 + }
  674 + .package_item {
  675 + .date {
  676 + font-size: 40px;
  677 + }
  678 + .week {
  679 + font-size: 34px;
  680 + }
  681 + .price {
  682 + font-size: 34px;
  683 + }
  684 + }
  685 + }
  686 + .content_box .content_all {
  687 + font-size: 40px !important;
  688 + line-height: 60px !important;
  689 + }
  690 + .tag_item {
  691 + .tag_title {
  692 + font-size: 44px;
  693 + }
  694 + .tag_text {
  695 + font-size: 40px !important;
  696 + line-height: 60px !important;
  697 + }
  698 + }
  699 + .base .center {
  700 + .basename {
  701 + font-size: 44px !important;
  702 + }
  703 + .address {
  704 + font-size: 40px !important;
  705 + }
  706 + }
  707 + .Collection .box {
  708 + span {
  709 + font-size: 44px !important;
  710 + }
  711 + .icon {
  712 + font-size: 40px !important;
  713 + }
  714 + }
  715 + .pintuan_about {
  716 + .about_title {
  717 + font-size: 44px;
  718 + }
  719 + .about_box {
  720 + height: 600px;
  721 + overflow: auto;
  722 + }
  723 + .about_content {
  724 + font-size: 36px;
  725 + }
  726 + .about_know {
  727 + font-size: 40px;
  728 + }
  729 + }
  730 + }
  731 +}
0 \ No newline at end of file 732 \ No newline at end of file
src/views/Service/AbroadDetail.vue
@@ -10,47 +10,19 @@ @@ -10,47 +10,19 @@
10 <img v-else src="@/assets/service/defCoure.jpg" alt="" /> 10 <img v-else src="@/assets/service/defCoure.jpg" alt="" />
11 </div> 11 </div>
12 <!--倒计时--> 12 <!--倒计时-->
13 - <div class="countDown" v-show="detailData.clusterTime && timeTamp * 1 > 0">  
14 - <div class="countDownTop">  
15 - <div>{{packageArr[0]?packageArr[0].day:''}} {{detailData.applyCount>=detailData.minPeopleCount?'报名截止时间:':'团期截止倒计时'}}</div>  
16 - <div v-if="detailData.applyCount>=detailData.minPeopleCount">{{detailData.periodOfValidity}}</div>  
17 - <div class="countDownTime" v-else>  
18 - <div class="countDownFont">{{ showTime.day }}</div>  
19 - 天  
20 - <div class="countDownFont">{{ showTime.hour }}</div>  
21 - 时  
22 - <div class="countDownFont">{{ showTime.minute }}</div>  
23 - 分  
24 - <div class="countDownFont">{{ showTime.second }}</div>  
25 - 秒  
26 - </div>  
27 - </div>  
28 - <div class="countDownBottom">  
29 - <div>  
30 - <div class="countDownBottomyellow" v-show="detailData.minPeopleCount">  
31 - {{ detailData.clusterName }}  
32 - </div>  
33 - <span v-if="detailData.applyCount>=detailData.minPeopleCount">已报名 {{detailData.applyCount}}/{{detailData.stockCount}}人</span>  
34 - <span v-else>最低成团数{{detailData.minPeopleCount}}人/已报名{{detailData.applyCount}}人</span>  
35 - <!-- 已报名:<span>{{ detailData.applyCount }}</span><span>/{{ detailData.stockCount }}</span> -->  
36 - </div>  
37 - <div class="countDownAbout" @click="showPintuanAbout=true">关于拼团?</div>  
38 - </div>  
39 - </div>  
40 - <div class="uni_text">  
41 - <!-- <div class="course_price" v-if="detailData.showPrice!=0">  
42 - <span>¥ {{ detailData.showPrice }}</span><span class="redmini">起</span><span class="tint">{{ detailData.productPrice }}</span> 13 + <count-down v-if="detailData&&packageArr[packageActive]" :productId="detailData.id" :packageArr="packageArr" :day="packageArr[packageActive].day" :bindId="packageArr[packageActive].comboInfoList[packageTypeActive].bindId" :comboId="packageArr[packageActive].comboInfoList[packageTypeActive].id"></count-down>
  14 +
  15 + <div class="uni_text" v-if="initPackageArr">
  16 + <!-- <div class="course_price" v-if="packageArr.length>0">
  17 + <span>¥ {{ detailData.showPrice }}</span><span class="redmini">起/{{detailData.unitName}}</span><span class="tint">{{ detailData.productPrice }}</span>
43 </div> 18 </div>
44 <div class="course_price_free" v-else> 19 <div class="course_price_free" v-else>
45 <span>¥ {{ detailData.price }}</span> 20 <span>¥ {{ detailData.price }}</span>
46 <span class="des">正在排期</span> 21 <span class="des">正在排期</span>
47 </div> --> 22 </div> -->
48 - <div class="course_coupons" v-if="proCoupon.length>0">  
49 - <div>  
50 - <van-tag v-for="(item,index) in proCoupon" :key="index" color="#ffffff" text-color="#FF2B2B">{{proCouponHas?'已领取:':''}}{{item.title}}</van-tag>  
51 - </div>  
52 - <div @click="toCoupons" class="fontBlue">领取 ></div>  
53 - </div> 23 + <!-- 优惠券 -->
  24 + <abroad-coupon v-if="detailData&&centerNo" :detailDataId="detailData.id" :centerNo="centerNo"></abroad-coupon>
  25 +
54 <p class="course_name">{{ detailData.course_name }}</p> 26 <p class="course_name">{{ detailData.course_name }}</p>
55 <p class="course_info">{{ detailData.course_info }}</p> 27 <p class="course_info">{{ detailData.course_info }}</p>
56 <p class="address" v-if="detailData.provinceAddress"> 28 <p class="address" v-if="detailData.provinceAddress">
@@ -63,15 +35,9 @@ @@ -63,15 +35,9 @@
63 detailData.addressDetail 35 detailData.addressDetail
64 }} 36 }}
65 </p> 37 </p>
66 - <div class="rate" @click="handleEvaluate">  
67 - <div>  
68 - <van-rate v-model="evaluationData.evaluationScore" color="#FFCC00" :size="16" readonly />  
69 - <span>{{ evaluationData.evaluationScore }}</span>  
70 - </div>  
71 - <span>共{{evaluationData.evaluationCount}}个客户评价  
72 - <van-icon name="arrow" />  
73 - </span>  
74 - </div> 38 + <!-- 商品评价 -->
  39 + <abroad-evaluate v-if="courseId" :courseId="courseId"></abroad-evaluate>
  40 + <!-- 商品标签 -->
75 <div class="tag_box"> 41 <div class="tag_box">
76 <template v-for="(tag, index) in detailData.course_labels"> 42 <template v-for="(tag, index) in detailData.course_labels">
77 <span class="tag" v-if="tag != ''" :key="index">{{ tag }}</span> 43 <span class="tag" v-if="tag != ''" :key="index">{{ tag }}</span>
@@ -81,94 +47,39 @@ @@ -81,94 +47,39 @@
81 <div class="package top_border"> 47 <div class="package top_border">
82 <p class="package_title">套餐类型/日期</p> 48 <p class="package_title">套餐类型/日期</p>
83 <div class="package_box" v-if="packageArr.length>0"> 49 <div class="package_box" v-if="packageArr.length>0">
84 - <div class="package_item" v-for="(item, index) in packageArr" :key="index" @click="checkDatePackage(item.date)">  
85 - <p class="date">{{ item.day }}</p>  
86 - <p class="week">{{ item.week }}</p>  
87 - <!-- <p class="price"><span>¥</span>{{ item.marketPrice }}</p> --> 50 + <div style="overflow:auto;">
  51 + <div class="package_item" :class="packageActive==index?'active':''" v-for="(item, index) in packageArr" :key="index" @click="handlePackageDay(index)">
  52 + <p class="date">{{ item.day }}</p>
  53 + <p class="week">{{ item.week }}</p>
  54 + <p class="price"><span>¥</span>{{ item.marketPrice }}<span class="des">起</span></p>
  55 + <img class="select" src="@/assets/service/select.png" alt="" />
  56 + </div>
88 </div> 57 </div>
89 - <div class="package_item package_item_more" @click="checkDatePackage()" v-if="packageArr.length > 3"> 58 + <div class="package_item package_item_more" @click="checkDatePackage()" v-if="packageArr.length>5">
90 <img class="more_icon" src="@/assets/service/more.png" alt="" /> 59 <img class="more_icon" src="@/assets/service/more.png" alt="" />
91 <p class="more_text">查看更多</p> 60 <p class="more_text">查看更多</p>
92 </div> 61 </div>
93 </div> 62 </div>
  63 + <img class="notime" v-if="packageArr.length==0" src="@/assets/service/notime.png" alt="">
94 </div> 64 </div>
95 - <img class="notime" v-if="packageArr.length==0" src="@/assets/service/notime.png" alt="">  
96 -  
97 - <van-tabs class="tabs top_border" v-model="active" swipeable :ellipsis="false" color="#4092FF" scrollspy sticky>  
98 - <van-tab title="产品详情">  
99 - <div class="tag_item" v-if="detailData.productFeatures">  
100 - <p class="tag_title">产品特色</p>  
101 - <p class="tag_text" v-html="detailData.productFeatures"></p>  
102 - </div>  
103 - <div class="tag_item" v-if="detailData.productDescription">  
104 - <p class="tag_title">产品描述</p>  
105 - <div class="content_box">  
106 - <div class="content_all" :class="isOpen ? 'open' : ''">  
107 - <p v-html="detailData.productDescription"></p>  
108 - </div>  
109 - </div>  
110 - </div>  
111 - <div class="tag_item" v-if="  
112 - detailData.courseContentList &&  
113 - detailData.courseContentList[0].content != ''  
114 - ">  
115 - <p class="tag_title">服务内容</p>  
116 - <ul class="courseContent">  
117 - <li v-for="(n, i) in detailData.courseContentList" :key="n.id">  
118 - <span class="left" v-if="n.title">{{ n.title }}</span>  
119 - <h3>{{ n.content }}</h3>  
120 - <div class="item" v-for="(k, j) in n.courseFileList" :key="i + '' + j">  
121 - <div>  
122 - <video v-if="k.url && k.url.indexOf('.mp4') > -1" id="video" :src="k.url" poster="" controls="controls" windowlessvideo="true" playsinline="true" webkit-playsinline="true" x5-playsinline="true" x-webkit-airplay="allow" width="100%" height="260px" type="video/mp4"></video>  
123 - </div>  
124 - <div>  
125 - <img v-if="k.url && k.url.indexOf('.mp4') == -1" :src="k.url" />  
126 - </div>  
127 - </div>  
128 - </li>  
129 - </ul>  
130 - </div>  
131 - <div class="tag_item" v-if="courseTable.length > 0 && showCourseTable">  
132 - <p class="tag_title">课程表</p>  
133 - <div class="cardCont" v-for="(item, index) in courseTable" :key="index">  
134 - <table cellspacing="0" cellpadding="8">  
135 - <tbody v-html="item"></tbody>  
136 - </table> 65 + <div class="package top_border" v-if="packageArr.length>0&&packageArr[packageActive].comboInfoList.length>1">
  66 + <div class="package_box">
  67 + <div style="overflow:auto;">
  68 + <div class="package_item package_item_type" :class="packageTypeActive==index?'active':''" v-for="(item, index) in packageArr[packageActive].comboInfoList" :key="index" @click="packageTypeActive=index">
  69 + <p class="price"><span class="index">套餐{{index+1}}</span><span>¥</span>{{ item.actualPrice }}</p>
  70 + <p class="name">{{item.comboName}}</p>
  71 + <img class="select" src="@/assets/service/select.png" alt="" />
137 </div> 72 </div>
138 </div> 73 </div>
139 - <div class="tag_item" v-if="detailData.extraService">  
140 - <p class="tag_title">附送服务</p>  
141 - <p class="tag_text" v-html="detailData.extraService"></p>  
142 - </div>  
143 - <div class="tag_item" v-if="detailData.serviceGuarantees">  
144 - <p class="tag_title">服务保障和承诺</p>  
145 - <p class="tag_text" v-html="detailData.serviceGuarantees"></p>  
146 - </div>  
147 - </van-tab>  
148 - <van-tab title="费用说明" v-if="detailData.feeDescription">  
149 - <div class="tag_item">  
150 - <p class="tag_title">费用说明</p>  
151 - <p class="tag_text" v-html="detailData.feeDescription"></p>  
152 - </div>  
153 - </van-tab>  
154 - <van-tab title="订购须知" v-if="detailData.notice">  
155 - <div class="tag_item">  
156 - <p class="tag_title">订购须知</p>  
157 - <p class="tag_text" v-html="detailData.notice"></p>  
158 - </div>  
159 - </van-tab>  
160 - </van-tabs>  
161 - <div class="base top_border" v-if="baseData">  
162 - <img v-if="baseData.coverList.length > 0" :src="baseData.coverList[0].cover_url" alt="" />  
163 - <div class="center">  
164 - <p class="basename">{{ baseData.baseName }}</p>  
165 - <p class="address">  
166 - <van-icon name="location-o" />{{ baseData.city }}{{ baseData.area  
167 - }}{{ baseData.address }}  
168 - </p>  
169 - <p class="tag">{{ baseData.baseLabel.join("/") }}</p>  
170 </div> 74 </div>
  75 + <!-- 套餐说明 -->
  76 + <p class="package_des" v-if="packageArr[packageActive]&&packageArr[packageActive].comboInfoList[packageTypeActive].comboDescrption">套餐说明<br>{{packageArr[packageActive].comboInfoList[packageTypeActive].comboDescrption}}</p>
171 </div> 77 </div>
  78 + <!-- 商品详情 -->
  79 + <abroad-des v-if="detailData" :detailData="detailData"></abroad-des>
  80 + <!-- 基地信息 -->
  81 + <abroad-base v-if="detailData" :baseId="detailData.baseId"></abroad-base>
  82 +
172 <div class="Collection"> 83 <div class="Collection">
173 <div class="box box1"> 84 <div class="box box1">
174 <div class="icon" @click="backHome"> 85 <div class="icon" @click="backHome">
@@ -186,23 +97,10 @@ @@ -186,23 +97,10 @@
186 </div> 97 </div>
187 <div class="box box2"> 98 <div class="box box2">
188 <span v-if="packageArr.length > 0&&detailData.applyCount>=detailData.stockCount" class="disabled">已满团</span> 99 <span v-if="packageArr.length > 0&&detailData.applyCount>=detailData.stockCount" class="disabled">已满团</span>
189 - <span v-else-if="packageArr.length > 0" @click="checkDatePackage(packageArr[0].date)">去订购</span> 100 + <span v-else-if="packageArr.length > 0" @click="checkDatePackage()">去订购</span>
190 <span v-else class="disabled">拼团请咨询客服</span> 101 <span v-else class="disabled">拼团请咨询客服</span>
191 </div> 102 </div>
192 </div> 103 </div>
193 - <van-popup v-model="showPintuanAbout" round>  
194 - <div class="pintuan_about">  
195 - <img class="about_img" src="@/assets/service/tip.png" alt="">  
196 - <p class="about_title">拼团规则说明</p>  
197 - <div class="about_box">  
198 - <p class="about_content">1、拼团展示默认为最近活动档期,选择其它档期请时刻注意成团动态。</p>  
199 - <p class="about_content">2、在限时截止后,报名人数未达最低成团数,则结束本团活动,系统将在72小时内,全额退还!</p>  
200 - <p class="about_content">3、报名人数达到最低成团要求后,则拼团成功,凡在报名截止时间内未达最大限团人数,则可放心参与。</p>  
201 - <p class="about_content">4、已成团的活动,除特殊情况等不可抗拒因素外,活动如期举行。</p>  
202 - </div>  
203 - <p class="about_know" @click="showPintuanAbout=false">我知道了</p>  
204 - </div>  
205 - </van-popup>  
206 <van-dialog v-model="showTip" title="温馨提示" show-cancel-button confirm-button-color="#3385FF" cancel-button-color="#999" confirm-button-text="同意" cancel-button-text="再想想" @confirm="tipConfirm"> 104 <van-dialog v-model="showTip" title="温馨提示" show-cancel-button confirm-button-color="#3385FF" cancel-button-color="#999" confirm-button-text="同意" cancel-button-text="再想想" @confirm="tipConfirm">
207 <div class="show_tip_title" slot="title"> 105 <div class="show_tip_title" slot="title">
208 <img src="@/assets/service/tip.png" alt=""> 106 <img src="@/assets/service/tip.png" alt="">
@@ -214,31 +112,25 @@ @@ -214,31 +112,25 @@
214 </div> 112 </div>
215 </template> 113 </template>
216 <script> 114 <script>
  115 +import AbroadDes from './component/AbroadDetail/AbroadDes';
  116 +import AbroadBase from './component/AbroadDetail/AbroadBase';
  117 +import AbroadEvaluate from './component/AbroadDetail/AbroadEvaluate';
  118 +import CountDown from './component/AbroadDetail/CountDown';
  119 +import AbroadCoupon from './component/AbroadDetail/AbroadCoupon';
  120 +import './AbroadDetail.scss';
217 export default { 121 export default {
218 name: "ServiceAbroadDetail", 122 name: "ServiceAbroadDetail",
219 data () { 123 data () {
220 return { 124 return {
221 - isOpen: true,  
222 courseId: "", 125 courseId: "",
223 detailData: "", 126 detailData: "",
224 - active: 0,  
225 - courseTable: [], //课程表  
226 packageData: [], //未处理过格式的套餐表 127 packageData: [], //未处理过格式的套餐表
  128 + packageActive: 0,
  129 + packageTypeActive: 0,
227 packageArr: [], //套餐时间价格 130 packageArr: [], //套餐时间价格
228 - evaluationData: '',//评价  
229 - baseData: "", //基地信息 131 + initPackageArr: false,//packageArr已生成
230 showCourseTable: true, 132 showCourseTable: true,
231 - showTime: {  
232 - day: "",  
233 - hour: "",  
234 - minute: "",  
235 - second: "",  
236 - },  
237 - timeTamp: "",  
238 unionId: '', 133 unionId: '',
239 - proCoupon: [],//优惠券  
240 - proCouponHas: false,//优惠券已领取  
241 - showPintuanAbout: false,  
242 centerNo: '', 134 centerNo: '',
243 showTip: false, 135 showTip: false,
244 PackageQuery: '', 136 PackageQuery: '',
@@ -252,69 +144,42 @@ export default { @@ -252,69 +144,42 @@ export default {
252 this.GetCourseDetail(); 144 this.GetCourseDetail();
253 }, 145 },
254 methods: { 146 methods: {
255 - // 展开关闭院校简介  
256 - extend_btn () {  
257 - this.isOpen = !this.isOpen;  
258 - },  
259 - //倒计时计算  
260 - timeDown () {  
261 - var clusterTime = Date.parse(new Date(this.detailData.clusterTime.replace(/\-/g, "/"))) + 60 * 60 * 24 * 1000;  
262 - var nowTime = Date.parse(new Date());  
263 - let timeTamp = clusterTime / 1000 - nowTime / 1000;  
264 - // console.log(timeTamp)  
265 - this.timeTamp = timeTamp;  
266 - // console.log(timeTamp)  
267 - let k = this.calculateDiffTime(timeTamp);  
268 - // console.log(k) 147 + // 点击套餐日期
  148 + handlePackageDay (index) {
  149 + this.packageActive = index;
  150 + this.packageTypeActive = 0;//重置套餐类型选择
  151 + //TODO 获取该日所包含的套餐
269 }, 152 },
270 - calculateDiffTime (timeDiff) {  
271 - var day = parseInt(timeDiff / 86400);  
272 - var hour = parseInt((timeDiff % 86400) / 3600);  
273 - var minute = parseInt(((timeDiff % 86400) % 3600) / 60);  
274 - var second = parseInt((((timeDiff % 86400) % 3600) % 60) % 60);  
275 153
276 - this.showTime = {  
277 - day,  
278 - hour,  
279 - minute,  
280 - second,  
281 - };  
282 - day = day ? day + "天" : "";  
283 - hour = hour ? hour + "时" : "";  
284 - minute = minute ? minute + "分" : "";  
285 - second = second ? second + "秒" : "";  
286 - return day + hour + minute + second;  
287 - },  
288 // 点击预约 154 // 点击预约
289 - checkDatePackage (date) {  
290 -  
291 - if (this.packageArr[0].date == date)  
292 - if (this.detailData.applyCount >= this.detailData.stockCount && this.packageArr[0].date == date) {  
293 - this.$toast('已满团')  
294 - return;  
295 - }  
296 - let query = {};  
297 - if (date || date === 0) {  
298 - query = { date: date };  
299 - } 155 + checkDatePackage () {
  156 + // if (this.packageArr[0].date == date) {
  157 + // if (this.detailData.applyCount >= this.detailData.stockCount && this.packageArr[0].date == date) {
  158 + // this.$toast('已满团')
  159 + // return;
  160 + // }
  161 + // }
  162 + const tagIndex = this.packageArr[this.packageActive].comboInfoList[this.packageTypeActive].tagIndex
  163 + console.log(this.packageArr[this.packageActive])
  164 + let query = { date: this.packageArr[this.packageActive].date, Index1: tagIndex[0], Index2: tagIndex[1] };
300 this.PackageQuery = query 165 this.PackageQuery = query
301 const AbroadDetailTipChecked = sessionStorage.getItem('AbroadDetailTipChecked'); 166 const AbroadDetailTipChecked = sessionStorage.getItem('AbroadDetailTipChecked');
302 - if(AbroadDetailTipChecked){ 167 + if (AbroadDetailTipChecked) {
303 this.$router.push({ name: "ServiceDatePackage", query: query }); 168 this.$router.push({ name: "ServiceDatePackage", query: query });
304 - }else{ 169 + } else {
305 this.showTip = true; 170 this.showTip = true;
306 } 171 }
307 }, 172 },
308 tipConfirm () { 173 tipConfirm () {
309 - if(this.tipChecked){  
310 - sessionStorage.setItem('AbroadDetailTipChecked',1) 174 + if (this.tipChecked) {
  175 + sessionStorage.setItem('AbroadDetailTipChecked', 1)
311 } 176 }
312 this.$router.push({ name: "ServiceDatePackage", query: this.PackageQuery }); 177 this.$router.push({ name: "ServiceDatePackage", query: this.PackageQuery });
313 }, 178 },
314 - // 获取品详情 179 + // 获取品详情
315 GetCourseDetail () { 180 GetCourseDetail () {
316 if (!this.courseId) { 181 if (!this.courseId) {
317 - this.$toast.fail('品id缺失,请从正确的途径访问') 182 + this.$toast.fail('品id缺失,请从正确的途径访问')
318 return; 183 return;
319 } 184 }
320 this.$toast.loading({ 185 this.$toast.loading({
@@ -339,7 +204,7 @@ export default { @@ -339,7 +204,7 @@ export default {
339 this.$toast.clear(); 204 this.$toast.clear();
340 if (res.data.data && res.data.data.id !== 0) { 205 if (res.data.data && res.data.data.id !== 0) {
341 let detailData = res.data.data; 206 let detailData = res.data.data;
342 - // console.log(detailData) 207 + console.log('产品详情:', detailData)
343 detailData.course_labels = detailData.course_labels?.split(","); 208 detailData.course_labels = detailData.course_labels?.split(",");
344 this.detailData = detailData; 209 this.detailData = detailData;
345 localStorage.setItem( 210 localStorage.setItem(
@@ -352,21 +217,6 @@ export default { @@ -352,21 +217,6 @@ export default {
352 }) 217 })
353 ); 218 );
354 this.getPackageData(); //获取套餐列表 219 this.getPackageData(); //获取套餐列表
355 - this.getOrderCoupon(); //获取商品可使用优惠券  
356 - this.getEvaluationSummary();//获取评价  
357 - let timer = setInterval(() => {  
358 - this.timeDown(); //倒计时  
359 - }, 1000);  
360 - this.$once("hook:beforeDestroy", () => {  
361 - clearInterval(timer); //清理定时器  
362 - });  
363 - this.$nextTick(() => {  
364 - this.GetOneBase(detailData.baseId); //获取单个基地  
365 - // this.setPackageArr();//设置套餐  
366 - for (let i in detailData.courseScheduleList) {  
367 - this.getWeekCard(i);  
368 - }  
369 - });  
370 } else { 220 } else {
371 let message = res.data.message; 221 let message = res.data.message;
372 if (!message) { 222 if (!message) {
@@ -380,82 +230,7 @@ export default { @@ -380,82 +230,7 @@ export default {
380 } 230 }
381 }); 231 });
382 }, 232 },
383 - //获取商品可使用优惠券  
384 - getOrderCoupon () {  
385 - this.mgop({  
386 - api: 'mgop.sz.hswsy.orderCoupon', // 必须  
387 - host: 'https://mapi.zjzwfw.gov.cn/',  
388 - dataType: 'JSON',  
389 - type: 'POST',  
390 - appKey: 'fuxgnukl+2001895516+edccpx', // 必须  
391 - headers: {  
392 - // 'isTestUrl': '1'  
393 - },  
394 - data: {  
395 - "proId": this.detailData.id,  
396 - "userId": this.centerNo,  
397 - },  
398 - onSuccess: res => {  
399 - if (res.data.data) {  
400 - if (res.data.data.has.length > 0) {  
401 - this.proCoupon = res.data.data.has  
402 - localStorage.setItem("proCoupon", JSON.stringify(this.proCoupon))  
403 - this.chooseDefaultUseCard(res.data.data.has)//设置默认选中的优惠券  
404 - this.proCouponHas = true;  
405 - } else if (res.data.data.get.length > 0) {  
406 - this.proCoupon = {  
407 - title: '您有可领优惠券'  
408 - }  
409 - }  
410 - }  
411 - },  
412 - onFail: err => {  
413 - console.log('err', err)  
414 - }  
415 - });  
416 - },  
417 - // 设置默认选中的优惠券  
418 - chooseDefaultUseCard (has) {  
419 - if (has.length > 1) {  
420 - let useCard = has[0];  
421 - for (let i in has) {  
422 - console.log(Number(has[i].couponPrice) > Number(useCard.couponPrice))  
423 - if (Number(has[i].couponPrice) > Number(useCard.couponPrice)) {  
424 - useCard = has[i]  
425 - }  
426 - }  
427 - // console.log('useCard', useCard)  
428 - this.proCoupon = [useCard]  
429 - localStorage.setItem('useCard', JSON.stringify(useCard))  
430 233
431 - } else {  
432 - localStorage.setItem('useCard', JSON.stringify(this.proCoupon[0]))  
433 - }  
434 - },  
435 - // 获取评价  
436 - getEvaluationSummary () {  
437 - this.mgop({  
438 - api: 'mgop.sz.hswsy.EvaluationSummary', // 必须  
439 - host: 'https://mapi.zjzwfw.gov.cn/',  
440 - dataType: 'JSON',  
441 - type: 'GET',  
442 - appKey: 'fuxgnukl+2001895516+edccpx', // 必须  
443 - headers: {  
444 - // 'isTestUrl': '1'  
445 - },  
446 - data: {  
447 - "courseId": this.courseId,  
448 - },  
449 - onSuccess: res => {  
450 - if (res.data.data) {  
451 - this.evaluationData = res.data.data  
452 - }  
453 - },  
454 - onFail: err => {  
455 - console.log('err', err)  
456 - }  
457 - });  
458 - },  
459 // 获取套餐列表 234 // 获取套餐列表
460 getPackageData () { 235 getPackageData () {
461 let startDate = this.Moment().format("YYYY-MM-DD"); 236 let startDate = this.Moment().format("YYYY-MM-DD");
@@ -475,6 +250,7 @@ export default { @@ -475,6 +250,7 @@ export default {
475 "endDate": endDate, 250 "endDate": endDate,
476 }, 251 },
477 onSuccess: res => { 252 onSuccess: res => {
  253 + console.log('套餐列表:', res.data.data);
478 if (res.data.data) { 254 if (res.data.data) {
479 let allPackage = res.data.data; 255 let allPackage = res.data.data;
480 let usefulPackage = []; 256 let usefulPackage = [];
@@ -483,7 +259,6 @@ export default { @@ -483,7 +259,6 @@ export default {
483 usefulPackage.push(allPackage[i]); 259 usefulPackage.push(allPackage[i]);
484 } 260 }
485 } 261 }
486 - console.log(usefulPackage);  
487 this.packageData = usefulPackage; 262 this.packageData = usefulPackage;
488 localStorage.setItem( 263 localStorage.setItem(
489 "packageData", 264 "packageData",
@@ -499,7 +274,7 @@ export default { @@ -499,7 +274,7 @@ export default {
499 }, 274 },
500 // 设置套餐价格 275 // 设置套餐价格
501 setPackageArr () { 276 setPackageArr () {
502 - console.log(this.packageData); 277 + console.log('含套餐的日期:', this.packageData);
503 let packageArr = []; 278 let packageArr = [];
504 for (let i in this.packageData) { 279 for (let i in this.packageData) {
505 let packageDate = this.Moment( 280 let packageDate = this.Moment(
@@ -522,108 +297,30 @@ export default { @@ -522,108 +297,30 @@ export default {
522 : week == 0 297 : week == 0
523 ? "周日" 298 ? "周日"
524 : ""; 299 : "";
525 - //超出部分不显示  
526 - if (packageArr.length > 3) {  
527 - this.packageArr = packageArr;  
528 - return; 300 + let comboInfoList = [];
  301 + let comboList = JSON.parse(JSON.stringify(this.packageData[i]?.comboList))
  302 + // 为套餐添加下标
  303 + let marketPrice = 999;
  304 + for (let j in comboList) {
  305 + for (let k in comboList[j].comboInfoList) {
  306 + comboList[j].comboInfoList[k].tagIndex = [j, k]
  307 + comboList[j].comboInfoList[k].bindId = comboList[j].id
  308 + if (comboList[j].comboInfoList[k].actualPrice < marketPrice) {
  309 + marketPrice = comboList[j].comboInfoList[k].actualPrice
  310 + }
  311 + }
  312 + comboInfoList.push(...comboList[j].comboInfoList)
529 } 313 }
530 packageArr.push({ 314 packageArr.push({
531 day: packageDate.format("M/D"), 315 day: packageDate.format("M/D"),
532 date: packageDate.format("YYYY-MM-DD"), 316 date: packageDate.format("YYYY-MM-DD"),
533 week: week, 317 week: week,
534 - marketPrice: this.packageData[i]?.comboList[0]?.actualPrice, 318 + marketPrice: marketPrice,
  319 + comboInfoList: comboInfoList,
535 }); 320 });
536 } 321 }
537 this.packageArr = packageArr; 322 this.packageArr = packageArr;
538 - },  
539 - // 获取单个基地  
540 - GetOneBase (baseId) {  
541 - this.mgop({  
542 - api: 'mgop.sz.hswsy.GetOneBase', // 必须  
543 - host: 'https://mapi.zjzwfw.gov.cn/',  
544 - dataType: 'JSON',  
545 - type: 'GET',  
546 - appKey: 'fuxgnukl+2001895516+edccpx', // 必须  
547 - headers: {  
548 - // 'isTestUrl': '1'  
549 - },  
550 - data: {  
551 - "id": baseId,  
552 - },  
553 - onSuccess: res => {  
554 - if (res.data.data) {  
555 - this.baseData = res.data.data;  
556 - }  
557 - },  
558 - onFail: err => {  
559 - console.log('err', err)  
560 - }  
561 - });  
562 - },  
563 - // 设置第几天的课程表  
564 - getWeekCard (index) {  
565 - var data = this.detailData.courseScheduleList[index].courseScheduleList;  
566 - var morning = [];  
567 - var afternoon = [];  
568 - var night = [];  
569 - data.forEach(function (k, j) {  
570 - if (k.type == 1 && k.content != "") {  
571 - morning.push(k);  
572 - } else if (k.type == 2 && k.content != "") {  
573 - afternoon.push(k);  
574 - } else if (k.type == 3 && k.content != "") {  
575 - night.push(k);  
576 - }  
577 - });  
578 - if (morning.length == 0 && afternoon.length == 0 && night.length == 0) {  
579 - this.showCourseTable = false;  
580 - }  
581 - var strMorning = "",  
582 - strAfternoon = "",  
583 - strNight = "";  
584 - if (morning.length > 0) {  
585 - strMorning = `<tr>  
586 - <td class="td_left" rowspan="${morning.length}">上午</td>  
587 - <td style="text-align: left;">${morning[0].content ? morning[0].content : "无安排"  
588 - }</td>  
589 - </tr>`;  
590 - morning.forEach(function (k, j) {  
591 - if (j > 0) {  
592 - strMorning += `<tr>  
593 - <td style="text-align: left;">${k.content ? k.content : "无安排"}</td>  
594 - </tr>`;  
595 - }  
596 - });  
597 - }  
598 - if (afternoon.length > 0) {  
599 - strAfternoon = `<tr>  
600 - <td class="td_left" rowspan="${afternoon.length}">下午</td>  
601 - <td style="text-align: left;">${afternoon[0].content ? afternoon[0].content : "无安排"  
602 - }</td>  
603 - </tr>`;  
604 - afternoon.forEach(function (k, j) {  
605 - if (j > 0) {  
606 - strAfternoon += `<tr>  
607 - <td style="text-align: left;">${k.content ? k.content : "无安排"}</td>  
608 - </tr>`;  
609 - }  
610 - });  
611 - }  
612 - if (night.length > 0) {  
613 - strNight = `<tr>  
614 - <td class="td_left" rowspan="${night.length}">晚上</td>  
615 - <td style="text-align: left;">${night[0].content ? night[0].content : "无安排"  
616 - }</td>  
617 - </tr>`;  
618 - night.forEach(function (k, j) {  
619 - if (j > 0) {  
620 - strNight += `<tr>  
621 - <td style="text-align: left;">${k.content ? k.content : "无安排"}</td>  
622 - </tr>`;  
623 - }  
624 - });  
625 - }  
626 - this.courseTable.push(strMorning + strAfternoon + strNight); 323 + this.initPackageArr = true
627 }, 324 },
628 // 联系客服 325 // 联系客服
629 contactService () { 326 contactService () {
@@ -635,707 +332,13 @@ export default { @@ -635,707 +332,13 @@ export default {
635 backHome () { 332 backHome () {
636 this.$router.push({ name: "ServiceKQ" }); 333 this.$router.push({ name: "ServiceKQ" });
637 }, 334 },
638 - // 点击评价进入评价详情页  
639 - handleEvaluate () {  
640 - this.$router.push({ name: "ServiceAbroadEvaluate", query: { courseId: this.courseId } });  
641 - },  
642 - //领券  
643 - toCoupons () {  
644 - this.$router.push({  
645 - name: "CardBoxXST",  
646 - });  
647 - },  
648 }, 335 },
  336 + components: {
  337 + AbroadDes,
  338 + AbroadBase,
  339 + AbroadEvaluate,
  340 + CountDown,
  341 + AbroadCoupon
  342 + }
649 }; 343 };
650 </script> 344 </script>
651 -<style lang="scss">  
652 -.abroad_detail {  
653 - padding-bottom: 200px;  
654 - .header {  
655 - img {  
656 - width: 100%;  
657 - }  
658 - }  
659 - .countDown {  
660 - height: 130px;  
661 - width: 100%;  
662 - background-color: #201e2b;  
663 - .countDownTop {  
664 - height: 50%;  
665 - padding: 0 3vw;  
666 - box-sizing: border-box;  
667 - display: flex;  
668 - justify-content: space-between;  
669 - align-items: center;  
670 - // color: blanchedalmond;  
671 - color: #ffffff;  
672 - font-size: 32px;  
673 - .countDownTime {  
674 - font-size: 24px;  
675 - .countDownFont {  
676 - line-height: 34px;  
677 - color: #333333;  
678 - border-radius: 5px;  
679 - margin: 0 8px;  
680 - }  
681 - div {  
682 - // color: red;  
683 - width: 34px;  
684 - text-align: center;  
685 - display: inline-block;  
686 - background-color: #ffe9b1;  
687 - }  
688 - }  
689 - }  
690 - .countDownBottom {  
691 - height: 50%;  
692 - padding: 0 3vw;  
693 - box-sizing: border-box;  
694 - display: flex;  
695 - justify-content: space-between;  
696 - align-items: center;  
697 - // color: blanchedalmond;  
698 - color: #ffffff;  
699 - font-size: 24px;  
700 - .countDownBottomyellow {  
701 - display: inline-block;  
702 - // width: 10vw;  
703 - height: 33px;  
704 - margin-right: 12px;  
705 - padding: 0 8px;  
706 - color: #333333;  
707 - font-size: 24px;  
708 - background-color: #ffe9b1;  
709 - border-radius: 4px;  
710 - }  
711 - .countDownBottomTime {  
712 - font-size: 2.8vw;  
713 - color: #ffffff;  
714 - opacity: 0.85;  
715 - }  
716 - .countDownAbout {  
717 - text-decoration: underline;  
718 - }  
719 - }  
720 - }  
721 - .uni_text {  
722 - width: 100%;  
723 - background: #fff;  
724 - padding: 24px 34px;  
725 - box-sizing: border-box;  
726 - .course_price {  
727 - font-size: 38px;  
728 - font-weight: bold;  
729 - color: red;  
730 - .redmini {  
731 - font-size: 25px;  
732 - }  
733 - .tint {  
734 - font-size: 25px;  
735 - font-weight: normal;  
736 - color: #909399;  
737 - margin-left: 2vw;  
738 - text-decoration: line-through;  
739 - }  
740 - }  
741 - .course_price_free {  
742 - font-size: 34px;  
743 - font-weight: bold;  
744 - color: red;  
745 - display: flex;  
746 - justify-content: space-between;  
747 - .des {  
748 - color: #333;  
749 - }  
750 - }  
751 - .course_coupons {  
752 - height: 70px;  
753 - font-size: 27px;  
754 - // color: #4092FF;  
755 - display: flex;  
756 - justify-content: space-between;  
757 - align-items: center;  
758 - .fontBlue {  
759 - color: #4092ff;  
760 - }  
761 - }  
762 - .course_name {  
763 - font-size: 34px;  
764 - font-weight: bold;  
765 - }  
766 - .course_info {  
767 - font-size: 24px;  
768 - color: #999;  
769 - margin-top: 16px;  
770 - }  
771 - .address {  
772 - font-size: 24px;  
773 - color: #999;  
774 - margin-top: 16px;  
775 - .icon {  
776 - color: #000;  
777 - }  
778 - }  
779 - .rate {  
780 - margin-top: 20px;  
781 - display: flex;  
782 - justify-content: space-between;  
783 - div > span {  
784 - font-size: 30px;  
785 - color: #ffcc00;  
786 - margin-left: 30px;  
787 - }  
788 - > span {  
789 - font-size: 26px;  
790 - }  
791 - }  
792 - .tag_box {  
793 - padding-top: 10px;  
794 - .tag {  
795 - display: inline-block;  
796 - margin-top: 10px;  
797 - margin-right: 12px;  
798 - color: #4092ff;  
799 - font-size: 24px;  
800 - border-radius: 8px;  
801 - border: 2px solid #4092ff;  
802 - padding: 2px 10px;  
803 - }  
804 - }  
805 - }  
806 - .package {  
807 - padding: 18px 22px;  
808 - .package_title {  
809 - font-size: 28px;  
810 - color: #999;  
811 - }  
812 - .package_box {  
813 - white-space: nowrap;  
814 - margin-top: 22px;  
815 - .package_item {  
816 - width: 128px;  
817 - height: 152px;  
818 - border-radius: 12px;  
819 - border: 2px solid #dde3ef;  
820 - box-sizing: border-box;  
821 - display: inline-flex;  
822 - align-content: center;  
823 - justify-content: center;  
824 - flex-wrap: wrap;  
825 - vertical-align: top;  
826 - margin-right: 16px;  
827 - p {  
828 - width: 100%;  
829 - margin: 0;  
830 - text-align: center;  
831 - }  
832 - .more_icon {  
833 - width: 36px;  
834 - margin-top: 10px;  
835 - }  
836 - .more_text {  
837 - font-size: 22px;  
838 - color: #fff;  
839 - margin-top: 22px;  
840 - }  
841 - .date {  
842 - font-size: 32px;  
843 - font-weight: bold;  
844 - }  
845 - .week {  
846 - font-size: 22px;  
847 - color: #999;  
848 - }  
849 - .price {  
850 - font-size: 28px;  
851 - color: #ff2b2b;  
852 - margin-top: 14px;  
853 - span {  
854 - font-size: 20px;  
855 - }  
856 - }  
857 - }  
858 - .package_item_more {  
859 - background: #3f92ff;  
860 - border: 2px solid #3f92ff;  
861 - box-shadow: 6px 12px 16px 0px rgba(63, 146, 255, 0.29);  
862 - margin-right: 0;  
863 - }  
864 - }  
865 - }  
866 - .notime {  
867 - width: 100%;  
868 - }  
869 - .content_box {  
870 - position: relative;  
871 -  
872 - .content_all {  
873 - overflow: hidden;  
874 - height: 580px;  
875 - // font-size: 26px;  
876 - // line-height: 36px;  
877 - font-size: 31px !important;  
878 - line-height: 40px !important;  
879 - letter-spacing: 1.6px;  
880 - color: #666;  
881 - // padding-bottom: 130px;  
882 - img {  
883 - width: 100%;  
884 - }  
885 - }  
886 -  
887 - /* 展开 */  
888 - .open {  
889 - height: auto;  
890 - }  
891 -  
892 - .extend_wrap {  
893 - display: flex;  
894 - align-items: center;  
895 - justify-content: center;  
896 - font-size: 26px;  
897 - padding: 40px 0;  
898 - color: #4092ff;  
899 - margin-top: -40px;  
900 - background: linear-gradient(  
901 - 180deg,  
902 - rgba(255, 255, 255, 0.3) 0%,  
903 - rgba(255, 255, 255, 0.8) 30%,  
904 - rgba(255, 255, 255, 1) 100%  
905 - );  
906 - width: 100%;  
907 - position: absolute;  
908 - bottom: 0;  
909 - left: 0;  
910 - }  
911 - }  
912 -  
913 - .tag_item {  
914 - padding: 22px;  
915 - .tag_title {  
916 - font-size: 34px;  
917 - font-weight: bold;  
918 - margin-bottom: 32px;  
919 - }  
920 - .tag_text {  
921 - // font-size: 24px;  
922 - // line-height: 40px;  
923 - font-size: 28px !important;  
924 - line-height: 44px !important;  
925 - padding: 16px 0;  
926 - }  
927 - }  
928 - .cardCont {  
929 - // font-size: 24px;  
930 - font-size: 28px !important;  
931 - table {  
932 - border-radius: 5px;  
933 - width: 100%;  
934 - border: 1px solid #dde3ef;  
935 - td {  
936 - border: 1px solid #dde3ef;  
937 - text-align: center;  
938 - background: rgb(245, 246, 250);  
939 - }  
940 - .td_left {  
941 - width: 132px;  
942 - background: #fff;  
943 - box-sizing: border-box;  
944 - }  
945 - }  
946 - }  
947 - .courseContent {  
948 - li:not(:last-child) {  
949 - border-bottom: 1px solid #eee;  
950 - }  
951 - li:first-child {  
952 - .left {  
953 - color: #fa9b00;  
954 - border: 1px solid #fa9b00;  
955 - background-color: #fef4d9;  
956 - }  
957 - }  
958 - li:nth-child(3n + 1) {  
959 - .left {  
960 - color: #fa9b00;  
961 - border: 1px solid #fa9b00;  
962 - background-color: #fef4d9;  
963 - }  
964 - }  
965 - li:nth-child(3n-1) {  
966 - .left {  
967 - color: #fa008c;  
968 - border: 1px solid #fa008c;  
969 - background-color: #ffeffc;  
970 - }  
971 - }  
972 - li:nth-child(3n) {  
973 - .left {  
974 - color: #0076fa;  
975 - border: 1px solid #0076fa;  
976 - background-color: #efffff;  
977 - }  
978 - }  
979 - li {  
980 - position: relative;  
981 - margin-top: 20px;  
982 - padding-bottom: 10px;  
983 - .left {  
984 - position: absolute;  
985 - top: 0;  
986 - left: 0;  
987 - width: 120px;  
988 - font-size: 26px;  
989 - text-align: center;  
990 - border-radius: 3px;  
991 - padding: 3px;  
992 - box-sizing: border-box;  
993 - font-weight: 600;  
994 - }  
995 - h3 {  
996 - color: #202228;  
997 - // font-size: 32px;  
998 - font-size: 30px !important;  
999 - font-weight: 400;  
1000 - margin: 0;  
1001 - padding-left: 160px;  
1002 - word-break: break-all;  
1003 - }  
1004 - .item {  
1005 - margin-top: 10px;  
1006 - img {  
1007 - width: 100%;  
1008 - }  
1009 - p {  
1010 - margin: 0;  
1011 - margin-top: 10px;  
1012 - color: #a7a7aa;  
1013 - // font-size: 28px;  
1014 - font-size: 31px !important;  
1015 - b {  
1016 - // font-size: 32px;  
1017 - font-size: 35px !important;  
1018 - font-weight: 400;  
1019 - color: #000000;  
1020 - margin-right: 10px;  
1021 - }  
1022 - span {  
1023 - // font-size: 24px;  
1024 - font-size: 27px !important;  
1025 - }  
1026 - }  
1027 - }  
1028 - }  
1029 - }  
1030 - .base {  
1031 - padding: 28px 24px;  
1032 - img {  
1033 - width: 98px;  
1034 - height: 98px;  
1035 - display: inline-block;  
1036 - vertical-align: top;  
1037 - border-radius: 12px;  
1038 - }  
1039 - .center {  
1040 - width: 550px;  
1041 - display: inline-block;  
1042 - margin-left: 20px;  
1043 - .basename {  
1044 - // font-size: 32px;  
1045 - font-size: 35px !important;  
1046 - font-weight: bold;  
1047 - }  
1048 - .address {  
1049 - // font-size: 24px;  
1050 - font-size: 27px !important;  
1051 - margin-top: 12px;  
1052 - }  
1053 - .tag {  
1054 - display: inline-block;  
1055 - // font-size: 24px;  
1056 - font-size: 26px !important;  
1057 - margin-top: 14px;  
1058 - background: #f5f6fa;  
1059 - border-radius: 6px;  
1060 - padding: 6px 20px;  
1061 - }  
1062 - }  
1063 - }  
1064 - .top_border {  
1065 - border-top: 16px solid #f6f7fa;  
1066 - ::v-deep .van-tab {  
1067 - .van-tab__text {  
1068 - font-size: 34px !important;  
1069 - }  
1070 - }  
1071 - }  
1072 - .popup_content {  
1073 - width: 408px;  
1074 - height: 346px;  
1075 - overflow: hidden;  
1076 - img {  
1077 - display: block;  
1078 - width: 86px;  
1079 - height: 86px;  
1080 - margin: 0 auto;  
1081 - margin-top: 64px;  
1082 - }  
1083 - p:first-of-type {  
1084 - text-align: center;  
1085 - margin-top: 46px;  
1086 - // font-size: 36px;  
1087 - font-size: 39px !important;  
1088 - }  
1089 - p:last-of-type {  
1090 - text-align: center;  
1091 - margin-top: 16px;  
1092 - // font-size: 26px;  
1093 - font-size: 29px !important;  
1094 - color: #999;  
1095 - }  
1096 - }  
1097 - .Collection {  
1098 - background-color: white;  
1099 - position: fixed;  
1100 - bottom: 0;  
1101 - left: 0;  
1102 - width: 100%;  
1103 - padding: 28px 22px;  
1104 - box-sizing: border-box;  
1105 - padding-bottom: 50px;  
1106 - z-index: 500;  
1107 - box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.34);  
1108 - .box1 {  
1109 - width: 40%;  
1110 - }  
1111 - .box2 {  
1112 - width: 60%;  
1113 - }  
1114 - .box {  
1115 - display: inline-block;  
1116 - vertical-align: middle;  
1117 - color: #666666;  
1118 - .icon {  
1119 - display: inline-block;  
1120 - width: 45%;  
1121 - text-align: center;  
1122 - // font-size: 24px;  
1123 - font-size: 26px !important;  
1124 - p {  
1125 - // margin: 0;  
1126 - color: #999999;  
1127 - margin-top: 8px;  
1128 - }  
1129 - i {  
1130 - font-size: 48px;  
1131 - color: rgb(45, 45, 45);  
1132 - font-weight: bold;  
1133 - }  
1134 - }  
1135 - .icon.active {  
1136 - color: 0ce39d;  
1137 - i {  
1138 - color: #0ce39d;  
1139 - }  
1140 - }  
1141 - span {  
1142 - display: inline-block;  
1143 - width: 100%;  
1144 - line-height: 92px;  
1145 - box-sizing: border-box;  
1146 - border-radius: 100px;  
1147 - color: white;  
1148 - // font-size: 32px;  
1149 - font-size: 35px !important;  
1150 - background: #4092ff;  
1151 - text-align: center;  
1152 - box-shadow: 0px 10px 40px 0px #a0c9ff;  
1153 - b {  
1154 - display: inline-block;  
1155 - vertical-align: middle;  
1156 - margin-left: 20px;  
1157 - color: white;  
1158 - }  
1159 - i {  
1160 - vertical-align: middle;  
1161 - font-size: 44px;  
1162 - font-weight: bold;  
1163 - }  
1164 - }  
1165 - .disabled {  
1166 - color: #999;  
1167 - background: #edeced;  
1168 - box-shadow: none;  
1169 - }  
1170 - }  
1171 - }  
1172 - .pintuan_about {  
1173 - width: 592px;  
1174 - box-sizing: border-box;  
1175 - padding: 0 50px;  
1176 - .about_img {  
1177 - width: 112px;  
1178 - margin: 0 auto;  
1179 - margin-top: 30px;  
1180 - display: block;  
1181 - }  
1182 - .about_title {  
1183 - font-size: 34px;  
1184 - font-weight: bold;  
1185 - text-align: center;  
1186 - }  
1187 - .about_content {  
1188 - font-size: 30px;  
1189 - margin-top: 20px;  
1190 - }  
1191 - .about_know {  
1192 - font-size: 32px;  
1193 - text-align: center;  
1194 - color: #3385ff;  
1195 - margin-top: 60px;  
1196 - margin-bottom: 44px;  
1197 - }  
1198 - }  
1199 - .show_tip_title {  
1200 - img {  
1201 - width: 112px;  
1202 - }  
1203 - p {  
1204 - margin-top: -20px;  
1205 - margin-bottom: 20px;  
1206 - }  
1207 - }  
1208 - .show_tip {  
1209 - padding: 0 20px;  
1210 - font-size: 28px;  
1211 - letter-spacing: 1px;  
1212 - text-align: left;  
1213 - line-height: 64px;  
1214 - color: rgb(153, 153, 153);  
1215 - b {  
1216 - color: #000;  
1217 - }  
1218 - }  
1219 - .tip_checkbox{  
1220 - font-size: 26px;  
1221 - margin-top: 24px;  
1222 - margin-bottom: 60px;  
1223 - margin-left: 50px;  
1224 - }  
1225 -}  
1226 -</style>  
1227 -<style lang="scss">  
1228 -.elder {  
1229 - .abroad_detail {  
1230 - .countDown {  
1231 - height: auto;  
1232 - .countDownTop {  
1233 - display: block;  
1234 - font-size: 40px;  
1235 - .countDownTime {  
1236 - font-size: 40px;  
1237 - padding: 10px 0;  
1238 - div {  
1239 - width: 60px;  
1240 - }  
1241 - .countDownFont {  
1242 - line-height: 60px;  
1243 - }  
1244 - }  
1245 - }  
1246 - .countDownBottom {  
1247 - display: block;  
1248 - font-size: 40px;  
1249 - .countDownBottomyellow {  
1250 - height: 60px;  
1251 - font-size: 40px;  
1252 - }  
1253 - }  
1254 - }  
1255 - .uni_text {  
1256 - .course_price {  
1257 - font-size: 48px;  
1258 - .redmini,  
1259 - .tint {  
1260 - font-size: 36px;  
1261 - }  
1262 - }  
1263 - .course_name {  
1264 - font-size: 44px;  
1265 - }  
1266 - .course_info {  
1267 - font-size: 40px;  
1268 - }  
1269 - .address {  
1270 - font-size: 40px;  
1271 - }  
1272 - .rate > span {  
1273 - font-size: 36px;  
1274 - }  
1275 - .tag_box .tag {  
1276 - font-size: 40px;  
1277 - }  
1278 - }  
1279 - .package {  
1280 - .package_title {  
1281 - font-size: 44px;  
1282 - }  
1283 - .package_item {  
1284 - .date {  
1285 - font-size: 40px;  
1286 - }  
1287 - .week {  
1288 - font-size: 34px;  
1289 - }  
1290 - .price {  
1291 - font-size: 34px;  
1292 - }  
1293 - }  
1294 - }  
1295 - .content_box .content_all {  
1296 - font-size: 40px !important;  
1297 - line-height: 60px !important;  
1298 - }  
1299 - .tag_item {  
1300 - .tag_title {  
1301 - font-size: 44px;  
1302 - }  
1303 - .tag_text {  
1304 - font-size: 40px !important;  
1305 - line-height: 60px !important;  
1306 - }  
1307 - }  
1308 - .base .center {  
1309 - .basename {  
1310 - font-size: 44px !important;  
1311 - }  
1312 - .address {  
1313 - font-size: 40px !important;  
1314 - }  
1315 - }  
1316 - .Collection .box {  
1317 - span {  
1318 - font-size: 44px !important;  
1319 - }  
1320 - .icon {  
1321 - font-size: 40px !important;  
1322 - }  
1323 - }  
1324 - .pintuan_about {  
1325 - .about_title {  
1326 - font-size: 44px;  
1327 - }  
1328 - .about_box {  
1329 - height: 600px;  
1330 - overflow: auto;  
1331 - }  
1332 - .about_content {  
1333 - font-size: 36px;  
1334 - }  
1335 - .about_know {  
1336 - font-size: 40px;  
1337 - }  
1338 - }  
1339 - }  
1340 -}  
1341 -</style>  
1342 \ No newline at end of file 345 \ No newline at end of file
src/views/Service/CheckOrder.vue
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <div> 6 <div>
7 <p class="goods_title">{{showCourseData.course_name}}</p> 7 <p class="goods_title">{{showCourseData.course_name}}</p>
8 <p class="package_name">套餐名称:{{selectCombo.comboName}}</p> 8 <p class="package_name">套餐名称:{{selectCombo.comboName}}</p>
9 - <p class="count">数量:x{{count}}</p> 9 + <p class="count">数量:x{{count}}{{selectComboUnitName}}</p>
10 </div> 10 </div>
11 </div> 11 </div>
12 <div class="bottom"> 12 <div class="bottom">
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 </div> 22 </div>
23 </div> 23 </div>
24 <div class="top_border"> 24 <div class="top_border">
25 - <contact-box :limit="count"></contact-box> 25 + <contact-box :limit="count" :people="selectCombo.adultCount" :child="selectCombo.chilCount"></contact-box>
26 </div> 26 </div>
27 <div class="card top_border"> 27 <div class="card top_border">
28 <p>服务承诺和保障</p> 28 <p>服务承诺和保障</p>
@@ -56,6 +56,7 @@ export default { @@ -56,6 +56,7 @@ export default {
56 useCard: '', 56 useCard: '',
57 orderDetail: '', 57 orderDetail: '',
58 selectCombo: '',//当前套餐信息 58 selectCombo: '',//当前套餐信息
  59 + selectComboUnitName:'',//套餐单位 人或份
59 showCourseData: '',//当前课程的信息 60 showCourseData: '',//当前课程的信息
60 selectCombo: '',//已选择的套餐 61 selectCombo: '',//已选择的套餐
61 userInfo: '',//支付用 62 userInfo: '',//支付用
@@ -76,6 +77,7 @@ export default { @@ -76,6 +77,7 @@ export default {
76 if (selectCombo) { 77 if (selectCombo) {
77 this.selectCombo = JSON.parse(selectCombo) 78 this.selectCombo = JSON.parse(selectCombo)
78 } 79 }
  80 + this.selectComboUnitName = sessionStorage.getItem('selectComboUnitName')
79 81
80 // 如果有优惠券,就展示 82 // 如果有优惠券,就展示
81 let useCard = localStorage.getItem('useCard') 83 let useCard = localStorage.getItem('useCard')
@@ -117,11 +119,20 @@ export default { @@ -117,11 +119,20 @@ export default {
117 // 出行人数量判断 119 // 出行人数量判断
118 let selectedContactArr = localStorage.getItem('selectedContactArr'); 120 let selectedContactArr = localStorage.getItem('selectedContactArr');
119 selectedContactArr = JSON.parse(selectedContactArr); 121 selectedContactArr = JSON.parse(selectedContactArr);
120 - if (selectedContactArr.length != this.count) {  
121 - this.$toast.fail('请选择与购买商品数量相同的出行人数'); 122 + let selAdult = 0;
  123 + let selChild = 0;
  124 + for(let i in selectedContactArr){
  125 + if(selectedContactArr[i].userType==2){
  126 + selAdult++
  127 + }else{
  128 + selChild++
  129 + }
  130 + }
  131 + // 判断选择成人和学生数量是否匹配
  132 + if(selAdult!=this.count*this.selectCombo.adultCount||selChild!=this.count*this.selectCombo.chilCount){
  133 + this.$toast.fail('请选择正确数量的出行人');
122 return; 134 return;
123 } 135 }
124 -  
125 // 协议勾选 136 // 协议勾选
126 if (!this.checked) { 137 if (!this.checked) {
127 this.$toast.fail('请先阅读并同意用户协议'); 138 this.$toast.fail('请先阅读并同意用户协议');
@@ -163,7 +174,6 @@ export default { @@ -163,7 +174,6 @@ export default {
163 // 使用后移除优惠券,防止返回继续使用 174 // 使用后移除优惠券,防止返回继续使用
164 localStorage.removeItem('useCard') 175 localStorage.removeItem('useCard')
165 this.$router.push({ name: 'ServiceOrderXST', query: { active: 1, showChatGroupUrl: 1 } }) 176 this.$router.push({ name: 'ServiceOrderXST', query: { active: 1, showChatGroupUrl: 1 } })
166 -  
167 } else { 177 } else {
168 // 使用后移除优惠券,防止返回继续使用 178 // 使用后移除优惠券,防止返回继续使用
169 localStorage.removeItem('useCard') 179 localStorage.removeItem('useCard')
src/views/Service/DatePackage.vue
1 <template> 1 <template>
2 - <div id="datePackage"> 2 + <div id="datePackage" v-if="comboList">
3 <!-- <div class="tag_item"> 3 <!-- <div class="tag_item">
4 <p class="tag_title">商品名称</p> 4 <p class="tag_title">商品名称</p>
5 <p class="package_name">{{showCourseData.course_name}}</p> 5 <p class="package_name">{{showCourseData.course_name}}</p>
6 </div> --> 6 </div> -->
7 <div class="tag_item"> 7 <div class="tag_item">
8 - <p class="tag_title">活动日期</p>  
9 - <p class="package_name" :class="date?'active':''" @click="showCalendar=true">{{date||'选择日期'}}</p> 8 + <p class="tag_title">出行时间</p>
  9 + <p class="package_name" :class="date?'active':''" @click="showCalendar=true">{{date||'选择日期'}}<van-icon name="arrow" /></p>
10 <van-calendar v-model="showCalendar" :default-date="defaultDate" @confirm="chooseDate" :show-confirm="false" color="#3F92FF" :formatter="formatCalendar" /> 10 <van-calendar v-model="showCalendar" :default-date="defaultDate" @confirm="chooseDate" :show-confirm="false" color="#3F92FF" :formatter="formatCalendar" />
11 </div> 11 </div>
12 - <div class="tag_item" v-if="comboList[active]">  
13 - <p class="tag_title">成团情况<span class="pintuan_status" v-if="comboList[active].clusterName">{{comboList[active].clusterName}}</span></p>  
14 - <p class="package_name">最低拼团数 {{comboList[active].peopleCount}}人 已报名人数{{numOne}}/{{comboList[active].stockCount}}人</p> 12 + <div class="tag_item" v-if="date">
  13 + <p class="tag_title">行程选择</p>
  14 + <div class="period">
  15 + <div class="period_item" :class="Index1==index?'active':''" v-for="(item,index) in comboList" :key="index" @click="choosePeriod(index)">行程{{index + 1}} :{{item.dateComboName}}</div>
  16 + </div>
15 </div> 17 </div>
16 - <div class="tag_item">  
17 - <p class="tag_title">天数</p>  
18 - <p class="package_name">{{days}}天</p> 18 + <div class="tag_item" v-if="comboList[Index1]">
  19 + <p class="tag_title">成团情况<span class="pintuan_status" v-if="comboList[Index1].clusterName">{{comboList[Index1].clusterName}}</span></p>
  20 + <p class="package_name">最低拼团数 {{comboList[Index1].peopleCount}}{{comboList[Index1].unitName}} 已报名{{comboList[Index1].unitName}}数{{numOne}}/{{comboList[Index1].stockCount}}{{comboList[Index1].unitName}}</p>
19 </div> 21 </div>
20 <div class="tag_item" v-if="date"> 22 <div class="tag_item" v-if="date">
21 - <p class="tag_title">套餐</p> 23 + <p class="tag_title">套餐类型</p>
22 <div class="period"> 24 <div class="period">
23 - <!-- <span class="period_item" :class="active==index?'active':''" v-for="(item,index) in comboList" :key="index" @click="choosePeriod(index)">{{item.comboName}} ¥{{item.actualPrice}}</span> -->  
24 - <div class="period_item" :class="active==index?'active':''" v-for="(item,index) in comboList" :key="index" @click="choosePeriod(index)">套餐{{index + 1}} :{{item.comboName}} ¥{{item.actualPrice}}</div> 25 + <div class="period_item" :class="Index2==index?'active':''" v-for="(item,index) in comboList[Index1].comboInfoList" :key="index" @click="choosePeriod2(index)">套餐{{index + 1}} :{{item.comboName}} ¥{{item.actualPrice}}</div>
25 </div> 26 </div>
26 </div> 27 </div>
27 <div class="tag_item"> 28 <div class="tag_item">
28 <div class="tag_title tag_title_flex"> 29 <div class="tag_title tag_title_flex">
29 - <span>数量</span> 30 + <span>请选择套餐数量</span>
30 <div class="tag_title_right"> 31 <div class="tag_title_right">
31 <span class="btn" @click="countReduce">-</span> 32 <span class="btn" @click="countReduce">-</span>
32 <span class="count">{{count}}</span> 33 <span class="count">{{count}}</span>
@@ -35,20 +36,26 @@ @@ -35,20 +36,26 @@
35 </div> 36 </div>
36 <div class="package_num"> 37 <div class="package_num">
37 <span>库存数量({{numSecond}} /</span> 38 <span>库存数量({{numSecond}} /</span>
38 - <span class="tint">{{numOne+numSecond}})</span> 39 + <span class="tint">{{numOne+numSecond}}{{comboList[Index1].unitName}})</span>
39 </div> 40 </div>
40 </div> 41 </div>
  42 + <p class="package_des" v-if="comboList[Index1].comboInfoList[Index2].comboDescrption">套餐说明<br>{{comboList[Index1].comboInfoList[Index2].comboDescrption}}</p>
41 <div class="Collection"> 43 <div class="Collection">
42 <div class="box box1"> 44 <div class="box box1">
43 - <p v-if="active>-1&&comboList[active]"><span>¥</span>{{comboList[active].actualPrice*1000*count/1000}} <del>{{comboList[active].productPrice*1000*count/1000}}</del></p> 45 + <p><span>¥</span>{{comboList[Index1].comboInfoList[Index2].actualPrice*1000*count/1000}} <del>{{comboList[Index1].comboInfoList[Index2].productPrice*1000*count/1000}}</del></p>
44 </div> 46 </div>
45 <div class="box box2"> 47 <div class="box box2">
46 <span @click="checkOrder()">去下单</span> 48 <span @click="checkOrder()">去下单</span>
47 </div> 49 </div>
48 </div> 50 </div>
  51 +
  52 + <van-popup style="background: transparent;" get-container="body" v-model="showSchool" @close='closeSchool'>
  53 + <school-add @closeAdd='closeAdd'></school-add>
  54 + </van-popup>
49 </div> 55 </div>
50 </template> 56 </template>
51 <script> 57 <script>
  58 +import schoolAdd from '@/views/Travel/component/schoolAdd'
52 export default { 59 export default {
53 name: 'ServiceDatePackage', 60 name: 'ServiceDatePackage',
54 data () { 61 data () {
@@ -58,12 +65,14 @@ export default { @@ -58,12 +65,14 @@ export default {
58 packageData: '', 65 packageData: '',
59 showCourseData: '', 66 showCourseData: '',
60 comboList: '', 67 comboList: '',
61 - active: 0,//选中的排期 68 + Index1: 0,//选中的档期
  69 + Index2: 0,//选中的套餐
62 showCalendar: false, 70 showCalendar: false,
63 count: 1, 71 count: 1,
64 days: 1, 72 days: 1,
65 numOne: 0, 73 numOne: 0,
66 numSecond: 0, 74 numSecond: 0,
  75 + showSchool: false
67 } 76 }
68 }, 77 },
69 mounted () { 78 mounted () {
@@ -93,7 +102,7 @@ export default { @@ -93,7 +102,7 @@ export default {
93 }, 102 },
94 methods: { 103 methods: {
95 // 获取库存 104 // 获取库存
96 - GetOrderPayCount () { 105 + GetOrderPayCount (bindId) {
97 let showCourseData = JSON.parse(localStorage.getItem('showCourseData')) 106 let showCourseData = JSON.parse(localStorage.getItem('showCourseData'))
98 this.mgop({ 107 this.mgop({
99 api: 'mgop.sz.hswsy.OrderPayCount', // 必须 108 api: 'mgop.sz.hswsy.OrderPayCount', // 必须
@@ -105,6 +114,7 @@ export default { @@ -105,6 +114,7 @@ export default {
105 // 'isTestUrl': '1' 114 // 'isTestUrl': '1'
106 }, 115 },
107 data: { 116 data: {
  117 + "bindId":bindId,
108 "productId": showCourseData.id, 118 "productId": showCourseData.id,
109 "startDate": this.date, 119 "startDate": this.date,
110 }, 120 },
@@ -147,12 +157,16 @@ export default { @@ -147,12 +157,16 @@ export default {
147 }, 157 },
148 // 选择排期 158 // 选择排期
149 choosePeriod (index) { 159 choosePeriod (index) {
150 - this.active = index;  
151 - this.days = this.packageData['0'].days ? this.packageData[index].days : 0  
152 - let bindId = this.packageData['0'].comboList[index].id ? this.packageData['0'].comboList[index].id : ''  
153 - let dateBindComboId = this.packageData['0'].comboList[index].dateBindComboId 160 + this.Index1 = index;
  161 + this.Index2 = 0;
  162 + let bindId = this.comboList[index].id
  163 + console.log(this.comboList[index])
154 this.GetOrderPayCount(bindId) 164 this.GetOrderPayCount(bindId)
155 - this.getSurplusComboCount(dateBindComboId) 165 + this.getSurplusComboCount(bindId)
  166 + },
  167 + // 选择套餐
  168 + choosePeriod2 (index) {
  169 + this.Index2 = index;
156 }, 170 },
157 // 选择日期 171 // 选择日期
158 chooseDate (date) { 172 chooseDate (date) {
@@ -167,7 +181,8 @@ export default { @@ -167,7 +181,8 @@ export default {
167 return; 181 return;
168 } 182 }
169 this.date = this.Moment(date, 'YYYY-MM-DD').format('YYYY-MM-DD') 183 this.date = this.Moment(date, 'YYYY-MM-DD').format('YYYY-MM-DD')
170 - this.active = 0; 184 + this.Index1 = 0;
  185 + this.Index2 = 0;
171 this.showCalendar = false; 186 this.showCalendar = false;
172 this.setComboList() 187 this.setComboList()
173 }, 188 },
@@ -176,21 +191,21 @@ export default { @@ -176,21 +191,21 @@ export default {
176 // console.log(day) 191 // console.log(day)
177 for (let i in this.packageData) { 192 for (let i in this.packageData) {
178 if (this.Moment(day.date, 'YYYY-MM-DD').format('YYYY-MM-DD') == this.Moment(this.packageData[i].dayName, 'YYYY-MM-DD').format('YYYY-MM-DD')) { 193 if (this.Moment(day.date, 'YYYY-MM-DD').format('YYYY-MM-DD') == this.Moment(this.packageData[i].dayName, 'YYYY-MM-DD').format('YYYY-MM-DD')) {
179 - day.bottomInfo = '¥' + this.packageData[i].comboList[0].actualPrice; 194 + day.bottomInfo = '¥' + this.packageData[i].comboList[0].comboInfoList[0].actualPrice;
180 } 195 }
181 } 196 }
182 return day; 197 return day;
183 }, 198 },
184 // 根据日期设置套餐 199 // 根据日期设置套餐
185 setComboList () { 200 setComboList () {
186 - let bindId = this.packageData['0'].comboList['0'].id ? this.packageData['0'].comboList['0'].id : ''  
187 - let dateBindComboId = this.packageData['0'].comboList['0'].dateBindComboId  
188 - this.days = this.packageData['0'].days ? this.packageData['0'].days : 0  
189 - this.GetOrderPayCount(bindId)  
190 - this.getSurplusComboCount(dateBindComboId)  
191 for (let i in this.packageData) { 201 for (let i in this.packageData) {
192 if (this.Moment(this.packageData[i].dayName, 'YYYY-MM-DD').format(('YYYY-MM-DD')) == this.date) { 202 if (this.Moment(this.packageData[i].dayName, 'YYYY-MM-DD').format(('YYYY-MM-DD')) == this.date) {
193 - this.comboList = this.packageData[i].comboList; 203 + let comboList = this.packageData[i].comboList;
  204 + this.comboList = comboList
  205 + let bindId = comboList[this.Index1].id
  206 + this.days = this.packageData[i].days
  207 + this.GetOrderPayCount(bindId)
  208 + this.getSurplusComboCount(bindId)
194 break; 209 break;
195 } 210 }
196 } 211 }
@@ -206,20 +221,28 @@ export default { @@ -206,20 +221,28 @@ export default {
206 if (this.count > this.numSecond) { 221 if (this.count > this.numSecond) {
207 this.$toast('库存不足'); 222 this.$toast('库存不足');
208 223
209 - }  
210 - else if (!this.date) {  
211 - this.$toast('请选择日期');  
212 - } else if (this.active == -1) {  
213 - this.$toast('请选择时间段');  
214 } else { 224 } else {
215 const query = { 225 const query = {
216 date: this.date, 226 date: this.date,
217 count: this.count 227 count: this.count
218 } 228 }
219 - localStorage.setItem('selectCombo', JSON.stringify(this.comboList[this.active])) 229 + localStorage.setItem('selectCombo', JSON.stringify(this.comboList[this.Index1].comboInfoList[this.Index2]))
  230 + localStorage.setItem('selectComboBindId', JSON.stringify(this.comboList[this.Index1].id))
  231 + localStorage.setItem('selectComboUnitName', this.comboList[this.Index1].unitName)
220 this.$router.push({ name: 'ServiceCheckOrder', query: query }) 232 this.$router.push({ name: 'ServiceCheckOrder', query: query })
221 } 233 }
222 }, 234 },
  235 + closeSchool () {
  236 + if (sessionStorage.getItem('schoolNames') == 'undefined' || !sessionStorage.getItem('schoolNames')) {
  237 + // this.showSchool = true
  238 + }
  239 + },
  240 + closeAdd () {
  241 + this.showSchool = false
  242 + }
  243 + },
  244 + components: {
  245 + schoolAdd
223 } 246 }
224 } 247 }
225 </script> 248 </script>
@@ -244,6 +267,8 @@ export default { @@ -244,6 +267,8 @@ export default {
244 } 267 }
245 } 268 }
246 .package_name { 269 .package_name {
  270 + display: flex;
  271 + justify-content: space-between;
247 font-size: 28px; 272 font-size: 28px;
248 width: 100%; 273 width: 100%;
249 background: #f5f6fa; 274 background: #f5f6fa;
@@ -312,6 +337,15 @@ export default { @@ -312,6 +337,15 @@ export default {
312 } 337 }
313 } 338 }
314 } 339 }
  340 + .package_des {
  341 + margin: 0 24px;
  342 + margin-top: 28px;
  343 + padding: 20px 0;
  344 + font-size: 26px;
  345 + line-height: 40px;
  346 + color: #a9a9aa;
  347 + border-top: 1px solid #e2e7ee;
  348 + }
315 .Collection { 349 .Collection {
316 background-color: white; 350 background-color: white;
317 position: fixed; 351 position: fixed;
src/views/Service/SelectContact.vue
@@ -31,10 +31,11 @@ @@ -31,10 +31,11 @@
31 </template> 31 </template>
32 <script> 32 <script>
33 import AddChildPopupGroup from '@/views/Home/component/AddChildPopupGroup' 33 import AddChildPopupGroup from '@/views/Home/component/AddChildPopupGroup'
  34 +import IdentityCodeValid from '@/common/validateIdent'
34 export default { 35 export default {
35 data () { 36 data () {
36 return { 37 return {
37 - limit: '', 38 + limit: '',//数量
38 hideParent: false, 39 hideParent: false,
39 contactList: [], 40 contactList: [],
40 showAddChildPopupGroup: false 41 showAddChildPopupGroup: false
@@ -43,7 +44,6 @@ export default { @@ -43,7 +44,6 @@ export default {
43 mounted () { 44 mounted () {
44 this.limit = this.$route.query.limit; 45 this.limit = this.$route.query.limit;
45 this.hideParent = this.$route.query.hideParent ? true : false; 46 this.hideParent = this.$route.query.hideParent ? true : false;
46 - console.log(this.hideParent)  
47 this.getContactList() 47 this.getContactList()
48 }, 48 },
49 methods: { 49 methods: {
@@ -120,23 +120,21 @@ export default { @@ -120,23 +120,21 @@ export default {
120 if ((!contactList[i].travelerIdCard || !contactList[i].gender) && !this.hideParent) { 120 if ((!contactList[i].travelerIdCard || !contactList[i].gender) && !this.hideParent) {
121 this.$toast('请先完善您选择的出行人信息') 121 this.$toast('请先完善您选择的出行人信息')
122 return; 122 return;
  123 + } else if (!IdentityCodeValid(contactList[i].travelerIdCard)) {
  124 + this.$toast(`${contactList[i].travelerName}的身份证有误,请重新完善修改`)
  125 + return;
123 } else { 126 } else {
124 selectedArr.push({ 127 selectedArr.push({
125 travelerName: contactList[i].travelerName, 128 travelerName: contactList[i].travelerName,
126 travelerMobile: contactList[i].travelerMobile, 129 travelerMobile: contactList[i].travelerMobile,
127 travelerNum: contactList[i].travelerNum, 130 travelerNum: contactList[i].travelerNum,
128 - travelerIdCard:contactList[i].travelerIdCard, 131 + travelerIdCard: contactList[i].travelerIdCard,
129 userType: contactList[i].userType, 132 userType: contactList[i].userType,
130 }) 133 })
131 } 134 }
132 } 135 }
133 } 136 }
134 console.log(this.limit, selectedArr.length) 137 console.log(this.limit, selectedArr.length)
135 - // 判断出行人数是否符合  
136 - if (this.limit && this.limit != selectedArr.length) {  
137 - this.$toast(`请选择${this.limit}位出行人`)  
138 - return;  
139 - }  
140 // 判断是否选择学生 138 // 判断是否选择学生
141 let hasStudent = false; 139 let hasStudent = false;
142 for (let i in selectedArr) { 140 for (let i in selectedArr) {
src/views/Service/component/AbroadDetail/AbroadBase.vue 0 → 100644
@@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
  1 +<template>
  2 + <div class="base_box">
  3 + <div class="base top_border" v-if="baseData">
  4 + <img v-if="baseData.coverList.length > 0" :src="baseData.coverList[0].cover_url" alt="" />
  5 + <div class="center">
  6 + <p class="basename">{{ baseData.baseName }}</p>
  7 + <p class="address">
  8 + <van-icon name="location-o" />{{ baseData.city }}{{ baseData.area}}{{ baseData.address }}
  9 + </p>
  10 + <p class="tag">{{ baseData.baseLabel.join("/") }}</p>
  11 + </div>
  12 + </div>
  13 + </div>
  14 +</template>
  15 +<script>
  16 +export default {
  17 + props: ['baseId'],
  18 + data () {
  19 + return {
  20 + baseData: "", //基地信息
  21 + }
  22 + },
  23 + mounted () {
  24 + this.GetOneBase()
  25 + },
  26 + methods: {
  27 + // 获取单个基地
  28 + GetOneBase (baseId) {
  29 + this.mgop({
  30 + api: 'mgop.sz.hswsy.GetOneBase', // 必须
  31 + host: 'https://mapi.zjzwfw.gov.cn/',
  32 + dataType: 'JSON',
  33 + type: 'GET',
  34 + appKey: 'fuxgnukl+2001895516+edccpx', // 必须
  35 + headers: {
  36 + // 'isTestUrl': '1'
  37 + },
  38 + data: {
  39 + "id": baseId,
  40 + },
  41 + onSuccess: res => {
  42 + if (res.data.data) {
  43 + this.baseData = res.data.data;
  44 + }
  45 + },
  46 + onFail: err => {
  47 + console.log('err', err)
  48 + }
  49 + });
  50 + },
  51 + }
  52 +}
  53 +</script>
0 \ No newline at end of file 54 \ No newline at end of file
src/views/Service/component/AbroadDetail/AbroadCoupon.vue 0 → 100644
@@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
  1 +<template>
  2 + <div class="course_coupons" v-if="proCoupon.length>0">
  3 + <div>
  4 + <van-tag v-for="(item,index) in proCoupon" :key="index" color="#ffffff" text-color="#FF2B2B">{{proCouponHas?'已领取:':''}}{{item.title}}</van-tag>
  5 + </div>
  6 + <div @click="toCoupons" class="fontBlue">领取 ></div>
  7 + </div>
  8 +</template>
  9 +<script>
  10 +export default {
  11 + props: ['detailDataId', 'centerNo'],
  12 + data () {
  13 + return {
  14 + proCoupon: [],//优惠券
  15 + proCouponHas: false,//优惠券已领取
  16 + }
  17 + },
  18 + mounted () {
  19 + this.getOrderCoupon()
  20 + },
  21 + methods: {
  22 + //获取产品可使用优惠券
  23 + getOrderCoupon () {
  24 + this.mgop({
  25 + api: 'mgop.sz.hswsy.orderCoupon', // 必须
  26 + host: 'https://mapi.zjzwfw.gov.cn/',
  27 + dataType: 'JSON',
  28 + type: 'POST',
  29 + appKey: 'fuxgnukl+2001895516+edccpx', // 必须
  30 + headers: {
  31 + // 'isTestUrl': '1'
  32 + },
  33 + data: {
  34 + "proId": this.detailDataId,
  35 + "userId": this.centerNo,
  36 + },
  37 + onSuccess: res => {
  38 + if (res.data.data) {
  39 + if (res.data.data.has.length > 0) {
  40 + this.proCoupon = res.data.data.has
  41 + localStorage.setItem("proCoupon", JSON.stringify(this.proCoupon))
  42 + this.chooseDefaultUseCard(res.data.data.has)//设置默认选中的优惠券
  43 + this.proCouponHas = true;
  44 + } else if (res.data.data.get.length > 0) {
  45 + this.proCoupon = {
  46 + title: '您有可领优惠券'
  47 + }
  48 + }
  49 + }
  50 + },
  51 + onFail: err => {
  52 + console.log('err', err)
  53 + }
  54 + });
  55 + },
  56 + // 设置默认选中的优惠券
  57 + chooseDefaultUseCard (has) {
  58 + if (has.length > 1) {
  59 + let useCard = has[0];
  60 + for (let i in has) {
  61 + console.log(Number(has[i].couponPrice) > Number(useCard.couponPrice))
  62 + if (Number(has[i].couponPrice) > Number(useCard.couponPrice)) {
  63 + useCard = has[i]
  64 + }
  65 + }
  66 + // console.log('useCard', useCard)
  67 + this.proCoupon = [useCard]
  68 + sessionStorage.setItem('useCard', JSON.stringify(useCard))
  69 +
  70 + } else {
  71 + sessionStorage.setItem('useCard', JSON.stringify(this.proCoupon[0]))
  72 + }
  73 + },
  74 + //领券
  75 + toCoupons () {
  76 + this.$router.push({
  77 + name: "CardBoxXST",
  78 + });
  79 + },
  80 + }
  81 +}
  82 +</script>
0 \ No newline at end of file 83 \ No newline at end of file
src/views/Service/component/AbroadDetail/AbroadDes.vue 0 → 100644
@@ -0,0 +1,157 @@ @@ -0,0 +1,157 @@
  1 +<template>
  2 + <div class="abroad_des">
  3 + <van-tabs class="tabs top_border" v-model="active" swipeable :ellipsis="false" color="#4092FF" scrollspy sticky>
  4 + <van-tab title="产品详情">
  5 + <div class="tag_item" v-if="detailData.productFeatures">
  6 + <p class="tag_title">产品特色</p>
  7 + <p class="tag_text" v-html="detailData.productFeatures"></p>
  8 + </div>
  9 + <div class="tag_item" v-if="detailData.productDescription">
  10 + <p class="tag_title">产品描述</p>
  11 + <div class="content_box">
  12 + <div class="content_all" :class="isOpen ? 'open' : ''">
  13 + <p v-html="detailData.productDescription"></p>
  14 + </div>
  15 + </div>
  16 + </div>
  17 + <div class="tag_item" v-if="
  18 + detailData.courseContentList &&
  19 + detailData.courseContentList[0].content != ''
  20 + ">
  21 + <p class="tag_title">服务内容</p>
  22 + <ul class="courseContent">
  23 + <li v-for="(n, i) in detailData.courseContentList" :key="n.id">
  24 + <span class="left" v-if="n.title">{{ n.title }}</span>
  25 + <h3>{{ n.content }}</h3>
  26 + <div class="item" v-for="(k, j) in n.courseFileList" :key="i + '' + j">
  27 + <div>
  28 + <video v-if="k.url && k.url.indexOf('.mp4') > -1" id="video" :src="k.url" poster="" controls="controls" windowlessvideo="true" playsinline="true" webkit-playsinline="true" x5-playsinline="true" x-webkit-airplay="allow" width="100%" height="260px" type="video/mp4"></video>
  29 + </div>
  30 + <div>
  31 + <img v-if="k.url && k.url.indexOf('.mp4') == -1" :src="k.url" />
  32 + </div>
  33 + </div>
  34 + </li>
  35 + </ul>
  36 + </div>
  37 + <div class="tag_item" v-if="courseTable.length > 0 && showCourseTable">
  38 + <p class="tag_title">课程表</p>
  39 + <div class="cardCont" v-for="(item, index) in courseTable" :key="index">
  40 + <table cellspacing="0" cellpadding="8">
  41 + <tbody v-html="item"></tbody>
  42 + </table>
  43 + </div>
  44 + </div>
  45 + <div class="tag_item" v-if="detailData.extraService">
  46 + <p class="tag_title">附送服务</p>
  47 + <p class="tag_text" v-html="detailData.extraService"></p>
  48 + </div>
  49 + <div class="tag_item" v-if="detailData.serviceGuarantees">
  50 + <p class="tag_title">服务保障和承诺</p>
  51 + <p class="tag_text" v-html="detailData.serviceGuarantees"></p>
  52 + </div>
  53 + </van-tab>
  54 + <van-tab title="费用说明" v-if="detailData.feeDescription">
  55 + <div class="tag_item">
  56 + <p class="tag_title">费用说明</p>
  57 + <p class="tag_text" v-html="detailData.feeDescription"></p>
  58 + </div>
  59 + </van-tab>
  60 + <van-tab title="订购须知" v-if="detailData.notice">
  61 + <div class="tag_item">
  62 + <p class="tag_title">订购须知</p>
  63 + <p class="tag_text" v-html="detailData.notice"></p>
  64 + </div>
  65 + </van-tab>
  66 + </van-tabs>
  67 + </div>
  68 +</template>
  69 +<script>
  70 +export default {
  71 + props: ['detailData'],
  72 + data () {
  73 + return {
  74 + courseTable: [], //课程表
  75 + active: 0,
  76 + isOpen: true,
  77 + showCourseTable:true
  78 + }
  79 + },
  80 + mounted () {
  81 + for (let i in this.detailData.courseScheduleList) {
  82 + this.getWeekCard(i);
  83 + }
  84 + },
  85 + methods: {
  86 + // 设置第几天的课程表
  87 + getWeekCard (index) {
  88 + var data = this.detailData.courseScheduleList[index].courseScheduleList;
  89 + var morning = [];
  90 + var afternoon = [];
  91 + var night = [];
  92 + data.forEach(function (k, j) {
  93 + if (k.type == 1 && k.content != "") {
  94 + morning.push(k);
  95 + } else if (k.type == 2 && k.content != "") {
  96 + afternoon.push(k);
  97 + } else if (k.type == 3 && k.content != "") {
  98 + night.push(k);
  99 + }
  100 + });
  101 + if (morning.length == 0 && afternoon.length == 0 && night.length == 0) {
  102 + this.showCourseTable = false;
  103 + }
  104 + var strMorning = "",
  105 + strAfternoon = "",
  106 + strNight = "";
  107 + if (morning.length > 0) {
  108 + strMorning = `<tr>
  109 + <td class="td_left" rowspan="${morning.length}">上午</td>
  110 + <td style="text-align: left;">${morning[0].content ? morning[0].content : "无安排"
  111 + }</td>
  112 + </tr>`;
  113 + morning.forEach(function (k, j) {
  114 + if (j > 0) {
  115 + strMorning += `<tr>
  116 + <td style="text-align: left;">${k.content ? k.content : "无安排"}</td>
  117 + </tr>`;
  118 + }
  119 + });
  120 + }
  121 + if (afternoon.length > 0) {
  122 + strAfternoon = `<tr>
  123 + <td class="td_left" rowspan="${afternoon.length}">下午</td>
  124 + <td style="text-align: left;">${afternoon[0].content ? afternoon[0].content : "无安排"
  125 + }</td>
  126 + </tr>`;
  127 + afternoon.forEach(function (k, j) {
  128 + if (j > 0) {
  129 + strAfternoon += `<tr>
  130 + <td style="text-align: left;">${k.content ? k.content : "无安排"}</td>
  131 + </tr>`;
  132 + }
  133 + });
  134 + }
  135 + if (night.length > 0) {
  136 + strNight = `<tr>
  137 + <td class="td_left" rowspan="${night.length}">晚上</td>
  138 + <td style="text-align: left;">${night[0].content ? night[0].content : "无安排"
  139 + }</td>
  140 + </tr>`;
  141 + night.forEach(function (k, j) {
  142 + if (j > 0) {
  143 + strNight += `<tr>
  144 + <td style="text-align: left;">${k.content ? k.content : "无安排"}</td>
  145 + </tr>`;
  146 + }
  147 + });
  148 + }
  149 + this.courseTable.push(strMorning + strAfternoon + strNight);
  150 + },
  151 + // 展开关闭院校简介
  152 + extend_btn () {
  153 + this.isOpen = !this.isOpen;
  154 + },
  155 + }
  156 +}
  157 +</script>
0 \ No newline at end of file 158 \ No newline at end of file
src/views/Service/component/AbroadDetail/AbroadEvaluate.vue 0 → 100644
@@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
  1 +<template>
  2 + <div class="abroad_evaluate">
  3 + <div class="rate" @click="handleEvaluate">
  4 + <div>
  5 + <van-rate v-model="evaluationData.evaluationScore" color="#FFCC00" :size="16" readonly />
  6 + <span>{{ evaluationData.evaluationScore }}</span>
  7 + </div>
  8 + <span>共{{evaluationData.evaluationCount}}个客户评价
  9 + <van-icon name="arrow" />
  10 + </span>
  11 + </div>
  12 + </div>
  13 +</template>
  14 +<script>
  15 +export default {
  16 + props:['courseId'],
  17 + data(){
  18 + return{
  19 + evaluationData: '',//评价
  20 + }
  21 + },
  22 + mounted(){
  23 + this.getEvaluationSummary()
  24 + },
  25 + methods:{
  26 + // 获取评价
  27 + getEvaluationSummary () {
  28 + this.mgop({
  29 + api: 'mgop.sz.hswsy.EvaluationSummary', // 必须
  30 + host: 'https://mapi.zjzwfw.gov.cn/',
  31 + dataType: 'JSON',
  32 + type: 'GET',
  33 + appKey: 'fuxgnukl+2001895516+edccpx', // 必须
  34 + headers: {
  35 + // 'isTestUrl': '1'
  36 + },
  37 + data: {
  38 + "courseId": this.courseId,
  39 + },
  40 + onSuccess: res => {
  41 + if (res.data.data) {
  42 + this.evaluationData = res.data.data
  43 + }
  44 + },
  45 + onFail: err => {
  46 + console.log('err', err)
  47 + }
  48 + });
  49 + },
  50 + // 点击评价进入评价详情页
  51 + handleEvaluate () {
  52 + this.$router.push({ name: "ServiceAbroadEvaluate", query: { courseId: this.courseId } });
  53 + },
  54 + }
  55 +}
  56 +</script>
0 \ No newline at end of file 57 \ No newline at end of file
src/views/Service/component/AbroadDetail/CountDown.vue 0 → 100644
@@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
  1 +<template>
  2 + <div class="count_down">
  3 + <div class="countDown" v-show="detailData.clusterTime ">
  4 + <div class="countDownTop">
  5 + <div>{{day}} {{detailData.applyCount>=detailData.minPeopleCount?'报名截止时间:':'团期截止倒计时'}}</div>
  6 + <div v-if="detailData.applyCount>=detailData.minPeopleCount||timeTamp * 1 < 0">{{detailData.periodOfValidity}}</div>
  7 + <div class="countDownTime" v-else>
  8 + <div class="countDownFont">{{ showTime.day }}</div>
  9 + 天
  10 + <div class="countDownFont">{{ showTime.hour }}</div>
  11 + 时
  12 + <div class="countDownFont">{{ showTime.minute }}</div>
  13 + 分
  14 + <div class="countDownFont">{{ showTime.second }}</div>
  15 + 秒
  16 + </div>
  17 + </div>
  18 + <!-- <div class="countDownTop" v-else>
  19 + <div>{{day}}</div>
  20 + </div> -->
  21 + <div class="countDownBottom">
  22 + <div>
  23 + <div class="countDownBottomyellow" v-show="detailData.minPeopleCount">
  24 + {{ detailData.clusterName }}
  25 + </div>
  26 + <span v-if="detailData.applyCount>=detailData.minPeopleCount">已报名 {{detailData.applyCount}}/{{detailData.stockCount}}{{detailData.unitName}}</span>
  27 + <span v-else>最低成团数{{detailData.minPeopleCount}}{{detailData.unitName}}/已报名{{detailData.applyCount}}{{detailData.unitName}}</span>
  28 + <!-- 已报名:<span>{{ detailData.applyCount }}</span><span>/{{ detailData.stockCount }}</span> -->
  29 + </div>
  30 + <div class="countDownAbout" @click="showPintuanAbout=true">关于拼团?</div>
  31 + </div>
  32 + </div>
  33 + <van-popup v-model="showPintuanAbout" round>
  34 + <div class="pintuan_about">
  35 + <img class="about_img" src="@/assets/service/tip.png" alt="">
  36 + <p class="about_title">拼团规则说明</p>
  37 + <p class="about_content">1、拼团展示默认为最近活动档期,选择其它档期请时刻注意成团动态。</p>
  38 + <p class="about_content">2、在限时截止后,报名人数未达最低成团数,则结束本团活动,系统将在72小时内,全额退还!</p>
  39 + <p class="about_content">3、报名人数达到最低成团要求后,则拼团成功,凡在报名截止时间内未达最大限团人数,则可放心参与。</p>
  40 + <p class="about_content">4、已成团的活动,除特殊情况等不可抗拒因素外,活动如期举行。</p>
  41 + <p class="about_know" @click="showPintuanAbout=false">我知道了</p>
  42 + </div>
  43 + </van-popup>
  44 + </div>
  45 +</template>
  46 +<script>
  47 +export default {
  48 + props: ['day','productId', 'packageArr', 'bindId', 'comboId'],
  49 + data () {
  50 + return {
  51 + timeTamp: "",
  52 + showTime: {
  53 + day: "",
  54 + hour: "",
  55 + minute: "",
  56 + second: "",
  57 + },
  58 + showPintuanAbout: false,
  59 + detailData: ''
  60 + }
  61 + },
  62 + watch: {
  63 + bindId (oldVal, newVal) {
  64 + this.getDateInfoById()
  65 + },
  66 + comboId (oldVal, newVal) {
  67 + this.getDateInfoById()
  68 + },
  69 + },
  70 + mounted () {
  71 + // console.log(this.detailData)
  72 + // console.log(this.packageArr)
  73 + this.getDateInfoById()
  74 +
  75 + },
  76 + methods: {
  77 + // 根据选择的档期显示成团状态
  78 + getDateInfoById () {
  79 + const productId = this.productId
  80 + const bindId = this.bindId
  81 + const comboId = this.comboId
  82 + // console.log(productId, bindId, comboId)
  83 + this.mgop({
  84 + api: 'mgop.sz.hswsy.DateInfoById', // 必须
  85 + host: 'https://mapi.zjzwfw.gov.cn/',
  86 + dataType: 'JSON',
  87 + type: 'GET',
  88 + appKey: 'fuxgnukl+2001895516+edccpx', // 必须
  89 + headers: {
  90 + // 'isTestUrl': '1'
  91 + },
  92 + data: {
  93 + "productId": productId,
  94 + "bindId": bindId,
  95 + "comboId": comboId,
  96 + },
  97 + onSuccess: res => {
  98 + console.log('套餐列表:', res.data.data);
  99 + if (res.data.data) {
  100 + this.detailData = res.data.data
  101 + let timer = setInterval(() => {
  102 + this.timeDown(); //倒计时
  103 + }, 1000);
  104 + this.$once("hook:beforeDestroy", () => {
  105 + clearInterval(timer); //清理定时器
  106 + console.log('清理定时器')
  107 + });
  108 + }
  109 + },
  110 + onFail: err => {
  111 + console.log('err', err)
  112 + }
  113 + });
  114 + },
  115 + //倒计时计算
  116 + timeDown () {
  117 + var clusterTime = Date.parse(new Date(this.detailData.clusterTime.replace(/\-/g, "/"))) + 60 * 60 * 24 * 1000;
  118 + var nowTime = Date.parse(new Date());
  119 + let timeTamp = clusterTime / 1000 - nowTime / 1000;
  120 + // console.log(timeTamp)
  121 + this.timeTamp = timeTamp;
  122 + // console.log(timeTamp)
  123 + let k = this.calculateDiffTime(timeTamp);
  124 + // console.log(k)
  125 + },
  126 + calculateDiffTime (timeDiff) {
  127 + var day = parseInt(timeDiff / 86400);
  128 + var hour = parseInt((timeDiff % 86400) / 3600);
  129 + var minute = parseInt(((timeDiff % 86400) % 3600) / 60);
  130 + var second = parseInt((((timeDiff % 86400) % 3600) % 60) % 60);
  131 +
  132 + this.showTime = {
  133 + day,
  134 + hour,
  135 + minute,
  136 + second,
  137 + };
  138 + day = day ? day + "天" : "";
  139 + hour = hour ? hour + "时" : "";
  140 + minute = minute ? minute + "分" : "";
  141 + second = second ? second + "秒" : "";
  142 + return day + hour + minute + second;
  143 + },
  144 + }
  145 +}
  146 +</script>
0 \ No newline at end of file 147 \ No newline at end of file
src/views/Service/component/ContactBox.vue
@@ -2,25 +2,26 @@ @@ -2,25 +2,26 @@
2 <div class="contact_box"> 2 <div class="contact_box">
3 <div class="flex_box"> 3 <div class="flex_box">
4 <p class="contact_title">出行人</p> 4 <p class="contact_title">出行人</p>
5 - <span class="contact_count">需添加{{limit}}位出行人</span> 5 + <span class="contact_count" v-if="people*limit">需添加{{child*limit}}位学生,{{people*limit}}位家长</span>
  6 + <span class="contact_count" v-else>只需添加{{child*limit}}位学生</span>
6 <span class="contact_btn" @click="enterSelectContact">选择出行人</span> 7 <span class="contact_btn" @click="enterSelectContact">选择出行人</span>
7 </div> 8 </div>
8 <p class="tip"> 9 <p class="tip">
9 - <van-icon class="icon" name="warning" /> 10 + <van-icon class="icon" name="warning" />
10 填写项须与出游所持证件保持一致 11 填写项须与出游所持证件保持一致
11 </p> 12 </p>
12 - <div class="contact_item" v-for="(item,index) in selectedContactArr" :key="index">  
13 - <van-icon class="close" name="close" @click="delContact(index)" />  
14 - <div class="info">  
15 - <p class="name">{{item.travelerName}}</p>  
16 - <p class="cardid">身份证{{item.travelerIdCard}}</p>  
17 - </div> 13 + <div class="contact_item" v-for="(item,index) in selectedContactArr" :key="index">
  14 + <van-icon class="close" name="close" @click="delContact(index)" />
  15 + <div class="info">
  16 + <p class="name">{{item.travelerName}}<span>{{item.userType==1?"学生":"家长"}}</span></p>
  17 + <p class="cardid">身份证{{item.travelerIdCard}}</p>
18 </div> 18 </div>
19 </div> 19 </div>
  20 + </div>
20 </template> 21 </template>
21 <script> 22 <script>
22 export default { 23 export default {
23 - props: ["limit"], 24 + props: ["limit", "people", "child"],
24 data () { 25 data () {
25 return { 26 return {
26 selectedContactArr: [],//选择的出行人 27 selectedContactArr: [],//选择的出行人
@@ -42,7 +43,7 @@ export default { @@ -42,7 +43,7 @@ export default {
42 // 删除联系人 43 // 删除联系人
43 delContact (index) { 44 delContact (index) {
44 this.selectedContactArr.splice(index, 1) 45 this.selectedContactArr.splice(index, 1)
45 - localStorage.setItem('selectedContactArr',JSON.stringify(this.selectedContactArr)) 46 + localStorage.setItem('selectedContactArr', JSON.stringify(this.selectedContactArr))
46 } 47 }
47 } 48 }
48 } 49 }
@@ -71,19 +72,19 @@ export default { @@ -71,19 +72,19 @@ export default {
71 color: #4092ff; 72 color: #4092ff;
72 font-weight: normal; 73 font-weight: normal;
73 } 74 }
74 - .tip{ 75 + .tip {
75 padding: 0 22px; 76 padding: 0 22px;
76 margin-bottom: 28px; 77 margin-bottom: 28px;
77 color: #999; 78 color: #999;
78 - .icon{  
79 - color: #FF9604; 79 + .icon {
  80 + color: #ff9604;
80 } 81 }
81 } 82 }
82 .contact_item { 83 .contact_item {
83 display: flex; 84 display: flex;
84 align-items: center; 85 align-items: center;
85 justify-content: space-between; 86 justify-content: space-between;
86 - border-top: 2px solid #F2F4F9; 87 + border-top: 2px solid #f2f4f9;
87 width: 702px; 88 width: 702px;
88 margin: 0 auto; 89 margin: 0 auto;
89 .close { 90 .close {
@@ -98,6 +99,15 @@ export default { @@ -98,6 +99,15 @@ export default {
98 .name { 99 .name {
99 font-size: 30px; 100 font-size: 30px;
100 font-weight: bold; 101 font-weight: bold;
  102 + span {
  103 + display: inline-block;
  104 + padding: 0 4px;
  105 + margin-left: 10px;
  106 + font-size: 22px;
  107 + font-weight: normal;
  108 + color: #4092ff;
  109 + border: 1px solid #e6e9ef;
  110 + }
101 } 111 }
102 .cardid { 112 .cardid {
103 margin-top: 6px; 113 margin-top: 6px;
src/views/Service/component/ServiceListFour.vue
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 <div class="flex_box"> 30 <div class="flex_box">
31 <div> 31 <div>
32 <p class="address">{{item.cityAddress}}{{item.cityAddress&&item.areaAddress?'·':''}}{{item.areaAddress}}</p> 32 <p class="address">{{item.cityAddress}}{{item.cityAddress&&item.areaAddress?'·':''}}{{item.areaAddress}}</p>
33 - <p class="price free"> <span class="limit">{{item.minPeopleCount}}成团</span></p> 33 + <p class="price free"> <span class="limit">{{item.minPeopleCount}}{{item.unitName}}成团</span></p>
34 </div> 34 </div>
35 <div class="pintuan" :class="item.applyCount>=item.stockCount?'disabled':''"> 35 <div class="pintuan" :class="item.applyCount>=item.stockCount?'disabled':''">
36 <p>{{item.applyCount>=item.stockCount?'已满团':'拼团中'}}</p> 36 <p>{{item.applyCount>=item.stockCount?'已满团':'拼团中'}}</p>
src/views/Service/component/ServiceListSecond.vue
@@ -28,7 +28,7 @@ @@ -28,7 +28,7 @@
28 </template> 28 </template>
29 </div> 29 </div>
30 <div class="flex_box"> 30 <div class="flex_box">
31 - <p class="price" v-if="item.showPrice>0"><span class="icon">¥</span>{{item.showPrice}}<span class="tint">起 </span><span class="limit">/{{item.minPeopleCount}}成团</span></p> 31 + <p class="price" v-if="item.showPrice>0"><span class="icon">¥</span>{{item.showPrice}}<span class="tint">起 </span><span class="limit">/{{item.minPeopleCount}}{{item.unitName}}成团</span></p>
32 <p class="price free" v-else>¥{{item.price}}</p> 32 <p class="price free" v-else>¥{{item.price}}</p>
33 <span class="count"> 33 <span class="count">
34 <van-icon name="eye-o" /> {{item.read_count}} 34 <van-icon name="eye-o" /> {{item.read_count}}