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 @@
  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 160 \ No newline at end of file
... ...
src/router/index.js
1 1 import Vue from 'vue'
2 2 import VueRouter from 'vue-router'
3 3 import Home from '@/views/Home/Home.vue'
  4 +import HomeUserInfo from '@/views/Home/HomeUserInfo.vue'
4 5  
5 6 import ServiceAbroadDetail from '@/views/Service/AbroadDetail.vue'
6 7 import ServiceAbroadEvaluate from '@/views/Service/AbroadEvaluate.vue'
... ... @@ -55,7 +56,14 @@ const routes = [{
55 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 68 path: '/abroad_detail',
61 69 name: 'ServiceAbroadDetail',
... ...
src/views/Home/Home.vue
... ... @@ -17,18 +17,6 @@
17 17 </div>
18 18 <HomeOrder></HomeOrder>
19 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 20 <div class="item" @click="handleMyCard">
33 21 <div class="left">
34 22 <van-icon class="icon" name="discount" />
... ... @@ -36,6 +24,13 @@
36 24 </div>
37 25 <van-icon name="arrow" />
38 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 34 <div class="item" @click="handelElder">
40 35 <div class="left">
41 36 <van-icon class="icon" name="friends-o" />
... ... @@ -122,6 +117,10 @@ export default {
122 117 handleMyCard () {
123 118 this.$router.push({ name: 'CardBoxXST' })
124 119 },
  120 + // 个人信息
  121 + handleMyInfo () {
  122 + this.$router.push({ name: 'HomeUserInfo' })
  123 + },
125 124 // 合伙人中心
126 125 handlePartner () {
127 126 this.$toast('暂未开放,敬请期待!');
... ... @@ -164,7 +163,7 @@ export default {
164 163 }
165 164 },
166 165 // 获取用户信息
167   - getUserInfo: function () {
  166 + getUserInfo () {
168 167 this.mgop({
169 168 api: 'mgop.sz.hswsy.getPortalUserByNum', // 必须
170 169 host: 'https://mapi.zjzwfw.gov.cn/',
... ... @@ -196,7 +195,6 @@ export default {
196 195 }
197 196 }
198 197 this.showChildList = true
199   -
200 198 },
201 199 onFail: err => {
202 200 console.log('err', err)
... ... @@ -220,6 +218,7 @@ export default {
220 218 //集团回调关闭页面
221 219 closeJT () {
222 220 this.showSchool = false
  221 + this.getUserInfo()
223 222 },
224 223 //查看是否有集团认证
225 224 getRZ () {
... ...
src/views/Home/HomeUserInfo.vue 0 → 100644
... ... @@ -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 91 \ No newline at end of file
... ...
src/views/Service/AbroadDetail.scss 0 → 100644
... ... @@ -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 732 \ No newline at end of file
... ...
src/views/Service/AbroadDetail.vue
... ... @@ -10,47 +10,19 @@
10 10 <img v-else src="@/assets/service/defCoure.jpg" alt="" />
11 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 18 </div>
44 19 <div class="course_price_free" v-else>
45 20 <span>¥ {{ detailData.price }}</span>
46 21 <span class="des">正在排期</span>
47 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 26 <p class="course_name">{{ detailData.course_name }}</p>
55 27 <p class="course_info">{{ detailData.course_info }}</p>
56 28 <p class="address" v-if="detailData.provinceAddress">
... ... @@ -63,15 +35,9 @@
63 35 detailData.addressDetail
64 36 }}
65 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 41 <div class="tag_box">
76 42 <template v-for="(tag, index) in detailData.course_labels">
77 43 <span class="tag" v-if="tag != ''" :key="index">{{ tag }}</span>
... ... @@ -81,94 +47,39 @@
81 47 <div class="package top_border">
82 48 <p class="package_title">套餐类型/日期</p>
83 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 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 59 <img class="more_icon" src="@/assets/service/more.png" alt="" />
91 60 <p class="more_text">查看更多</p>
92 61 </div>
93 62 </div>
  63 + <img class="notime" v-if="packageArr.length==0" src="@/assets/service/notime.png" alt="">
94 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 72 </div>
138 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 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 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 83 <div class="Collection">
173 84 <div class="box box1">
174 85 <div class="icon" @click="backHome">
... ... @@ -186,23 +97,10 @@
186 97 </div>
187 98 <div class="box box2">
188 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 101 <span v-else class="disabled">拼团请咨询客服</span>
191 102 </div>
192 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 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 105 <div class="show_tip_title" slot="title">
208 106 <img src="@/assets/service/tip.png" alt="">
... ... @@ -214,31 +112,25 @@
214 112 </div>
215 113 </template>
216 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 121 export default {
218 122 name: "ServiceAbroadDetail",
219 123 data () {
220 124 return {
221   - isOpen: true,
222 125 courseId: "",
223 126 detailData: "",
224   - active: 0,
225   - courseTable: [], //课程表
226 127 packageData: [], //未处理过格式的套餐表
  128 + packageActive: 0,
  129 + packageTypeActive: 0,
227 130 packageArr: [], //套餐时间价格
228   - evaluationData: '',//评价
229   - baseData: "", //基地信息
  131 + initPackageArr: false,//packageArr已生成
230 132 showCourseTable: true,
231   - showTime: {
232   - day: "",
233   - hour: "",
234   - minute: "",
235   - second: "",
236   - },
237   - timeTamp: "",
238 133 unionId: '',
239   - proCoupon: [],//优惠券
240   - proCouponHas: false,//优惠券已领取
241   - showPintuanAbout: false,
242 134 centerNo: '',
243 135 showTip: false,
244 136 PackageQuery: '',
... ... @@ -252,69 +144,42 @@ export default {
252 144 this.GetCourseDetail();
253 145 },
254 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 165 this.PackageQuery = query
301 166 const AbroadDetailTipChecked = sessionStorage.getItem('AbroadDetailTipChecked');
302   - if(AbroadDetailTipChecked){
  167 + if (AbroadDetailTipChecked) {
303 168 this.$router.push({ name: "ServiceDatePackage", query: query });
304   - }else{
  169 + } else {
305 170 this.showTip = true;
306 171 }
307 172 },
308 173 tipConfirm () {
309   - if(this.tipChecked){
310   - sessionStorage.setItem('AbroadDetailTipChecked',1)
  174 + if (this.tipChecked) {
  175 + sessionStorage.setItem('AbroadDetailTipChecked', 1)
311 176 }
312 177 this.$router.push({ name: "ServiceDatePackage", query: this.PackageQuery });
313 178 },
314   - // 获取品详情
  179 + // 获取品详情
315 180 GetCourseDetail () {
316 181 if (!this.courseId) {
317   - this.$toast.fail('品id缺失,请从正确的途径访问')
  182 + this.$toast.fail('品id缺失,请从正确的途径访问')
318 183 return;
319 184 }
320 185 this.$toast.loading({
... ... @@ -339,7 +204,7 @@ export default {
339 204 this.$toast.clear();
340 205 if (res.data.data && res.data.data.id !== 0) {
341 206 let detailData = res.data.data;
342   - // console.log(detailData)
  207 + console.log('产品详情:', detailData)
343 208 detailData.course_labels = detailData.course_labels?.split(",");
344 209 this.detailData = detailData;
345 210 localStorage.setItem(
... ... @@ -352,21 +217,6 @@ export default {
352 217 })
353 218 );
354 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 220 } else {
371 221 let message = res.data.message;
372 222 if (!message) {
... ... @@ -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 235 getPackageData () {
461 236 let startDate = this.Moment().format("YYYY-MM-DD");
... ... @@ -475,6 +250,7 @@ export default {
475 250 "endDate": endDate,
476 251 },
477 252 onSuccess: res => {
  253 + console.log('套餐列表:', res.data.data);
478 254 if (res.data.data) {
479 255 let allPackage = res.data.data;
480 256 let usefulPackage = [];
... ... @@ -483,7 +259,6 @@ export default {
483 259 usefulPackage.push(allPackage[i]);
484 260 }
485 261 }
486   - console.log(usefulPackage);
487 262 this.packageData = usefulPackage;
488 263 localStorage.setItem(
489 264 "packageData",
... ... @@ -499,7 +274,7 @@ export default {
499 274 },
500 275 // 设置套餐价格
501 276 setPackageArr () {
502   - console.log(this.packageData);
  277 + console.log('含套餐的日期:', this.packageData);
503 278 let packageArr = [];
504 279 for (let i in this.packageData) {
505 280 let packageDate = this.Moment(
... ... @@ -522,108 +297,30 @@ export default {
522 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 314 packageArr.push({
531 315 day: packageDate.format("M/D"),
532 316 date: packageDate.format("YYYY-MM-DD"),
533 317 week: week,
534   - marketPrice: this.packageData[i]?.comboList[0]?.actualPrice,
  318 + marketPrice: marketPrice,
  319 + comboInfoList: comboInfoList,
535 320 });
536 321 }
537 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 326 contactService () {
... ... @@ -635,707 +332,13 @@ export default {
635 332 backHome () {
636 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 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 345 \ No newline at end of file
... ...
src/views/Service/CheckOrder.vue
... ... @@ -6,7 +6,7 @@
6 6 <div>
7 7 <p class="goods_title">{{showCourseData.course_name}}</p>
8 8 <p class="package_name">套餐名称:{{selectCombo.comboName}}</p>
9   - <p class="count">数量:x{{count}}</p>
  9 + <p class="count">数量:x{{count}}{{selectComboUnitName}}</p>
10 10 </div>
11 11 </div>
12 12 <div class="bottom">
... ... @@ -22,7 +22,7 @@
22 22 </div>
23 23 </div>
24 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 26 </div>
27 27 <div class="card top_border">
28 28 <p>服务承诺和保障</p>
... ... @@ -56,6 +56,7 @@ export default {
56 56 useCard: '',
57 57 orderDetail: '',
58 58 selectCombo: '',//当前套餐信息
  59 + selectComboUnitName:'',//套餐单位 人或份
59 60 showCourseData: '',//当前课程的信息
60 61 selectCombo: '',//已选择的套餐
61 62 userInfo: '',//支付用
... ... @@ -76,6 +77,7 @@ export default {
76 77 if (selectCombo) {
77 78 this.selectCombo = JSON.parse(selectCombo)
78 79 }
  80 + this.selectComboUnitName = sessionStorage.getItem('selectComboUnitName')
79 81  
80 82 // 如果有优惠券,就展示
81 83 let useCard = localStorage.getItem('useCard')
... ... @@ -117,11 +119,20 @@ export default {
117 119 // 出行人数量判断
118 120 let selectedContactArr = localStorage.getItem('selectedContactArr');
119 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 134 return;
123 135 }
124   -
125 136 // 协议勾选
126 137 if (!this.checked) {
127 138 this.$toast.fail('请先阅读并同意用户协议');
... ... @@ -163,7 +174,6 @@ export default {
163 174 // 使用后移除优惠券,防止返回继续使用
164 175 localStorage.removeItem('useCard')
165 176 this.$router.push({ name: 'ServiceOrderXST', query: { active: 1, showChatGroupUrl: 1 } })
166   -
167 177 } else {
168 178 // 使用后移除优惠券,防止返回继续使用
169 179 localStorage.removeItem('useCard')
... ...
src/views/Service/DatePackage.vue
1 1 <template>
2   - <div id="datePackage">
  2 + <div id="datePackage" v-if="comboList">
3 3 <!-- <div class="tag_item">
4 4 <p class="tag_title">商品名称</p>
5 5 <p class="package_name">{{showCourseData.course_name}}</p>
6 6 </div> -->
7 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 10 <van-calendar v-model="showCalendar" :default-date="defaultDate" @confirm="chooseDate" :show-confirm="false" color="#3F92FF" :formatter="formatCalendar" />
11 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 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 21 </div>
20 22 <div class="tag_item" v-if="date">
21   - <p class="tag_title">套餐</p>
  23 + <p class="tag_title">套餐类型</p>
22 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 26 </div>
26 27 </div>
27 28 <div class="tag_item">
28 29 <div class="tag_title tag_title_flex">
29   - <span>数量</span>
  30 + <span>请选择套餐数量</span>
30 31 <div class="tag_title_right">
31 32 <span class="btn" @click="countReduce">-</span>
32 33 <span class="count">{{count}}</span>
... ... @@ -35,20 +36,26 @@
35 36 </div>
36 37 <div class="package_num">
37 38 <span>库存数量({{numSecond}} /</span>
38   - <span class="tint">{{numOne+numSecond}})</span>
  39 + <span class="tint">{{numOne+numSecond}}{{comboList[Index1].unitName}})</span>
39 40 </div>
40 41 </div>
  42 + <p class="package_des" v-if="comboList[Index1].comboInfoList[Index2].comboDescrption">套餐说明<br>{{comboList[Index1].comboInfoList[Index2].comboDescrption}}</p>
41 43 <div class="Collection">
42 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 46 </div>
45 47 <div class="box box2">
46 48 <span @click="checkOrder()">去下单</span>
47 49 </div>
48 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 55 </div>
50 56 </template>
51 57 <script>
  58 +import schoolAdd from '@/views/Travel/component/schoolAdd'
52 59 export default {
53 60 name: 'ServiceDatePackage',
54 61 data () {
... ... @@ -58,12 +65,14 @@ export default {
58 65 packageData: '',
59 66 showCourseData: '',
60 67 comboList: '',
61   - active: 0,//选中的排期
  68 + Index1: 0,//选中的档期
  69 + Index2: 0,//选中的套餐
62 70 showCalendar: false,
63 71 count: 1,
64 72 days: 1,
65 73 numOne: 0,
66 74 numSecond: 0,
  75 + showSchool: false
67 76 }
68 77 },
69 78 mounted () {
... ... @@ -93,7 +102,7 @@ export default {
93 102 },
94 103 methods: {
95 104 // 获取库存
96   - GetOrderPayCount () {
  105 + GetOrderPayCount (bindId) {
97 106 let showCourseData = JSON.parse(localStorage.getItem('showCourseData'))
98 107 this.mgop({
99 108 api: 'mgop.sz.hswsy.OrderPayCount', // 必须
... ... @@ -105,6 +114,7 @@ export default {
105 114 // 'isTestUrl': '1'
106 115 },
107 116 data: {
  117 + "bindId":bindId,
108 118 "productId": showCourseData.id,
109 119 "startDate": this.date,
110 120 },
... ... @@ -147,12 +157,16 @@ export default {
147 157 },
148 158 // 选择排期
149 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 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 172 chooseDate (date) {
... ... @@ -167,7 +181,8 @@ export default {
167 181 return;
168 182 }
169 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 186 this.showCalendar = false;
172 187 this.setComboList()
173 188 },
... ... @@ -176,21 +191,21 @@ export default {
176 191 // console.log(day)
177 192 for (let i in this.packageData) {
178 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 197 return day;
183 198 },
184 199 // 根据日期设置套餐
185 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 201 for (let i in this.packageData) {
192 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 209 break;
195 210 }
196 211 }
... ... @@ -206,20 +221,28 @@ export default {
206 221 if (this.count > this.numSecond) {
207 222 this.$toast('库存不足');
208 223  
209   - }
210   - else if (!this.date) {
211   - this.$toast('请选择日期');
212   - } else if (this.active == -1) {
213   - this.$toast('请选择时间段');
214 224 } else {
215 225 const query = {
216 226 date: this.date,
217 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 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 248 </script>
... ... @@ -244,6 +267,8 @@ export default {
244 267 }
245 268 }
246 269 .package_name {
  270 + display: flex;
  271 + justify-content: space-between;
247 272 font-size: 28px;
248 273 width: 100%;
249 274 background: #f5f6fa;
... ... @@ -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 349 .Collection {
316 350 background-color: white;
317 351 position: fixed;
... ...
src/views/Service/SelectContact.vue
... ... @@ -31,10 +31,11 @@
31 31 </template>
32 32 <script>
33 33 import AddChildPopupGroup from '@/views/Home/component/AddChildPopupGroup'
  34 +import IdentityCodeValid from '@/common/validateIdent'
34 35 export default {
35 36 data () {
36 37 return {
37   - limit: '',
  38 + limit: '',//数量
38 39 hideParent: false,
39 40 contactList: [],
40 41 showAddChildPopupGroup: false
... ... @@ -43,7 +44,6 @@ export default {
43 44 mounted () {
44 45 this.limit = this.$route.query.limit;
45 46 this.hideParent = this.$route.query.hideParent ? true : false;
46   - console.log(this.hideParent)
47 47 this.getContactList()
48 48 },
49 49 methods: {
... ... @@ -120,23 +120,21 @@ export default {
120 120 if ((!contactList[i].travelerIdCard || !contactList[i].gender) && !this.hideParent) {
121 121 this.$toast('请先完善您选择的出行人信息')
122 122 return;
  123 + } else if (!IdentityCodeValid(contactList[i].travelerIdCard)) {
  124 + this.$toast(`${contactList[i].travelerName}的身份证有误,请重新完善修改`)
  125 + return;
123 126 } else {
124 127 selectedArr.push({
125 128 travelerName: contactList[i].travelerName,
126 129 travelerMobile: contactList[i].travelerMobile,
127 130 travelerNum: contactList[i].travelerNum,
128   - travelerIdCard:contactList[i].travelerIdCard,
  131 + travelerIdCard: contactList[i].travelerIdCard,
129 132 userType: contactList[i].userType,
130 133 })
131 134 }
132 135 }
133 136 }
134 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 139 let hasStudent = false;
142 140 for (let i in selectedArr) {
... ...
src/views/Service/component/AbroadDetail/AbroadBase.vue 0 → 100644
... ... @@ -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 54 \ No newline at end of file
... ...
src/views/Service/component/AbroadDetail/AbroadCoupon.vue 0 → 100644
... ... @@ -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 83 \ No newline at end of file
... ...
src/views/Service/component/AbroadDetail/AbroadDes.vue 0 → 100644
... ... @@ -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 158 \ No newline at end of file
... ...
src/views/Service/component/AbroadDetail/AbroadEvaluate.vue 0 → 100644
... ... @@ -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 57 \ No newline at end of file
... ...
src/views/Service/component/AbroadDetail/CountDown.vue 0 → 100644
... ... @@ -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 147 \ No newline at end of file
... ...
src/views/Service/component/ContactBox.vue
... ... @@ -2,25 +2,26 @@
2 2 <div class="contact_box">
3 3 <div class="flex_box">
4 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 7 <span class="contact_btn" @click="enterSelectContact">选择出行人</span>
7 8 </div>
8 9 <p class="tip">
9   - <van-icon class="icon" name="warning" />
  10 + <van-icon class="icon" name="warning" />
10 11 填写项须与出游所持证件保持一致
11 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 18 </div>
19 19 </div>
  20 + </div>
20 21 </template>
21 22 <script>
22 23 export default {
23   - props: ["limit"],
  24 + props: ["limit", "people", "child"],
24 25 data () {
25 26 return {
26 27 selectedContactArr: [],//选择的出行人
... ... @@ -42,7 +43,7 @@ export default {
42 43 // 删除联系人
43 44 delContact (index) {
44 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 72 color: #4092ff;
72 73 font-weight: normal;
73 74 }
74   - .tip{
  75 + .tip {
75 76 padding: 0 22px;
76 77 margin-bottom: 28px;
77 78 color: #999;
78   - .icon{
79   - color: #FF9604;
  79 + .icon {
  80 + color: #ff9604;
80 81 }
81 82 }
82 83 .contact_item {
83 84 display: flex;
84 85 align-items: center;
85 86 justify-content: space-between;
86   - border-top: 2px solid #F2F4F9;
  87 + border-top: 2px solid #f2f4f9;
87 88 width: 702px;
88 89 margin: 0 auto;
89 90 .close {
... ... @@ -98,6 +99,15 @@ export default {
98 99 .name {
99 100 font-size: 30px;
100 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 112 .cardid {
103 113 margin-top: 6px;
... ...
src/views/Service/component/ServiceListFour.vue
... ... @@ -30,7 +30,7 @@
30 30 <div class="flex_box">
31 31 <div>
32 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 34 </div>
35 35 <div class="pintuan" :class="item.applyCount>=item.stockCount?'disabled':''">
36 36 <p>{{item.applyCount>=item.stockCount?'已满团':'拼团中'}}</p>
... ...
src/views/Service/component/ServiceListSecond.vue
... ... @@ -28,7 +28,7 @@
28 28 </template>
29 29 </div>
30 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 32 <p class="price free" v-else>¥{{item.price}}</p>
33 33 <span class="count">
34 34 <van-icon name="eye-o" /> {{item.read_count}}
... ...