Quellcode durchsuchen

add LCY liffPage

Sherry vor 1 Jahr
Ursprung
Commit
a52e62dd13
44 geänderte Dateien mit 24774 neuen und 1 gelöschten Zeilen
  1. 11378
    0
      src/fe/css/all.css
  2. 1
    0
      src/fe/css/all.css.map
  3. 26
    0
      src/fe/css/all.scss
  4. 17
    0
      src/fe/css/component/_button.scss
  5. 141
    0
      src/fe/css/component/_form.scss
  6. 106
    0
      src/fe/css/component/_loading.scss
  7. 112
    0
      src/fe/css/component/_modal.scss
  8. 18
    0
      src/fe/css/component/_section.scss
  9. 39
    0
      src/fe/css/component/_tag.scss
  10. 32
    0
      src/fe/css/component/_userPhoto.scss
  11. 113
    0
      src/fe/css/layout/_body.scss
  12. 13
    0
      src/fe/css/module/_ellipsis.scss
  13. 8
    0
      src/fe/css/module/_frosted.scss
  14. 22
    0
      src/fe/css/module/_img-scale.scss
  15. 32
    0
      src/fe/css/module/_px2em.scss
  16. 15
    0
      src/fe/css/page/_method.scss
  17. 115
    0
      src/fe/css/page/_passport.scss
  18. 5
    0
      src/fe/css/page/_register.scss
  19. 27
    0
      src/fe/css/variable/_base.scss
  20. 10224
    0
      src/fe/css/vendor/_bootstrap.scss
  21. 13
    0
      src/fe/css/vendor/_swiper.min.scss
  22. BIN
      src/fe/images/arrow-down.png
  23. BIN
      src/fe/images/form-tick.png
  24. BIN
      src/fe/images/passport-bg.png
  25. BIN
      src/fe/images/passport-intro.png
  26. BIN
      src/fe/images/select-arrow.png
  27. BIN
      src/fe/images/solar_camera-linear.png
  28. 520
    1
      src/fe/index.html
  29. 146
    0
      src/fe/js/base.js
  30. 188
    0
      src/fe/js/passport.js
  31. 321
    0
      src/fe/js/register.js
  32. 140
    0
      src/fe/js/services/index.js
  33. 85
    0
      src/fe/js/services/userModel.js
  34. 212
    0
      src/fe/js/tagData.json
  35. 70
    0
      src/fe/js/type/index.ts
  36. 267
    0
      src/fe/js/utlis.js
  37. 12
    0
      src/fe/lib/cookie.js
  38. 6
    0
      src/fe/lib/current-device.min.js
  39. 11
    0
      src/fe/lib/gsap.min.js
  40. 2
    0
      src/fe/lib/jquery-3.5.1.min.js
  41. 320
    0
      src/fe/lib/jquery.mobile.touch.min.js
  42. 2
    0
      src/fe/lib/jquery.nicescroll.min.js
  43. 1
    0
      src/fe/lib/line-sdk.js
  44. 14
    0
      src/fe/lib/swiper.min.js

+ 11378
- 0
src/fe/css/all.css
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 1
- 0
src/fe/css/all.css.map
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 26
- 0
src/fe/css/all.scss Datei anzeigen

1
+@charset "UTF-8";
2
+
3
+@import "vendor/bootstrap";   //4.4.1版
4
+@import "vendor/swiper.min";   //5.3.1版
5
+
6
+@import "module/ellipsis";
7
+@import "module/img-scale";
8
+@import "module/px2em";
9
+@import "module/frosted";
10
+
11
+@import "variable/base";
12
+
13
+@import "component/loading";
14
+@import "component/tag";
15
+@import "component/button";
16
+@import "component/form";
17
+@import "component/userPhoto";
18
+@import "component/modal";
19
+@import "component/section";
20
+
21
+@import "layout/body";
22
+
23
+@import "page/register";
24
+@import "page/passport";
25
+@import "page/method";
26
+

+ 17
- 0
src/fe/css/component/_button.scss Datei anzeigen

1
+@charset "UTF-8";
2
+.button {
3
+    background-color: #2AACE2;
4
+    width: 100%;
5
+    padding: 1.8em;
6
+    border-radius: 1em;
7
+    p {
8
+        text-align: center;
9
+        font-size: 1.6em;
10
+        color: $c-whiite;
11
+        margin-bottom: 0;
12
+    }
13
+    &.disable {
14
+        background-color: $c-gray-lighten;
15
+        pointer-events: none;
16
+    }
17
+}

+ 141
- 0
src/fe/css/component/_form.scss Datei anzeigen

1
+@charset "UTF-8";
2
+.form {
3
+    width: 100%;
4
+    display: flex;
5
+    justify-content: center;
6
+    flex-wrap: wrap;
7
+    legend {
8
+        font-size: inherit;
9
+    }
10
+    label {
11
+        display: block;
12
+    }
13
+    input[type="checkbox"] ,input[type="radio"] {
14
+        -webkit-appearance: none;
15
+        appearance: none;
16
+        background-color: #fff;
17
+        margin: 0;
18
+        display: none;
19
+        // &:checked + label {
20
+        //     background: $c-blue-active;
21
+        //     border: 1px solid $c-blue;
22
+        // }
23
+    }
24
+    &__changepic {
25
+        position: absolute;
26
+        width: 10em;
27
+        img {
28
+            width: 100%;
29
+            height: 100%;
30
+        }
31
+    }
32
+    &__item {
33
+        padding: 0;
34
+        width: 100%;
35
+        border: none;
36
+        margin-bottom: 1em;
37
+        &-photo {
38
+            margin-bottom: 3em;
39
+        }
40
+        &-agree {
41
+            background: none;
42
+            margin-bottom: 0.5em;
43
+            &::before {
44
+                display: none;
45
+            }
46
+            &::after {
47
+                display: none;
48
+            }
49
+            .label {
50
+                flex: 0 0 100%;
51
+                display: flex;
52
+                justify-content: center;
53
+                align-items: center;
54
+                p {
55
+                    display: inline-block;
56
+                    font-size: 1.3em;
57
+                    margin-bottom: 0;
58
+                }
59
+                &__checkbox {
60
+                    display: inline-block;
61
+                    width: 1em;
62
+                    height: 1em;
63
+                    border: 1px solid $c-black;
64
+                    margin-right: 0.5em;
65
+                    display: flex;
66
+                    justify-content: center;
67
+                    align-items: center;
68
+                    &::before {
69
+                        content: "";
70
+                        width: 80%;
71
+                        height: 80%;
72
+                        display: none;
73
+                        background: url(../images/form-tick.png) no-repeat center center/contain;
74
+                    }
75
+                }
76
+            }
77
+            input {
78
+                display: none;
79
+                flex: 0 0 auto;
80
+                &:checked + .label__checkbox {
81
+                    background-color: $c-whiite;
82
+                    &::before {
83
+                        display: block;
84
+                    }
85
+                }
86
+            }
87
+        }
88
+        .goToActivity {
89
+            color: $c-blue-bright;
90
+            text-decoration: underline;
91
+        }
92
+    }
93
+    &__ques {
94
+        margin-bottom: 1em;
95
+        p {
96
+            font-size: 2em;
97
+            font-weight: 400;
98
+            white-space: nowrap;
99
+            margin: 0;
100
+            color: $c-black;
101
+        }
102
+    }
103
+    &__options {
104
+        &__item {
105
+            margin-bottom: 1.8em;
106
+        }
107
+    }
108
+    &__input {
109
+        width: 100%;
110
+        border: 0.1em solid $c-gray-lighten;
111
+        border-radius: 1em;
112
+        padding: 1em 1.5em;
113
+        margin-bottom: 1.8em;
114
+        input, select {
115
+            width: 100%;
116
+            border: none;
117
+            background-color: transparent;
118
+            font-size: 1.4em;
119
+            color: #747474;
120
+            &:focus, &:focus-visible, &:hover {
121
+                outline: none;
122
+            }
123
+        }
124
+        select {
125
+            background: url(../images/select-arrow.png) no-repeat center right/0.7em auto;
126
+        }
127
+        ::placeholder {
128
+            color: $c-gray-lighten;
129
+            opacity: 1; /* Firefox */
130
+        }
131
+        
132
+        ::-ms-input-placeholder { /* Edge 12 -18 */
133
+            color: $c-gray-lighten;
134
+        }
135
+    }
136
+    .button {
137
+        p {
138
+            white-space: nowrap;
139
+        }
140
+    }
141
+}

+ 106
- 0
src/fe/css/component/_loading.scss Datei anzeigen

1
+.loading {
2
+    // opacity: 0;
3
+    // visibility: hidden;
4
+    position: fixed;
5
+    top: 0;
6
+    left: 0;
7
+    width: 100%;
8
+    height: 100%;
9
+    display: flex;
10
+    justify-content: center;
11
+    align-items: center;
12
+    z-index: 2999;
13
+    background: $c-blue-bg;
14
+    &__box {
15
+        position: absolute;
16
+        top: 50%;
17
+        left: 50%;
18
+        transform: translate(-50%,-50%);
19
+        width: 100%;
20
+        height: 100%;
21
+        display: flex;
22
+        justify-content: center;
23
+        align-items: center;
24
+        z-index: 1;
25
+    }
26
+
27
+    &__ani {
28
+        position: relative;
29
+        width: em(130);
30
+        height: em(130);
31
+        border-radius: 100%;
32
+        border: 2px solid transparent;
33
+        border-color: transparent rgba($c-blue-bright, 0.5) transparent rgba($c-blue-bright, 0.5);
34
+        animation: rotate-loading 1.5s linear 0s infinite normal;
35
+        transform-origin: 50% 50%;
36
+
37
+        -webkit-transition: all 0.5s ease-in-out;
38
+        -moz-transition: all 0.5s ease-in-out;
39
+        -ms-transition: all 0.5s ease-in-out;
40
+        -o-transition: all 0.5s ease-in-out;
41
+        transition: all 0.5s ease-in-out;
42
+    }
43
+
44
+    &__text {
45
+        // -moz-animation: loading-text-opacity 2s linear 0s infinite normal;
46
+        // -o-animation: loading-text-opacity 2s linear 0s infinite normal;
47
+        // -webkit-animation: loading-text-opacity 2s linear 0s infinite normal;
48
+        // animation: loading-text-opacity 2s linear 0s infinite normal;
49
+        color: rgba($c-blue-bright, 0.8);
50
+        font-size: em(18);
51
+        font-weight: 400;
52
+        line-height: 1;
53
+        opacity: 1;
54
+        position: absolute;
55
+        top: 50%;
56
+        left: 50%;
57
+        transform: translate(-50%,-50%);
58
+        text-align: center;
59
+        text-transform: uppercase;
60
+    }
61
+
62
+    @keyframes picIn {
63
+        0% {
64
+            transform: scale(0.7);
65
+        }
66
+        100% {
67
+            transform: scale(1);
68
+        }
69
+    }
70
+
71
+    @keyframes rotate-loading {
72
+        0% {
73
+            transform: rotate(0deg);
74
+            -ms-transform: rotate(0deg);
75
+            -webkit-transform: rotate(0deg);
76
+            -o-transform: rotate(0deg);
77
+            -moz-transform: rotate(0deg);
78
+        }
79
+
80
+        100% {
81
+            transform: rotate(360deg);
82
+            -ms-transform: rotate(360deg);
83
+            -webkit-transform: rotate(360deg);
84
+            -o-transform: rotate(360deg);
85
+            -moz-transform: rotate(360deg);
86
+        }
87
+    }
88
+
89
+    @keyframes loading-text-opacity {
90
+        0% {
91
+            opacity: 0
92
+        }
93
+
94
+        20% {
95
+            opacity: 0
96
+        }
97
+
98
+        50% {
99
+            opacity: 1
100
+        }
101
+
102
+        100% {
103
+            opacity: 0
104
+        }
105
+    }
106
+}

+ 112
- 0
src/fe/css/component/_modal.scss Datei anzeigen

1
+@charset "UTF-8";
2
+.modal {
3
+    .close {
4
+        font-size: 1rem;
5
+    }
6
+    .close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {
7
+        opacity: 1;
8
+        outline: none;
9
+    }
10
+    &-backdrop.fade {
11
+        opacity: 0;
12
+        @include frosted(transparent,0,0);
13
+        transition: 0.3s linear;
14
+    }
15
+    &-backdrop.show {
16
+        opacity: 1;
17
+        @include frosted(#000,0.6,2px);
18
+        border-radius: 0;
19
+    }
20
+    &-dialog {
21
+        max-width: em(560);
22
+    }
23
+    &-content {
24
+        background-color: #ffffff;
25
+        box-shadow: 0px 0px 63px rgba(0, 0, 0, 0.1);
26
+        border-radius: 1.25em;
27
+        border: 2px solid #2AACE2;
28
+        overflow: hidden;
29
+    }
30
+    &-header {
31
+        display: block;
32
+        text-align: center;
33
+        border: none;
34
+        padding: 1.5em em(15) 0.2em;
35
+    }
36
+    &-body {
37
+        padding-bottom: 1em;
38
+        .alert-message{
39
+            text-align: center;
40
+            font-size: 2cqmax;
41
+            margin-bottom: 0;
42
+            color: $c-blue-bright;
43
+        }
44
+    }
45
+    &-footer {
46
+        border: none;
47
+        border-radius: 0;
48
+        padding: em(15) em(15) em(30);
49
+        justify-content: center;
50
+        &:active,&:focus,&:focus-visible,&:focus-within,&:hover,&:visited {
51
+            outline: none;
52
+        }
53
+        .buttons {
54
+            width: 100%;
55
+            display: flex;
56
+            justify-content: center;
57
+            align-items: center;
58
+        }
59
+        .button {
60
+            opacity: 1;
61
+            left: auto;
62
+            transform: none;
63
+            display: flex;
64
+            justify-content: center;
65
+            align-items: center;
66
+            width: em(400);
67
+            height: em(85);
68
+            padding-bottom: 0;
69
+            background: $c-blue-bright;
70
+            border-radius: em(85);
71
+            box-shadow: 0 0 15px rgba(0,0,0,0.3);
72
+            p {
73
+                font-size: 1.8em;
74
+                font-weight: 300;
75
+                color: $c-whiite;
76
+            }
77
+            &:after {
78
+                display: none;
79
+            }
80
+            &__apart {
81
+                &-disagree {
82
+                    background: #eec082;
83
+                    border: 3px solid #b97453;
84
+                    text-shadow: 0 3px 3px rgba(#000, 0.3);
85
+                }
86
+            }
87
+        }
88
+    }
89
+    &__logo {
90
+        display: inline-block;
91
+        width: em(180);
92
+        img {
93
+            width: 100%;
94
+            height: auto;
95
+        }
96
+    }
97
+    &__close {
98
+        margin: 0;
99
+        padding: 0;
100
+        position: absolute;
101
+        top: em(20);
102
+        right: em(20);
103
+        opacity: 1;
104
+        span {
105
+            color: #fff;
106
+            font-weight: 700;
107
+            font-size: em(20);
108
+            line-height: 1;
109
+            display: inline-block;
110
+        }
111
+    }
112
+}

+ 18
- 0
src/fe/css/component/_section.scss Datei anzeigen

1
+.section {
2
+    opacity: 0;
3
+    visibility: hidden;
4
+    position: absolute;
5
+    overflow-y: auto;
6
+    overflow-x: hidden;
7
+    width: 100%;
8
+    height: 100%;
9
+    top: 0;
10
+    left: 0;
11
+    &__container {
12
+        position: relative;
13
+        width: em(560);
14
+        margin: 0 auto;
15
+        padding-top: 0;
16
+        transform-origin: center top;
17
+    }
18
+}

+ 39
- 0
src/fe/css/component/_tag.scss Datei anzeigen

1
+@charset "UTF-8";
2
+
3
+.tags {
4
+    width: 100%;
5
+    display: flex;
6
+    flex-wrap: wrap;
7
+    .tags__item {
8
+        border: $c-gray 0.15em solid;
9
+        border-radius: 0.8em;
10
+        padding: 0.8em 0.55em;
11
+        &-md {
12
+            width: 30%;
13
+            margin-right: 5%;
14
+            &:nth-child(3n) {
15
+                margin-right: 0;
16
+            }
17
+        }
18
+        &-lg {
19
+            width: 100%;
20
+        }
21
+        label {
22
+            margin-bottom: 0;
23
+        }
24
+        p {
25
+            text-align: center;
26
+            font-size: 1.4em;
27
+            margin-bottom: 0;
28
+            color: $c-gray;
29
+            font-weight: 400;
30
+        }
31
+        &.checked {
32
+            border: $c-blue 0.15em solid;
33
+            background-color: $c-blue-active;
34
+            p {
35
+                color: $c-blue;
36
+            }
37
+        }
38
+    }
39
+}

+ 32
- 0
src/fe/css/component/_userPhoto.scss Datei anzeigen

1
+@charset "UTF-8";
2
+.photo {
3
+  position: relative;
4
+  &__img {
5
+    width: 16em;
6
+    height: 16em;
7
+    // border: 1px solid red;
8
+    border-radius: 50%;
9
+    overflow: hidden;
10
+    margin: 0 auto;
11
+    img {
12
+      display: block;
13
+      object-fit: cover;
14
+      object-position: center;
15
+      width: 100%;
16
+      height: 100%;
17
+    }
18
+  }
19
+  &__icon {
20
+    width: 4em;
21
+    position: absolute;
22
+    bottom: 0;
23
+    left: 61%;
24
+    img {
25
+      width: 100%;
26
+      height: auto;
27
+    }
28
+  }
29
+  .fileInput {
30
+    display: none;
31
+  }
32
+}

+ 113
- 0
src/fe/css/layout/_body.scss Datei anzeigen

1
+@charset "UTF-8";
2
+html,body {
3
+    width: 100%;
4
+    height: 100%;
5
+    overflow: hidden;
6
+    // scroll-behavior: smooth;
7
+}
8
+
9
+body,
10
+h1, h2, h3, h4, h5, h6,
11
+.h1, .h2, .h3, .h4, .h5, .h6 {
12
+    font-family: $font-family-base;
13
+}
14
+
15
+
16
+p {
17
+    font-family: $font-family-base;
18
+}
19
+
20
+.wrapper {
21
+    opacity: 0;
22
+    visibility: hidden;
23
+    position: fixed;
24
+    top: 0;
25
+    left: 50%;
26
+    transform: translateX(-50%);
27
+    overflow-x: hidden;
28
+    overflow-y: auto;
29
+    width: 100%;
30
+    height: 100%;
31
+    max-width: 640px;
32
+    margin: 0 auto;
33
+    color: $c-black;
34
+    background-color: $c-blue-bg;
35
+}
36
+
37
+.wrapper__line-scroll-fixed {
38
+    position: relative;
39
+    width: 100%;
40
+    height: calc(100% + 10px);
41
+    z-index: 1;
42
+}
43
+
44
+.main {
45
+    position: fixed;
46
+    top: 0;
47
+    left: 0;
48
+    width: 100%;
49
+    height: 100%;
50
+    z-index: 1;
51
+}
52
+
53
+.formLoadingIcon {
54
+    position: absolute;
55
+    width: 100%;
56
+    height: 100%;
57
+    top: 0;
58
+    left: 0;
59
+    background-image: url(../images/loading.gif);
60
+    background-size: auto 80%;
61
+    background-position: center center;
62
+    background-repeat: no-repeat;
63
+    z-index: 1;
64
+    display: none;
65
+}
66
+
67
+.wapper-loading {
68
+    width: 100%;
69
+    height: 100%;
70
+    display: inline-block;
71
+    position: absolute;
72
+    top: 50%;
73
+    left: 50%;
74
+    transform: translate(-50%, -50%);
75
+    color: #817b72!important;
76
+    font-size: em(20)!important;
77
+    font-weight: 400!important;
78
+    z-index: 1;
79
+}
80
+
81
+.backform {
82
+    position: absolute;
83
+    left: 3em;
84
+    top: 2em;
85
+    color: $c-blue-bright;
86
+    font-weight: 500;
87
+    z-index: 1;
88
+    span {
89
+        display: inline-block;
90
+        font-size: 1.5em;
91
+        transform: scaleY(2);
92
+        margin-right: 0.5em;
93
+    }
94
+    p {
95
+        display: inline-block;
96
+        font-size: 1.8em;
97
+        margin-bottom: 0;
98
+    }
99
+}
100
+
101
+
102
+@media (min-height: 992px) {
103
+    .wrapper {
104
+        min-height: 992px;
105
+    }
106
+}
107
+
108
+@media screen and (min-width: 641px) {
109
+    .main {
110
+        height: calc(100% - 9.4375em);
111
+        padding-bottom: em(151);
112
+    }
113
+}

+ 13
- 0
src/fe/css/module/_ellipsis.scss Datei anzeigen

1
+@charset "UTF-8";
2
+
3
+@mixin ellipsis($width:auto,$row:1){
4
+  width:$width;
5
+  display: -webkit-box;
6
+  overflow: hidden;
7
+  min-height: initial !important;
8
+  text-overflow: clip;
9
+  /*! autoprefixer: off */
10
+  -webkit-box-orient: vertical;
11
+  /* autoprefixer: on */
12
+  -webkit-line-clamp: $row;
13
+}

+ 8
- 0
src/fe/css/module/_frosted.scss Datei anzeigen

1
+@charset "UTF-8";
2
+
3
+@mixin frosted($bg:#ebcd4c,$opacity:0.7, $blur: 7.5px){
4
+  backdrop-filter: blur($blur);
5
+  -webkit-backdrop-filter: blur($blur);
6
+  background-color: rgba($bg,$opacity);
7
+  box-shadow: 0px 0px 63px rgba(#000,0.1);
8
+}

+ 22
- 0
src/fe/css/module/_img-scale.scss Datei anzeigen

1
+@charset "UTF-8";
2
+
3
+@mixin img-scale($imgW:1,$imgH:1) {
4
+  position: relative;
5
+  display: block;
6
+  &:before {
7
+    content: '';
8
+    display: block;
9
+    padding-top: $imgH/$imgW*100%;
10
+  }
11
+  >img {
12
+    position: absolute;
13
+    top: 0;
14
+    left: 0;
15
+    bottom: 0;
16
+    right: 0;
17
+    margin: auto;
18
+    width: auto !important;
19
+    max-width: 100%;
20
+    max-height: 100%;
21
+  }
22
+}

+ 32
- 0
src/fe/css/module/_px2em.scss Datei anzeigen

1
+@charset "UTF-8";
2
+//un-modified
3
+
4
+@function calc-em($target-px, $context) {
5
+  @return calc(($target-px / $context) * 1em);
6
+}
7
+
8
+// and modified to accept a base context variable
9
+$browser-context: 16;
10
+
11
+@function em($pixels, $context: $browser-context) {
12
+  @return calc(($pixels / $context) * 1em);
13
+}
14
+
15
+@function rem($pixels, $context: $browser-context) {
16
+  @return calc(($pixels / $context) * 1rem);
17
+}
18
+
19
+
20
+@function font-size($size) {
21
+  @return em($size);
22
+}
23
+
24
+@mixin em($size) {
25
+  font-size: $size;
26
+  font-size: em($size);
27
+}
28
+
29
+@mixin rem($size) {
30
+  font-size: $size;
31
+  font-size: rem($size);
32
+}

+ 15
- 0
src/fe/css/page/_method.scss Datei anzeigen

1
+@charset "UTF-8";
2
+.methods {
3
+    p {
4
+        font-size: 1.3em;
5
+        line-height: 1.6;
6
+    }
7
+    &__container {
8
+        width: 100%;
9
+        height: 100%;
10
+        padding: 3em;
11
+        display: flex;
12
+        justify-content: center;
13
+        align-items: center;
14
+    }
15
+}

+ 115
- 0
src/fe/css/page/_passport.scss Datei anzeigen

1
+@charset "UTF-8";
2
+
3
+.passport {
4
+    width: 100%;
5
+    min-height: 100%;
6
+    background: url(../images/passport-bg.png) no-repeat bottom center/contain, linear-gradient(to bottom, rgba(191,230,246,1) 0%,rgba(191,230,246,0) 100%);;
7
+    &__container {
8
+        width: 100%;
9
+    }
10
+    &__intro {
11
+        position: relative;
12
+        width: 100%;
13
+        &__bg {
14
+            img {
15
+                width: 100%;
16
+                height: auto;
17
+            }
18
+        }
19
+        &__container {
20
+            position: absolute;
21
+            left: 0;
22
+            top: 0;
23
+            width: 100%;
24
+            height: 100%;
25
+            display: flex;
26
+            justify-content: center;
27
+            align-items: center;
28
+            flex-direction: column;
29
+        }
30
+        .photo {
31
+            margin-bottom: 0.8em;
32
+            &__img {
33
+                width: 11em;
34
+                height: 11em;
35
+            }
36
+            &__icon {
37
+                left: 78%;
38
+            }
39
+        }
40
+        &__content {
41
+            color: $c-whiite;
42
+        }
43
+        &__nickname {
44
+            margin-bottom: 0.1em;
45
+            h2 {
46
+                width: 100%;
47
+                text-align: center;
48
+                font-size: 2.4em;
49
+                font-weight: 600;
50
+                text-shadow: 0 0.1em 0.1em rgba(#000, 0.15);
51
+                margin-bottom: 0;
52
+            }
53
+        }
54
+        &__info {
55
+            p {
56
+                width: 100%;
57
+                text-align: center;
58
+                font-size: 1.6em;
59
+                text-shadow: 0 0.1em 0.1em rgba(#000, 0.2);
60
+                margin-bottom: 0;
61
+            }
62
+        }
63
+    }
64
+    &__toggle {
65
+        width: 89%;
66
+        margin: 0 auto 2em;
67
+        box-shadow: 0 0.2em 0.5em rgba(#000, 0.2);
68
+        border-radius: 1.5em;
69
+        overflow: hidden;
70
+        &.toggleClose {
71
+            .passport__toggle__head {
72
+                &::before {
73
+                    transform: translateY(-50%) rotate(0);
74
+                }
75
+            }
76
+            .passport__toggle__body {
77
+                display: none;
78
+            }
79
+        }
80
+        &__head {
81
+            position: relative;
82
+            background-color: $c-blue-bright;
83
+            padding: 1.5em;
84
+            &::before {
85
+                content: "";
86
+                display: block;
87
+                width: 2.5em;
88
+                height: 2.5em;
89
+                position: absolute;
90
+                right: 1.5em;
91
+                top: 50%;
92
+                transform: translateY(-50%) rotate(-180deg);
93
+                background: url(../images/arrow-down.png) no-repeat center center/contain;
94
+            }
95
+            p {
96
+                color: $c-whiite;
97
+                text-align: center;
98
+                margin-bottom: 0;
99
+                font-size: 1.6em;
100
+                font-weight: 300;
101
+                letter-spacing: 0.07em;
102
+            }
103
+        }
104
+        &__body {
105
+            background-color: $c-whiite;
106
+            padding: 1.5em 1.5em 0;
107
+            .tags {
108
+                &__item {
109
+                    margin-bottom: 1.5em;
110
+                    padding: 0.5em 0.55em;
111
+                }
112
+            }
113
+        }
114
+    }
115
+}

+ 5
- 0
src/fe/css/page/_register.scss Datei anzeigen

1
+@charset "UTF-8";
2
+.register {
3
+    padding-top: 3.5em;
4
+    padding-bottom: 3em;
5
+}

+ 27
- 0
src/fe/css/variable/_base.scss Datei anzeigen

1
+@charset "UTF-8";
2
+// 共用變數與函數
3
+@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap');  // -思源黑體
4
+@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+TC:wght@200;300;400;500;600;700;900&display=swap');  // -思源宋體
5
+
6
+
7
+/* Font */
8
+$font-family-base: 'Noto Sans TC','PingFangTC', 'Heiti TC', 'Microsoft JhengHei', 'Noto Sans Myanmar','Arial', 'sans-serif';
9
+
10
+/* color */
11
+$c-blue: #6591BB;
12
+
13
+$c-blue-bg: #F9FDFF;
14
+
15
+$c-blue-active: #EAF2F8;
16
+
17
+$c-blue-bright: #2AACE2;
18
+
19
+$c-whiite: #ffffff;
20
+
21
+$c-black: #1E2846;
22
+
23
+$c-gray: #747474;
24
+
25
+$c-gray-lighten: #C8C8C8;
26
+
27
+

+ 10224
- 0
src/fe/css/vendor/_bootstrap.scss
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 13
- 0
src/fe/css/vendor/_swiper.min.scss
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


BIN
src/fe/images/arrow-down.png Datei anzeigen


BIN
src/fe/images/form-tick.png Datei anzeigen


BIN
src/fe/images/passport-bg.png Datei anzeigen


BIN
src/fe/images/passport-intro.png Datei anzeigen


BIN
src/fe/images/select-arrow.png Datei anzeigen


BIN
src/fe/images/solar_camera-linear.png Datei anzeigen


+ 520
- 1
src/fe/index.html Datei anzeigen

1
-test
1
+<!DOCTYPE html>
2
+<html lang="zh-Hant-TW">
3
+
4
+<head>
5
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+  <meta name="viewport" content="width=640, user-scalable=no" />
8
+  <meta name="format-detection" content="telephone=no">
9
+
10
+  <title>健康護照</title>
11
+  <meta name="description" content="" />
12
+  <meta name="keywords" content="" />
13
+
14
+  <link rel="shortcut icon" href="" type="image/x-icon" sizes="32x32" />
15
+  <link rel="image_src" href="/images/share.jpg" />
16
+  <meta property="og:title" content="健康護照" />
17
+  <meta property="og:type" content="website" />
18
+  <meta property="og:url" content="" />
19
+  <meta property="og:image" content="/images/share.jpg" />
20
+  <meta property="og:description" content="" />
21
+  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css"
22
+    integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
23
+  <link rel="stylesheet" href="css/all.css">
24
+
25
+</head>
26
+
27
+<body>
28
+  <div class="wapper-loading">
29
+      <!-- Loading Start -->
30
+    <div class="loading">
31
+      <div class="loading__box">
32
+        <div class="loading__ani"></div>
33
+        <div class="loading__text">Loading</div>
34
+      </div>
35
+    </div>
36
+    <!-- Loading End -->
37
+  </div>
38
+  <div class="wrapper">
39
+    <div class="wrapper__line-scroll-fixed">
40
+      <main class="main">
41
+        <!-- 表單 form -->
42
+        <section class="section register">
43
+          <div class="section__container form__container">
44
+            <div class="form">
45
+              <div class="form__item form__item-photo photo">
46
+                <div class="photo__img"></div>
47
+                <input type="file" id="fileInput1" class="fileInput" accept="image/*">
48
+                <div class="photo__icon photo__icon-1">
49
+                  <img src="./images/solar_camera-linear.png" alt="">
50
+                </div>
51
+              </div>
52
+              <fieldset class="form__item form__item-1 form__item-healthAction" data-ques="healthAction">
53
+                <legend class="form__ques">
54
+                    <p>
55
+                      平常你有什麼健康行動(複選)
56
+                    </p>
57
+                </legend>
58
+                <div class="form__options tags">
59
+                  <div class="form__options__item tags__item tags__item-md">
60
+                      <input id="healthActionOption_1" type="checkbox" value="tag-WCzAvKUiL" name="healthAction">
61
+                      <label for="healthActionOption_1">
62
+                          <p>良好作息</p>
63
+                      </label>
64
+                  </div>
65
+                  <div class="form__options__item tags__item tags__item-md">
66
+                      <input id="healthActionOption_2" type="checkbox" value="tag-lIcE-WkEe" name="healthAction">
67
+                      <label for="healthActionOption_2">
68
+                          <p>
69
+                              規律運動
70
+                          </p>
71
+                      </label>
72
+                  </div>
73
+                  <div class="form__options__item tags__item tags__item-md">
74
+                      <input id="healthActionOption_3" type="checkbox" value="tag-uEOBbgPoG" name="healthAction">
75
+                      <label for="healthActionOption_3">
76
+                          <p>
77
+                              飲食控制
78
+                          </p>
79
+                      </label>
80
+                  </div>
81
+                  <div class="form__options__item tags__item tags__item-md">
82
+                      <input id="healthActionOption_4" type="checkbox" value="tag-YEJfK7-I7" name="healthAction">
83
+                      <label for="healthActionOption_4">
84
+                          <p>
85
+                              營養品補充
86
+                          </p>
87
+                      </label>
88
+                  </div>
89
+                  <div class="form__options__item tags__item tags__item-md">
90
+                      <input id="healthActionOption_5" type="checkbox" value="tag-stfrz1nD8" name="healthAction">
91
+                      <label for="healthActionOption_5">
92
+                          <p>
93
+                              閱讀健康文章
94
+                          </p>
95
+                      </label>
96
+                  </div>
97
+                  <div class="form__options__item tags__item tags__item-md">
98
+                      <input id="healthActionOption_6" type="checkbox" value="x" name="healthAction">
99
+                      <label for="healthActionOption_6">
100
+                          <p>
101
+                            其他
102
+                          </p>
103
+                      </label>
104
+                  </div>
105
+                </div>
106
+              </fieldset>
107
+              <fieldset class="form__item form__item-2 form__item-healthTopic" data-ques="healthTopic">
108
+                <legend class="form__ques">
109
+                    <p>
110
+                      你對什麼健康話題有興趣(複選)
111
+                    </p>
112
+                </legend>
113
+                <div class="form__options tags">
114
+                  <div class="form__options__item tags__item tags__item-md">
115
+                      <input id="healthTopicOption_1" type="checkbox" value="tag-vstHmk4YP" name="healthTopic">
116
+                      <label for="healthTopicOption_1">
117
+                          <p>流行感冒</p>
118
+                      </label>
119
+                  </div>
120
+                  <div class="form__options__item tags__item tags__item-md">
121
+                      <input id="healthTopicOption_2" type="checkbox" value="tag-CorN36876" name="healthTopic">
122
+                      <label for="healthTopicOption_2">
123
+                          <p>
124
+                              免疫調節
125
+                          </p>
126
+                      </label>
127
+                  </div>
128
+                  <div class="form__options__item tags__item tags__item-md">
129
+                      <input id="healthTopicOption_3" type="checkbox" value="tag-nWHBzbUCr" name="healthTopic">
130
+                      <label for="healthTopicOption_3">
131
+                          <p>
132
+                              腸胃功能
133
+                          </p>
134
+                      </label>
135
+                  </div>
136
+                  <div class="form__options__item tags__item tags__item-md">
137
+                      <input id="healthTopicOption_4" type="checkbox" value="tag-VQSDoXlAL" name="healthTopic">
138
+                      <label for="healthTopicOption_4">
139
+                          <p>
140
+                              過敏體質
141
+                          </p>
142
+                      </label>
143
+                  </div>
144
+                  <div class="form__options__item tags__item tags__item-md">
145
+                      <input id="healthTopicOption_5" type="checkbox" value="tag-MLdZCbE9y" name="healthTopic">
146
+                      <label for="healthTopicOption_5">
147
+                          <p>
148
+                              睡眠問題
149
+                          </p>
150
+                      </label>
151
+                  </div>
152
+                  <div class="form__options__item tags__item tags__item-md">
153
+                      <input id="healthTopicOption_6" type="checkbox" value="tag-Yz0_DhZBV" name="healthTopic">
154
+                      <label for="healthTopicOption_6">
155
+                          <p>
156
+                            日常保健
157
+                          </p>
158
+                      </label>
159
+                  </div>
160
+                </div>
161
+              </fieldset>
162
+              <fieldset class="form__item form__item-3 form__item-healthStatus" data-ques="healthStatus">
163
+                <legend class="form__ques">
164
+                    <p>
165
+                      你覺得自己的身體狀況如何
166
+                    </p>
167
+                </legend>
168
+                <div class="form__options tags">
169
+                  <div class="form__options__item tags__item tags__item-md">
170
+                    <input id="healthStatusOption_1" type="radio" value="tag-TN-u8YIrm" name="healthStatus">
171
+                    <label for="healthStatusOption_1">
172
+                        <p>
173
+                            很少生病
174
+                        </p>
175
+                    </label>
176
+                    
177
+                </div>
178
+                <div class="form__options__item tags__item tags__item-md">
179
+                    <input id="healthStatusOption_2" type="radio" value="tag-ATnIMezXK" name="healthStatus">
180
+                    <label for="healthStatusOption_2">
181
+                        <p>
182
+                            偶爾疲倦​
183
+                        </p>
184
+                    </label>
185
+                </div>
186
+                <div class="form__options__item tags__item tags__item-md">
187
+                    <input id="healthStatusOption_3" type="radio" value="tag-LJg1ec9-L" name="healthStatus">
188
+                    <label for="healthStatusOption_3">
189
+                        <p>
190
+                            經常感冒
191
+                        </p>
192
+                    </label>
193
+                </div>
194
+                </div>
195
+              </fieldset>
196
+              <fieldset class="form__item form__item-4 form__item-healthAdapt" data-ques="healthAdapt">
197
+                <legend class="form__ques">
198
+                    <p>
199
+                      面對疫情趨緩,<br>以下哪一個情況最符合你的應對
200
+                    </p>
201
+                </legend>
202
+                <div class="form__options tags">
203
+                  <div class="form__options__item tags__item tags__item-lg">
204
+                    <input id="healthAdaptOption_1" type="radio" value="tag-bDRawibcP" name="healthAdapt">
205
+                    <label for="healthAdaptOption_1">
206
+                        <p>
207
+                          我仍會主動參考政府機構的資訊,持續戴口罩積極防疫
208
+                        </p>
209
+                    </label>
210
+                    
211
+                </div>
212
+                <div class="form__options__item tags__item tags__item-lg">
213
+                    <input id="healthAdaptOption_2" type="radio" value="tag-JiWCgTnNs" name="healthAdapt">
214
+                    <label for="healthAdaptOption_2">
215
+                        <p>
216
+                          我在前往人多的地方或搭乘大眾交通工具時會佩戴口罩
217
+                        </p>
218
+                    </label>
219
+                </div>
220
+                <div class="form__options__item tags__item tags__item-lg">
221
+                    <input id="healthAdaptOption_3" type="radio" value="tag-4dcsmiwqt" name="healthAdapt">
222
+                    <label for="healthAdaptOption_3">
223
+                        <p>
224
+                          我不再對疫情感到恐慌,幾乎不戴口罩、回到正常生活
225
+                        </p>
226
+                    </label>
227
+                </div>
228
+                </div>
229
+              </fieldset>
230
+              <fieldset class="form__item form__item-5 form__item-healthThought" data-ques="healthThought">
231
+                <legend class="form__ques">
232
+                    <p>
233
+                      下列哪一個敘述符合你的想法<br>
234
+                      (複選,至多可選擇2個答案)
235
+                    </p>
236
+                </legend>
237
+                <div class="form__options tags">
238
+                  <div class="form__options__item tags__item tags__item-lg">
239
+                      <input id="healthThoughtOption_1" type="checkbox" value="tag-FhMvcmSJm" name="healthThought">
240
+                      <label for="healthThoughtOption_1">
241
+                          <p>我願意了解新的疫苗並採取行動</p>
242
+                      </label>
243
+                  </div>
244
+                  <div class="form__options__item tags__item tags__item-lg">
245
+                      <input id="healthThoughtOption_2" type="checkbox" value="tag-g4GSGpTHq" name="healthThought">
246
+                      <label for="healthThoughtOption_2">
247
+                          <p>
248
+                              我會自律做好防疫,避免造成他人困擾
249
+                          </p>
250
+                      </label>
251
+                  </div>
252
+                  <div class="form__options__item tags__item tags__item-lg">
253
+                      <input id="healthThoughtOption_3" type="checkbox" value="tag-lDhpoS39o" name="healthThought">
254
+                      <label for="healthThoughtOption_3">
255
+                          <p>
256
+                              我覺得應該維持正常社交,不用過度緊張
257
+                          </p>
258
+                      </label>
259
+                  </div>
260
+                  <div class="form__options__item tags__item tags__item-lg">
261
+                      <input id="healthThoughtOption_4" type="checkbox" value="tag-qmywOc8af" name="healthThought">
262
+                      <label for="healthThoughtOption_4">
263
+                          <p>
264
+                              我覺得保持正向的態度,與病毒共處自然會產生抗體
265
+                          </p>
266
+                      </label>
267
+                  </div>
268
+                  <div class="form__options__item tags__item tags__item-lg">
269
+                      <input id="healthThoughtOption_5" type="checkbox" value="tag-77KImqQGb" name="healthThought">
270
+                      <label for="healthThoughtOption_5">
271
+                          <p>
272
+                              沒做好防疫準備,我會感到焦慮
273
+                          </p>
274
+                      </label>
275
+                  </div>
276
+                </div>
277
+              </fieldset>
278
+              <fieldset class="form__item form__item-6 form__item-healthAge" data-ques="healthAge">
279
+                <legend class="form__ques">
280
+                    <p>
281
+                      你的年齡
282
+                    </p>
283
+                </legend>
284
+                <div class="form__options tags">
285
+                  <div class="form__options__item tags__item tags__item-md">
286
+                    <input id="healthAgeOption_1" type="radio" value="tag-bjbXSt2gi" name="healthAge">
287
+                    <label for="healthAgeOption_1">
288
+                        <p>
289
+                          20歲以下
290
+                        </p>
291
+                    </label>
292
+                  </div>
293
+                  <div class="form__options__item tags__item tags__item-md">
294
+                    <input id="healthAgeOption_2" type="radio" value="tag-qYe0v6HqF" name="healthAge">
295
+                    <label for="healthAgeOption_2">
296
+                        <p>
297
+                          20-29歲
298
+                        </p>
299
+                    </label>
300
+                  </div>
301
+                  <div class="form__options__item tags__item tags__item-md">
302
+                    <input id="healthAgeOption_3" type="radio" value="tag-6iaNB8Ea4" name="healthAge">
303
+                    <label for="healthAgeOption_3">
304
+                        <p>
305
+                          30-39歲
306
+                        </p>
307
+                    </label>
308
+                  </div>
309
+                  <div class="form__options__item tags__item tags__item-md">
310
+                    <input id="healthAgeOption_4" type="radio" value="tag-e4JG3GBG_" name="healthAge">
311
+                    <label for="healthAgeOption_4">
312
+                        <p>
313
+                          40-49歲
314
+                        </p>
315
+                    </label>
316
+                  </div>
317
+                  <div class="form__options__item tags__item tags__item-md">
318
+                    <input id="healthAgeOption_5" type="radio" value="tag-DTE6DWovG" name="healthAge">
319
+                    <label for="healthAgeOption_5">
320
+                        <p>
321
+                          50-59歲
322
+                        </p>
323
+                    </label>
324
+                  </div>
325
+                  <div class="form__options__item tags__item tags__item-md">
326
+                    <input id="healthAgeOption_6" type="radio" value="tag-pAxHnckQs" name="healthAge">
327
+                    <label for="healthAgeOption_6">
328
+                        <p>
329
+                          59歲以上
330
+                        </p>
331
+                    </label>
332
+                  </div>
333
+                </div>
334
+              </fieldset>
335
+              <fieldset class="form__item form__item-6 form__item-healthNickname" data-ques="healthNickname">
336
+                <legend class="form__ques">
337
+                    <p>
338
+                      暱稱
339
+                    </p>
340
+                </legend>
341
+                <div class="form__input">
342
+                  <input id="nickName" type="text" value="" placeholder="請輸入暱稱">
343
+                </div>
344
+              </fieldset>
345
+              <fieldset class="form__item form__item-6 form__item-healthGender" data-ques="healthGender">
346
+                <legend class="form__ques">
347
+                    <p>
348
+                      性別
349
+                    </p>
350
+                </legend>
351
+                <div class="form__input">
352
+                  <select name="gender" id="gender">
353
+                    <option value="">請選擇性別</option>
354
+                    <option value="tag-8HwqQuQ43">女性</option>
355
+                    <option value="tag-F8Me8-UGg">男性</option>
356
+                    <option value="tag-8HwqQuQ43">不提供</option>
357
+                  </select>
358
+                </div>
359
+              </fieldset>
360
+              <div class="form__item form__item-agree">
361
+                <label for="methodsAgree" class="label">
362
+                    <input type="checkbox" id="methodsAgree" name="methodsAgree">
363
+                    <div class="label__checkbox"></div>
364
+                    <p>我同意<span class="goToActivity">個人資料使用方法</span></p>
365
+                </label>
366
+            </div>
367
+              <div class="button form-submit">
368
+                <p>下一步</p>
369
+              </div>
370
+            </div>
371
+          </div>
372
+        </section>
373
+        <!-- 活動辦法 methods -->
374
+        <section class="section methods">
375
+          <div class="backform"><span><</span><p>回上一頁</p></div>
376
+          <div class="section__container methods__container">
377
+            <p>
378
+              李慶雲兒童感染暨疫苗發展醫學文教基金會以本訊息向您告知並徵求同意。由於個人資料蒐集涉及您的隱私權益,請您務必詳閱本告知內容。為經營「mRNA 健康管家」LINE官方帳號之需要,帳號內的「健康護照」功能互動,將蒐集您的個人資料,以進行後續的內容分眾溝通。<br><br>
379
+
380
+              其中包含暱稱、照片、性別、年齡區間、對於健康議題之
381
+              想法意向等。但毋須提供姓名、出生年月日、身分證字號
382
+              、住居所地址、各類電信電話號碼、電子郵件信箱、聯絡
383
+              人資訊以及其他可辨識之個人資料。本單位只會在中華民
384
+              國境內利用您的個人資料,利用期間為本單位或業務所必
385
+              須之保存期間。利用方式為符合個人資料保護相關法令以
386
+              自動化機器或其他非自動化之利用方式。除非有個人資料
387
+              保護法所規定例外情形,否則您可以依照個人資料保護法
388
+              相關規定,就您提供的個人資料行使以下權利:查詢或請
389
+              求閱覽或請求製給複製本、請求補充或更正、請求停止蒐
390
+              集、處理或利用、請求刪除,如有相關需求,可透過 Email
391
+              與我們聯繫(prof.lee.foundation@gmail.com)。<br><br>
392
+
393
+              提醒您,您可以自由選擇提供您的個人資料,如果您拒絕
394
+              提供的個人資料是與前述蒐集、處理與利用目的相關,則
395
+              會導致您無法使用帳號內的「健康護照」功能。
396
+            </p>
397
+          </div>
398
+        </section>
399
+        <!-- 護照 passport -->
400
+        <section class="section passport">
401
+          <div class="section__container passport__container">
402
+            <div class="passport__intro">
403
+              <div class="passport__intro__bg">
404
+                <img src="./images/passport-intro.png" alt="">
405
+              </div>
406
+              <div class="passport__intro__container">
407
+                <div class="photo">
408
+                  <div class="photo__img"></div>
409
+                  <input type="file" id="fileInput2" class="fileInput" accept="image/*">
410
+                  <div class="photo__icon photo__icon-2">
411
+                    <img src="./images/solar_camera-linear.png" alt="">
412
+                  </div>
413
+                </div>
414
+                <div class="passport__intro__content">
415
+                  <div class="passport__intro__nickname">
416
+                    <h2>王小美</h2>
417
+                  </div>
418
+                  <div class="passport__intro__info">
419
+                    <p><span class="introGender">女性</span> / <span class="introAge">30-39歲 </span></p>
420
+                  </div>
421
+                </div>
422
+              </div>
423
+            </div>
424
+            <div class="passport__toggle passport__toggle-healthTopic">
425
+              <div class="passport__toggle__head">
426
+                <p>關注議題</p>
427
+              </div>
428
+              <div class="passport__toggle__body">
429
+                <div class="tags">
430
+                  <div class="tags__item tags__item-md checked">
431
+                    <p>良好作息</p>
432
+                  </div>
433
+                  <div class="tags__item tags__item-md checked">
434
+                    <p>良好作息</p>
435
+                  </div>
436
+                </div>
437
+              </div>
438
+            </div>
439
+            <div class="passport__toggle passport__toggle-healthAction">
440
+              <div class="passport__toggle__head">
441
+                <p>健康行動</p>
442
+              </div>
443
+              <div class="passport__toggle__body">
444
+                <div class="tags">
445
+                  <div class="tags__item tags__item-md checked">
446
+                    <p>良好作息</p>
447
+                  </div>
448
+                  <div class="tags__item tags__item-md checked">
449
+                    <p>良好作息</p>
450
+                  </div>
451
+                  <div class="tags__item tags__item-md checked">
452
+                    <p>良好作息</p>
453
+                  </div>
454
+                  <div class="tags__item tags__item-md checked">
455
+                    <p>良好作息</p>
456
+                  </div>
457
+                  <div class="tags__item tags__item-md checked">
458
+                    <p>良好作息</p>
459
+                  </div>
460
+                  <div class="tags__item tags__item-md checked">
461
+                    <p>良好作息</p>
462
+                  </div>
463
+                </div>
464
+              </div>
465
+            </div>
466
+          </div>
467
+        </section>
468
+      </main>
469
+      <footer class="footer">
470
+      </footer>
471
+    </div>
472
+  </div>
473
+  <!-- Alert Modal -->
474
+  <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
475
+    aria-hidden="true">
476
+    <div class="modal-dialog modal-dialog-centered" role="document">
477
+      <div class="modal-content">
478
+        <button type="button" class="close modal__close" data-dismiss="modal" aria-label="Close">
479
+          <span aria-hidden="true">&times;</span>
480
+        </button>
481
+        <div class="modal-header">
482
+        </div>
483
+        <div class="modal-body">
484
+          <p class="alert-message"></p>
485
+        </div>
486
+        <div class="modal-footer">
487
+
488
+          <button type="button" class="close button" data-dismiss="modal" aria-label="Close">
489
+            <p><span aria-hidden="true">確定</span></p>
490
+          </button>
491
+
492
+        </div>
493
+      </div>
494
+    </div>
495
+  </div>
496
+
497
+  <script src="lib/jquery-3.5.1.min.js"></script>
498
+  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/js/bootstrap.min.js"
499
+    integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
500
+    crossorigin="anonymous"></script>
501
+  <script charset="utf-8" src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script>
502
+  <script src="./lib/gsap.min.js"></script>
503
+  <script src="js/utlis.js"></script>
504
+  <script src="./js/services/userModel.js"></script>
505
+  <script src="./js/services/index.js"></script>
506
+  <script src="js/base.js"></script>
507
+  <script src="js/register.js"></script>
508
+  <script src="js/passport.js"></script>
509
+
510
+  <!-- <script src="https://cdn.jsdelivr.net/npm/vconsole@3.2.0/dist/vconsole.min.js"></script>
511
+
512
+  <script>
513
+    // init vConsole
514
+    var vConsole = new VConsole();
515
+    console.log('Hello world');
516
+  </script> -->
517
+
518
+</body>
519
+
520
+</html>

+ 146
- 0
src/fe/js/base.js Datei anzeigen

1
+base = function () {
2
+	//private menbers
3
+	let isActivityOver = false;
4
+	let userProfile = null;
5
+	let userData = null;
6
+
7
+
8
+	//private methods
9
+	function init() {
10
+
11
+		console.log('base init')
12
+
13
+		// 判斷是否活動已結束
14
+		// entranceTimer();
15
+
16
+		// 用戶登入
17
+		GameService.getInstanse().init().then((profile) => {
18
+			$(".wapper-loading .loading__text").text("LINE登入中");
19
+			// console.log(profile)
20
+			userProfile = profile;
21
+			getProfile();
22
+
23
+			register.LinePicHandler(profile.pictureUrl)
24
+
25
+			// 正式用 記得開
26
+			GameService.getInstanse().userLogin()
27
+				.then(_res => {
28
+					console.log("_res: ",_res);
29
+
30
+					$(".wapper-loading").remove();
31
+
32
+					gsap.to(".wrapper", {
33
+						duration: 0.5,
34
+						autoAlpha: 1
35
+					});
36
+
37
+					userData = GameService.getInstanse().getUserData();
38
+
39
+					console.log("userData: ",userData)
40
+					
41
+					if(Object.keys(userData).length === 0) {
42
+						sectionFadeIn(".register");
43
+					}else {
44
+						sectionFadeIn(".passport");
45
+						passport.buildPassportHandler(userData)
46
+					}
47
+				})
48
+				.catch(err => {
49
+					console.log(err)
50
+					$(".wapper-loading").remove();
51
+					gsap.to(".wrapper", {
52
+						duration: 0.5,
53
+						autoAlpha: 1
54
+					});
55
+				})
56
+		})
57
+
58
+		// 返回表單頁
59
+		$(".backform").on("click", function(){
60
+			console.log("backform click")
61
+			sectionFadeOut(".methods");
62
+			sectionFadeIn(".register");
63
+		});
64
+
65
+		// 前往活動辦法頁
66
+		$(".goToActivity").on("click", function(){
67
+			console.log("backform click")
68
+			sectionFadeOut(".register");
69
+			sectionFadeIn(".methods");
70
+		});
71
+
72
+		
73
+	}
74
+
75
+	// 活動期間判斷
76
+	function entranceTimer() {
77
+		var _nowDate = new Date();
78
+		var _endDate = new Date("2023/09/08 23:29");
79
+
80
+		if (_nowDate.getTime() >= _endDate.getTime()) {
81
+
82
+			isActivityOver = true;
83
+
84
+			// 活動結束後提供查詢
85
+			// myAlert(``);
86
+			console.log("活動已結束")
87
+		} else {
88
+			isActivityOver = false;
89
+			console.log("活動進行中")
90
+		}
91
+	}
92
+
93
+	function getProfile() {
94
+		return userProfile
95
+	}
96
+
97
+	// 提醒popup
98
+	function myAlert(_msg) {
99
+		$('#agreeAccModal').modal('hide');
100
+		$('#exampleModal').find('.alert-message').html(_msg);
101
+		$('#exampleModal').modal('show');
102
+		$(".modal-backdrop.show").css("backdrop-filter", "blur(2px)");
103
+		$(".modal-backdrop.show").css("-webkit-backdrop-filter", "blur(2px)")
104
+	}
105
+
106
+	// page進入動態
107
+	function sectionFadeIn(el) {
108
+		// $(el).fadeIn();
109
+		gsap.to(el, {
110
+			duration: 0.3,
111
+			autoAlpha: 1
112
+		})
113
+	}
114
+
115
+	// page離開動態
116
+	function sectionFadeOut(el) {
117
+		// $(el).fadeOut();
118
+		gsap.to(el, {
119
+			duration: 0.3,
120
+			autoAlpha: 0
121
+		})
122
+	}
123
+
124
+	{
125
+		$(document).ready(function () {
126
+			init();
127
+		});
128
+	}
129
+
130
+	//public
131
+	return {
132
+		sectionFadeIn: function(el) {
133
+			sectionFadeIn(el)
134
+		},
135
+		sectionFadeOut: function(el) {
136
+			sectionFadeOut(el)
137
+		},
138
+		myAlert: function (_msg) {
139
+			myAlert(_msg);
140
+		},
141
+		getProfile,
142
+
143
+	};
144
+};
145
+
146
+var base = new base();

+ 188
- 0
src/fe/js/passport.js Datei anzeigen

1
+passport = function () {
2
+	//private menbers
3
+	let tagData = null;
4
+	let convertData = {}
5
+
6
+
7
+
8
+
9
+	//private methods
10
+	function init() {
11
+
12
+		console.log('passport init')
13
+
14
+		getTagData();
15
+
16
+		$(".photo__icon-2").on("click", function(){
17
+			$("#fileInput2").click();
18
+		});
19
+
20
+		$(".passport__toggle__head").on("click", function(){
21
+			if(!$(this).parent(".passport__toggle").hasClass("toggleClose")) {
22
+				$(this).parent(".passport__toggle").addClass("toggleClose");
23
+			}else {
24
+				$(this).parent(".passport__toggle").removeClass("toggleClose");
25
+			}
26
+		});
27
+
28
+		
29
+	}
30
+
31
+	function getTagData(){
32
+		$.ajax('./js/tagData.json').then(res => {
33
+			tagData = res;
34
+			// console.log(res)
35
+		})
36
+	}
37
+
38
+	function buildPassportHandler(_data){
39
+		let data = _data;
40
+		console.log(data);
41
+
42
+		setTimeout(()=>{
43
+
44
+			let getHealthAction = convertMultipleTag('healthAction', data.healthAction);
45
+			let gethealthTopic = convertMultipleTag('healthTopic', data.healthTopic);
46
+			let getHealthAge = convertSingleTag('healthAge', data.healthAge);
47
+			let getHealthGender= convertSingleTag('healthGender', data.healthGender);
48
+			convertData.headSticker = data.headSticker;
49
+			convertData.healthNickname = data.healthNickname;
50
+			
51
+			Promise.all([getHealthAction ,gethealthTopic, getHealthAge, getHealthGender]).then((res) => {
52
+				console.log(convertData); // [3, 1337, "foo"]
53
+				buildTagHtml();
54
+			});
55
+		}, 200);
56
+
57
+	}
58
+
59
+	function convertMultipleTag(_name, _arr) {
60
+		return new Promise(resolve => {
61
+			// 篩出特定問題資料
62
+			let tags = tagData.filter(quesItem => {
63
+				// console.log(item)
64
+				return quesItem.questionName == _name
65
+			}).map(quesItem => {
66
+				return quesItem.tags
67
+			})
68
+			// console.log(tags)
69
+
70
+			// 轉換回傳資料
71
+			let convertArr = [];
72
+			_arr.forEach(element => {
73
+				// console.log("element: "+element)
74
+				tags[0].forEach((_tagItem) => {
75
+					// console.log("tagId: "+_tagItem.tagId)
76
+					if(_tagItem.tagId == element) {
77
+						convertArr.push(_tagItem.answer)
78
+						// console.log("tagId: "+_tagItem.answer)
79
+					}
80
+				});
81
+			});
82
+			
83
+			// console.log(convertArr)
84
+
85
+			if(_name == "healthAction") {
86
+				convertData.healthAction = convertArr;
87
+			}
88
+			if(_name == "healthTopic") {
89
+				convertData.healthTopic = convertArr;
90
+			}
91
+
92
+			resolve(_name + " convertMultipleTag success");
93
+
94
+			return convertArr;
95
+		});
96
+	}
97
+
98
+	function convertSingleTag(_name, _value) {
99
+		return new Promise(resolve => {
100
+			// 篩出特定問題資料
101
+			let tags = tagData.filter(quesItem => {
102
+				// console.log(item)
103
+				return quesItem.questionName == _name
104
+			}).map(quesItem => {
105
+				return quesItem.tags
106
+			})
107
+			// console.log(tags)
108
+
109
+			let converValue = "";
110
+			tags[0].forEach((_tagItem) => {
111
+				// console.log("tagId: "+_tagItem.tagId)
112
+				if(_tagItem.tagId == _value) {
113
+					converValue = _tagItem.answer
114
+					// console.log("tagId: "+_tagItem.answer)
115
+				}
116
+			});
117
+			
118
+			if(_name == "healthAge") {
119
+				convertData.healthAge =  converValue;
120
+			}
121
+
122
+			if(_name == "healthGender") {
123
+				convertData.healthGender =  converValue;
124
+			}
125
+
126
+			// console.log(converValue)
127
+
128
+			resolve(_name + " convertMultipleTag success");
129
+
130
+			return converValue;
131
+		});
132
+	}
133
+
134
+	function buildTagHtml() {
135
+		$(".passport__toggle-healthTopic .tags").html("");
136
+		$(".passport__toggle-healthAction .tags").html("");
137
+		$(".passport__intro .photo__img").html("");
138
+		$(".passport__intro__nickname h2").html("");
139
+		$(".passport__intro__info .introAge").html("");
140
+		$(".passport__intro__info .introGender").html("");
141
+
142
+		convertData.healthTopic.forEach(_tagName => {
143
+			$(".passport__toggle-healthTopic .tags").append(
144
+				`
145
+				<div class="tags__item tags__item-md checked">
146
+					<p>${_tagName}</p>
147
+				</div>	
148
+				`
149
+			);
150
+		});
151
+
152
+		convertData.healthAction.forEach(_tagName => {
153
+			$(".passport__toggle-healthAction .tags").append(
154
+				`
155
+				<div class="tags__item tags__item-md checked">
156
+					<p>${_tagName}</p>
157
+				</div>	
158
+				`
159
+			);
160
+		});
161
+		
162
+		$(".passport__intro .photo__img").append(
163
+			`
164
+				<img src="${convertData.headSticker}" />
165
+			`
166
+		);
167
+
168
+		$(".passport__intro__nickname h2").text(convertData.healthNickname);
169
+		
170
+		$(".passport__intro__info .introAge").text(convertData.healthAge);
171
+		$(".passport__intro__info .introGender").text(convertData.healthGender);
172
+	}
173
+
174
+	{
175
+		$(document).ready(function () {
176
+			init();
177
+		});
178
+	}
179
+
180
+	//public
181
+	return {
182
+		buildPassportHandler: function(data) {
183
+			buildPassportHandler(data)
184
+		}
185
+	};
186
+};
187
+
188
+var passport = new passport();

+ 321
- 0
src/fe/js/register.js Datei anzeigen

1
+
2
+register = function () {
3
+	let _noteScrollTop = 0;
4
+	let linePicUrl = null;
5
+	let lineBase64Data = null;
6
+	let customBase64Data = null;
7
+	let finalase64Data = null;
8
+	let registerAlert = "";
9
+	let registerData = {
10
+		healthAction: null,
11
+		healthTopic: null,
12
+		healthStatus: null,
13
+		healthAdapt: null,
14
+        healthThought: null,
15
+        healthAge: null,
16
+        healthNickname: null,
17
+        healthGender: null,
18
+		headSticker: null,
19
+		healthGenderRole: null
20
+	}
21
+
22
+
23
+	//private methods
24
+	function init() {
25
+		console.log('register is loaded.');
26
+
27
+		selectImage();
28
+
29
+		// 換大頭照點擊
30
+		$(".photo__icon-1").on("click", function(){
31
+			$("#fileInput1").click();
32
+		});
33
+
34
+		// 多選題選中添加checked樣式
35
+		$(".register .form__options__item input[type='checkbox']").change(function(){
36
+			if($(this).prop("checked")) {
37
+				$(this).parents(".form__options__item").addClass("checked");
38
+			}else {
39
+				$(this).parents(".form__options__item").removeClass("checked");
40
+			}
41
+		});
42
+
43
+		// 單選題選中添加checked樣式
44
+		$(".register .form__options__item input[type='radio']").change(function(){
45
+			if($(this).prop("checked")) {
46
+				$(this).parents(".form__options").children(".form__options__item").removeClass("checked");
47
+				$(this).parents(".form__options__item").addClass("checked");
48
+			}
49
+		});
50
+
51
+		// 多選限制複選數
52
+		$('.register .form__item-healthThought .form__options__item').click(function() {
53
+			// console.log("healthThought click")
54
+            $(".form__item-healthThought .form__options__item input[type=checkbox]").attr('disabled', true);
55
+            if ($(".form__item-healthThought .form__options__item input[type=checkbox]:checked").length >= 2) {
56
+                $(".form__item-healthThought .form__options__item input[type=checkbox]:checked").attr('disabled', false);
57
+            } else {
58
+                $('.form__item-healthThought .form__options__item input[type=checkbox]').attr('disabled', false);
59
+            }
60
+        });
61
+
62
+		// 點擊資料表單"下一步"
63
+		$(".register .form-submit").on("click", function(){
64
+			// console.log("form-submit click");
65
+			$(this).addClass("disable");
66
+            $(".form-submit p").text("傳送中...");
67
+
68
+			if(checkRegister()) {
69
+				sendRegister();
70
+			}else {
71
+				base.myAlert(registerAlert);
72
+				$(this).removeClass("disable");
73
+                $(".form-submit p").text("下一步");
74
+			}
75
+		});
76
+	}
77
+
78
+	// Line大頭貼
79
+	function LinePicHandler(url) {
80
+
81
+		linePicUrl = url;
82
+		$(".photo__img").html("");
83
+		$(".photo__img").append(`
84
+			<img src="${linePicUrl}"/>
85
+		`);
86
+
87
+		const imageURL = linePicUrl;
88
+		if(imageURL.trim() !== '') {
89
+			const img = new Image();
90
+			img.src = imageURL;
91
+
92
+			const canvas = document.createElement("canvas");
93
+			const ctx = canvas.getContext("2d");
94
+			img.crossOrigin = 'Anonymous';
95
+
96
+			img.onload = function() {
97
+				canvas.width = img.width;
98
+				canvas.height = img.height;
99
+				ctx.drawImage(img, 0, 0);
100
+
101
+				// 將圖片轉換為 Base64
102
+				lineBase64Data = canvas.toDataURL('image/jpeg')
103
+				finalase64Data = lineBase64Data;
104
+
105
+				// console.log(finalase64Data)
106
+
107
+			}
108
+		}
109
+	}
110
+
111
+	// 選照片
112
+	function selectImage() {
113
+		const fileInputs = document.querySelectorAll('.fileInput');
114
+		const imagePreview = $('.photo__img');
115
+		// console.log(fileInput.id)
116
+
117
+
118
+		fileInputs.forEach((fileInput)=> {
119
+			// 當選擇圖片後,顯示圖片的預覽
120
+			fileInput.addEventListener("change", function(e){
121
+				console.log(fileInput.id)
122
+
123
+				const selectedFile = fileInput.files[0];
124
+
125
+				if(selectedFile) {
126
+					const reader = new FileReader();
127
+					reader.onload = function(e) {
128
+						// 移除 data:image/jpeg;base64,
129
+						// customBase64Data = e.target.result.split(",")[1];
130
+
131
+						customBase64Data = e.target.result;
132
+						finalase64Data = customBase64Data;
133
+						// console.log(e.target)
134
+						const img = new Image();
135
+						img.src = e.target.result;
136
+						imagePreview.html("");
137
+						imagePreview.append(img);
138
+
139
+						// console.log(finalase64Data)
140
+					}
141
+					reader.readAsDataURL(selectedFile);
142
+				}else {
143
+					LinePicHandler(linePicUrl);
144
+				}
145
+				if(fileInput.id == 'fileInput2') {
146
+					// console.log(finalase64Data)
147
+					sendBase64DataToApi(finalase64Data);
148
+				}
149
+			});
150
+		});
151
+	}
152
+
153
+	// 送出圖片
154
+	function sendBase64DataToApi(finalase64Data) {
155
+
156
+		GameService.getInstanse().userUpdatePhoto(finalase64Data).then(res => {
157
+			console.log('userUpdatePhoto:', res);
158
+			// base.myAlert('成功上傳。');
159
+		});
160
+		
161
+	}
162
+
163
+
164
+	function getCheckboxVal(name) {
165
+
166
+		let vals = $(".register input[type=checkbox][name="+name+"]:checked").map(function() {
167
+			return $(this).val();
168
+		}).get();
169
+
170
+		return vals;
171
+	}
172
+
173
+	function getRadioVal(name){
174
+		return $("input[name="+name+"]:checked").val();
175
+	}
176
+
177
+	function checkRegister(){
178
+		let isComplete = true;
179
+		registerAlert = "";
180
+
181
+		if(getCheckboxVal("healthAction").length > 0) {
182
+			registerData.healthAction = getCheckboxVal("healthAction");
183
+		}else {
184
+			isComplete = false;
185
+		}
186
+
187
+		if(getCheckboxVal("healthTopic").length > 0) {
188
+			registerData.healthTopic = getCheckboxVal("healthTopic");
189
+		}else {
190
+			isComplete = false;
191
+		}
192
+		
193
+		if(getRadioVal("healthStatus") !== "" && getRadioVal("healthStatus") !== undefined ) {
194
+			registerData.healthStatus = getRadioVal("healthStatus");
195
+		}else {
196
+			isComplete = false;
197
+		}
198
+
199
+		if(getRadioVal("healthAdapt") !== "" && getRadioVal("healthAdapt") !== undefined ) {
200
+			registerData.healthAdapt = getRadioVal("healthAdapt");
201
+		}else {
202
+			isComplete = false;
203
+		}
204
+
205
+		if(getCheckboxVal("healthThought").length > 0) {
206
+			registerData.healthThought = getCheckboxVal("healthThought");
207
+		}else {
208
+			isComplete = false;
209
+		}
210
+
211
+		if(getRadioVal("healthAge") !== "" && getRadioVal("healthAge") !== undefined ) {
212
+			registerData.healthAge = getRadioVal("healthAge");
213
+		}else {
214
+			isComplete = false;
215
+		}
216
+
217
+		if($("#nickName").val().trim() !== "") {
218
+			registerData.healthNickname = $("#nickName").val().trim();
219
+		}else {
220
+			isComplete = false;
221
+		}
222
+
223
+		if($("#gender").val() !== "") {
224
+
225
+			registerData.healthGender = $("#gender").val();
226
+
227
+			if($("#gender").val() === "tag-8HwqQuQ43") {
228
+				registerData.healthGenderRole = "female"
229
+			} else if($("#gender").val() === "tag-F8Me8-UGg") {
230
+				registerData.healthGenderRole = "male"
231
+			}else {
232
+				registerData.healthGenderRole = "";
233
+			}
234
+
235
+		}else {
236
+			isComplete = false;
237
+		}
238
+
239
+		if(!isComplete) {
240
+			registerAlert = "請確認問題皆已作答";
241
+		}
242
+
243
+		if(getCheckboxVal("methodsAgree").length == 0) {
244
+			registerAlert == "" ? registerAlert = "請勾選'我同意個人資料使用方法'" : registerAlert+="<br>請勾選'我同意個人資料使用方法'";
245
+			isComplete = false;
246
+		}
247
+
248
+		if(isComplete) {
249
+			registerData.headSticker = finalase64Data;
250
+			console.log(registerData)
251
+		}
252
+
253
+
254
+		return isComplete;
255
+	}
256
+
257
+	function sendRegister() {
258
+
259
+		// 測試用
260
+		// base.sectionFadeOut(".register");
261
+		// base.sectionFadeIn(".passport");
262
+		// $(".register .form-submit").removeClass("disable");
263
+        // $(".register .form-submit p").text("下一步");
264
+
265
+		// 正式用
266
+		GameService.getInstanse().userRegister(registerData)
267
+			.then(_res => {
268
+				console.log(_res);
269
+				base.sectionFadeOut(".register");
270
+				base.sectionFadeIn(".passport");
271
+				$(".register .form-submit").removeClass("disable");
272
+                $(".register .form-submit p").text("下一步");
273
+				// 清除表單
274
+				resetRegister();
275
+				// 再次載入取得資料
276
+				GameService.getInstanse().userLogin();
277
+				passport.buildPassportHandler(registerData);
278
+			})
279
+			.catch(_err => {
280
+				console.log(_err);
281
+				// let msg = err.message.replaceAll("Error:", "");
282
+				base.myAlert(_err);
283
+				$(".register .form-submit").removeClass("disable");
284
+                $(".register .form-submit p").text("下一步");
285
+			})
286
+	}
287
+
288
+	function resetRegister() {
289
+		$('.register .form input[type=checkbox], .register .form input[type=radio]').prop('checked', false);
290
+		$('.register .form input[type=text], .register .form select').val('');
291
+	}
292
+	
293
+
294
+
295
+	//constructor
296
+
297
+	{
298
+		$(document).ready(function () {
299
+			init();
300
+		});
301
+	}
302
+
303
+	//public
304
+
305
+	return {
306
+		LinePicHandler: function(url) {
307
+			LinePicHandler(url);
308
+		},
309
+		getCheckboxVal: function(name) {
310
+			return getCheckboxVal(name)
311
+		},
312
+		getRadioVal: function(name) {
313
+			return getRadioVal(name)
314
+		},
315
+		selectImage: function() {
316
+			selectImage();
317
+		}
318
+	};
319
+};
320
+
321
+var register = new register();

+ 140
- 0
src/fe/js/services/index.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 85
- 0
src/fe/js/services/userModel.js Datei anzeigen

1
+function UserModel(_lineUserId) {
2
+
3
+  let m_lineUserId = _lineUserId;
4
+
5
+  function init() {
6
+  }
7
+
8
+  /**
9
+   * 用戶登入
10
+   * @returns {TypeUserResponse} Promise
11
+   */
12
+  function loginUser () {
13
+    return POST('/api/JWPokeGame/getUserInfo.ashx', {
14
+      lineUserId: m_lineUserId,
15
+    });
16
+  }
17
+
18
+  /**
19
+   * 用戶註冊
20
+   * @param {object} _formdata 
21
+   * @returns {TypeResponse} Promise
22
+   */
23
+  function registerUser (_formdata) {
24
+    return POST('/api/JWPokeGame/saveUserInfo.ashx', {
25
+      lineUserId: m_lineUserId,
26
+      ..._formdata,
27
+    }).catch((error)=> {
28
+      console.log('_register:' + error);
29
+      throw '表單儲存失敗';
30
+    });
31
+  }
32
+
33
+  /**
34
+  * 用戶更新頭貼
35
+  * @returns {TypeUserResponse} Promise
36
+  */
37
+    function updatePhoto(base64Image) {
38
+      return POST('/api/JWPokeGame/getUserInfo.ashx', {
39
+        lineUserPhoto: base64Image,
40
+      });
41
+    }
42
+  
43
+  /**
44
+    * 驗證表單
45
+    * @param {object} formdata 
46
+    * @returns {Object | boolean}
47
+    */
48
+  function verifyUserForm(theContext) {
49
+    const {userName, IDNo, phone, birthday} = formdata;
50
+    let output;
51
+    
52
+    if (!userName || userName.length === 0) {
53
+      output['userName'] = '姓名格式不正確';
54
+    }
55
+
56
+    if (/[A-Za-z]{1}[1-2]{1}[0-9]{8}$/.test(IDNo)) {
57
+      output['IDNo'] = '身分證格式不正確';
58
+    }
59
+
60
+    if (/09\d{2}\d{3}\d{3}/.test(phone)) {
61
+      output['phone'] = '電話格式不正確';
62
+    }
63
+
64
+    if (!/[0-9]{4}\/[0-9]{3}\/[0-9]{3}$/.test(birthday)) {
65
+      output['birthday'] = '生日格式不正確';
66
+    }
67
+
68
+    if (output) {
69
+      return output;
70
+    }
71
+
72
+    return true;
73
+  }
74
+
75
+  {
76
+    init();  
77
+  }
78
+
79
+  return {
80
+    loginUser,
81
+    registerUser,
82
+    verifyUserForm,
83
+    updatePhoto
84
+  }
85
+}

+ 212
- 0
src/fe/js/tagData.json Datei anzeigen

1
+[
2
+    {
3
+        "question": "平常你有什麼健康行動(複選)",
4
+        "questionName": "healthAction",
5
+        "tags": [
6
+            {
7
+                "answer": "良好作息",
8
+                "tagName": "良好作息",
9
+                "tagId": "tag-WCzAvKUiL"
10
+            },
11
+            {
12
+                "answer": "規律運動",
13
+                "tagName": "規律運動",
14
+                "tagId": "tag-lIcE-WkEe"
15
+            },
16
+            {
17
+                "answer": "飲食控制",
18
+                "tagName": "飲食控制",
19
+                "tagId": "tag-uEOBbgPoG"
20
+            },
21
+            {
22
+                "answer": "營養品補充",
23
+                "tagName": "營養品補充",
24
+                "tagId": "tag-YEJfK7-I7"
25
+            },
26
+            {
27
+                "answer": "閱讀健康文章",
28
+                "tagName": "閱讀健康文章",
29
+                "tagId": "tag-stfrz1nD8"
30
+            },
31
+            {
32
+                "answer": "其他",
33
+                "tagName": "X",
34
+                "tagId": "x"
35
+            }
36
+        ]
37
+        
38
+    },
39
+    {
40
+        "question": "你對什麼健康話題有興趣(複選)",
41
+        "questionName": "healthTopic",
42
+        "tags": [
43
+            {
44
+                "answer": "流行感冒",
45
+                "tagName": "流行感冒",
46
+                "tagId": "tag-vstHmk4YP"
47
+            },
48
+            {
49
+                "answer": "免疫調節",
50
+                "tagName": "免疫調節",
51
+                "tagId": "tag-CorN36876"
52
+            },
53
+            {
54
+                "answer": "腸胃功能",
55
+                "tagName": "腸胃功能",
56
+                "tagId": "tag-nWHBzbUCr"
57
+            },
58
+            {
59
+                "answer": "過敏體質",
60
+                "tagName": "過敏體質",
61
+                "tagId": "tag-VQSDoXlAL"
62
+            },
63
+            {
64
+                "answer": "睡眠問題",
65
+                "tagName": "睡眠問題",
66
+                "tagId": "tag-MLdZCbE9y"
67
+            },
68
+            {
69
+                "answer": "日常保健",
70
+                "tagName": "日常保健",
71
+                "tagId": "tag-Yz0_DhZBV"
72
+            }
73
+        ]
74
+        
75
+    },
76
+    {
77
+        "question": "你覺得自己的身體狀況如何",
78
+        "questionName": "healthStatus",
79
+        "tags": [
80
+            {
81
+                "answer": "很少生病",
82
+                "tagName": "很少生病",
83
+                "tagId": "tag-TN-u8YIrm"
84
+            },
85
+            {
86
+                "question": "",
87
+                "answer": "偶爾疲倦",
88
+                "tagName": "偶爾疲倦",
89
+                "tagId": "tag-ATnIMezXK"
90
+            },
91
+            {
92
+                "question": "",
93
+                "answer": "經常感冒",
94
+                "tagName": "經常感冒",
95
+                "tagId": "tag-LJg1ec9-L"
96
+            }
97
+        ]
98
+    },
99
+    {
100
+        "question": "面對疫情趨緩,以下哪一個敘述最符合你的應對",
101
+        "questionName": "healthAdapt",
102
+        "tags": [
103
+            {
104
+                "answer": "我仍會主動參考政府機構的資訊,持續戴口罩積極防疫",
105
+                "tagName": "一直戴口罩",
106
+                "tagId": "tag-bDRawibcP"
107
+            },
108
+            {
109
+                "answer": "我在前往人多的地方或搭乘大眾交通工具時會配戴口罩​",
110
+                "tagName": "人多戴口罩",
111
+                "tagId": "tag-JiWCgTnNs"
112
+            },
113
+            {
114
+                "answer": "我不再對疫情感到恐慌,幾乎不戴口罩、回到正常生活",
115
+                "tagName": "不戴口罩",
116
+                "tagId": "tag-4dcsmiwqt"
117
+            }
118
+
119
+        ]
120
+        
121
+    },
122
+    {
123
+        "question": "下列哪一個敘述最符合你的想法",
124
+        "questionName": "healthThought",
125
+        "tags": [
126
+            {
127
+                "answer": "我願意了解新的疫苗並採取行動",
128
+                "tagName": "開放性人格",
129
+                "tagId": "tag-FhMvcmSJm"
130
+            },
131
+            {
132
+                "answer": "我會自律做好防疫,避免造成他人困擾",
133
+                "tagName": "嚴謹性人格",
134
+                "tagId": "tag-g4GSGpTHq"
135
+            },
136
+            {
137
+                "answer": "我覺得應該維持正常社交,不用過度緊張​",
138
+                "tagName": "外向性人格",
139
+                "tagId": "tag-lDhpoS39o"
140
+            },
141
+            {
142
+                "answer": "我覺得保持正向的態度,與病毒共處自然會產生抗體​",
143
+                "tagName": "親和性人格",
144
+                "tagId": "tag-qmywOc8af"
145
+            },
146
+            {
147
+                "answer": "沒做好防疫準備,我會感到焦慮",
148
+                "tagName": "神經質人格",
149
+                "tagId": "tag-77KImqQGb"
150
+            }
151
+        ]
152
+        
153
+    },
154
+    {
155
+        "question": "你的年齡",
156
+        "questionName": "healthAge",
157
+        "tags": [
158
+            {
159
+                "answer": "20歲以下",
160
+                "tagName": "20歲以下",
161
+                "tagId": "tag-bjbXSt2gi"
162
+            },
163
+            {
164
+                "answer": "20-29歲",
165
+                "tagName": "20-29歲",
166
+                "tagId": "tag-qYe0v6HqF"
167
+            },
168
+            {
169
+                "answer": "30-39歲",
170
+                "tagName": "30-39歲",
171
+                "tagId": "tag-6iaNB8Ea4"
172
+            },
173
+            {
174
+                "answer": "40-49歲",
175
+                "tagName": "40-49歲",
176
+                "tagId": "tag-e4JG3GBG_"
177
+            },
178
+            {
179
+                "answer": "50-59歲",
180
+                "tagName": "50-59歲",
181
+                "tagId": "tag-DTE6DWovG"
182
+            },
183
+            {
184
+                "answer": "59歲以上",
185
+                "tagName": "59歲以上",
186
+                "tagId": "tag-pAxHnckQs"
187
+            }
188
+        ]
189
+    },
190
+    {
191
+        "question": "性別",
192
+        "questionName": "healthGender",
193
+        "tags": [
194
+            {
195
+                "answer": "男性",
196
+                "tagName": "男性",
197
+                "tagId": "tag-F8Me8-UGg"
198
+            },
199
+            {
200
+                "answer": "女性",
201
+                "tagName": "女性",
202
+                "tagId": "tag-8HwqQuQ43"
203
+            },
204
+            {
205
+                "answer": "不提供",
206
+                "tagName": "不提供性別",
207
+                "tagId": "tag-BrpgwlI5E"
208
+            }
209
+        ]
210
+        
211
+    }
212
+]

+ 70
- 0
src/fe/js/type/index.ts Datei anzeigen

1
+type TypeResponse = {
2
+  success: boolean,
3
+  msg: string,
4
+  data: object | null
5
+}
6
+
7
+type TypeUserResponse = {
8
+  success: boolean,
9
+  msg: string,
10
+  data: {
11
+    id: number,
12
+    activityId: number ,
13
+    lineUserId: string,
14
+    lineName: string,
15
+    picUrl: string,
16
+    userStatus: number,
17
+    agreePolicy: number,
18
+    taxFiled: number,
19
+    totalPrize: number,
20
+    cdate: string
21
+  }
22
+}
23
+
24
+type TypeCoupon = {
25
+  title: string,
26
+  subTitle: string,
27
+  keyValue: string,
28
+  totalPrize: number,
29
+  processStatus: number, // 狀態 => 0:待領取(空白)1:待專人聯繫 2:待同意 3:已同意&已領取 4:已同意&已領取
30
+  cdate: string
31
+}
32
+
33
+type TypeCouponItem = {
34
+  id: number,
35
+  campaignId: number,
36
+  activityId: number,
37
+  title: string,
38
+  subTitle: string,
39
+  keyValue: string,
40
+  pin: string,
41
+  activityCheckCode: string,
42
+  used: number,
43
+  userId: number,
44
+  useDate: string,
45
+  city: string,
46
+  area: string,
47
+  store: string,
48
+  processStatus: number, // 狀態 => 0:待領取(空白)1:待專人聯繫 2:待同意 3:已同意&已領取 4:已同意&已領取
49
+  cdate: string
50
+}
51
+
52
+type TypeCouponResponse = {
53
+  success: boolean,
54
+  msg: "ok",
55
+  data: TypeCoupon
56
+}
57
+
58
+type TypeCouponListResponse = {
59
+  success: boolean,
60
+  msg: "ok",
61
+  data: TypeCouponItem[]
62
+}
63
+
64
+type TypeRedeemCouponResponse = {
65
+  success: boolean,
66
+  msg: string,
67
+  data: {
68
+    quoteId: number
69
+  }
70
+}

+ 267
- 0
src/fe/js/utlis.js Datei anzeigen

1
+
2
+/* utlis */
3
+
4
+// if (typeof console == "undefined") {
5
+//     window.console = {
6
+//         log: function () {}
7
+//     };
8
+// }
9
+
10
+// window.console = {
11
+//        log: function () {}
12
+// };
13
+
14
+isLIVE = false;
15
+
16
+switch (window.location.host.toLowerCase()) {
17
+
18
+  case 'mortlach-com.diageoplatform.com':
19
+    isLIVE = false;
20
+    break;
21
+
22
+  case 'line.maltssociety.com.tw':
23
+    isLIVE = true;
24
+    break;
25
+
26
+  case 'www.mortlach.com.tw':
27
+    isLIVE = true;
28
+    break;
29
+}
30
+
31
+console.log('isLIVE : ' + isLIVE);
32
+
33
+function gtag_pageView(_key) {
34
+  //console.log("gtag_pageView: " + _key);
35
+}
36
+
37
+function gtag_ButtonClick(_key) {
38
+  console.log("gtag_ButtonClick: " + _key);
39
+
40
+  window.dataLayer = window.dataLayer || [];
41
+  window.dataLayer.push({
42
+    'event': 'customEvent',
43
+    'eventCategory': 'Button',
44
+    'eventAction': 'Click',
45
+    'eventLabel': _key
46
+  });
47
+}
48
+
49
+function setDefault(_textbox, _value) { // depend on jQuery
50
+  $(_textbox).val(_value).css({ opacity: .4 });
51
+  $(_textbox).focus(
52
+    function () {
53
+      if ($(this).val() == _value) {
54
+        $(this).val('').css({ opacity: 1 });
55
+      }
56
+    })
57
+    .blur(function () {
58
+      if ($(this).val() == '') {
59
+        $(this).val(_value).css({ opacity: .4 });
60
+      }
61
+    });
62
+}
63
+
64
+function getParameterByName(name, url) {
65
+  if (!url) url = window.location.href;
66
+  name = name.replace(/[\[\]]/g, "\\$&");
67
+  var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
68
+    results = regex.exec(url);
69
+  if (!results) return null;
70
+  if (!results[2]) return '';
71
+  return decodeURIComponent(results[2].replace(/\+/g, " "));
72
+}
73
+
74
+function setParameterByName(name, value, url) {
75
+  if (!url) url = window.location.href;
76
+  var re = new RegExp("([?|&])" + name + "=.*?(&|$)", "i");
77
+  separator = url.indexOf('?') !== -1 ? "&" : "?";
78
+  if (url.match(re)) {
79
+    return url.replace(re, '$1' + name + "=" + value + '$2');
80
+  }
81
+  else {
82
+    return url + separator + name + "=" + value;
83
+  }
84
+}
85
+
86
+function loadAnimate(_namespace, $container, _callback) {
87
+  var $canvas, stage, exportRoot, anim_container, dom_overlay_container, fnStartAnimation;
88
+
89
+  var key = Object.keys(this[_namespace].compositions)[0];
90
+  var comp = this[_namespace].getComposition(key);
91
+  var lib = comp.getLibrary();
92
+
93
+  $canvas = $('<canvas></canvas>').attr({
94
+    width: lib.properties.width,
95
+    height: lib.properties.height
96
+  }).appendTo($container);
97
+
98
+  var loader = new createjs.LoadQueue(false);
99
+  loader.addEventListener("fileload", function (evt) { handleFileLoad(evt, comp) });
100
+  loader.addEventListener("complete", function (evt) { handleComplete(evt, comp) });
101
+  loader.loadManifest(lib.properties.manifest);
102
+
103
+  function handleFileLoad(evt, comp) {
104
+    var images = comp.getImages();
105
+    if (evt && (evt.item.type == "image")) { images[evt.item.id] = evt.result; }
106
+  }
107
+  function handleComplete(evt, comp) {
108
+    var lib = comp.getLibrary();
109
+    var ss = comp.getSpriteSheet();
110
+    var queue = evt.target;
111
+    var ssMetadata = lib.ssMetadata;
112
+    for (i = 0; i < ssMetadata.length; i++) {
113
+      ss[ssMetadata[i].name] = new createjs.SpriteSheet({ "images": [queue.getResult(ssMetadata[i].name)], "frames": ssMetadata[i].frames })
114
+    }
115
+    exportRoot = new lib[_namespace]();
116
+    stage = new lib.Stage($canvas[0]);
117
+    fnStartAnimation = function () {
118
+      stage.addChild(exportRoot);
119
+      createjs.Ticker.setFPS(lib.properties.fps);
120
+      createjs.Ticker.addEventListener("tick", stage);
121
+      exportRoot.stop();
122
+      if (_callback != null) {
123
+        _callback(exportRoot);
124
+      }
125
+    }
126
+
127
+    this[_namespace].compositionLoaded(lib.properties.id);
128
+    fnStartAnimation();
129
+  }
130
+}
131
+
132
+function setCookie(name,value,days) {
133
+  var expires = "";
134
+  if (days) {
135
+      var date = new Date();
136
+      date.setTime(date.getTime() + (days*24*60*60*1000));
137
+      expires = "; expires=" + date.toUTCString();
138
+  }
139
+  document.cookie = name + "=" + (value || "")  + expires + "; path=/";
140
+}
141
+function getCookie(name) {
142
+  var nameEQ = name + "=";
143
+  var ca = document.cookie.split(';');
144
+  for(var i=0;i < ca.length;i++) {
145
+      var c = ca[i];
146
+      while (c.charAt(0)==' ') c = c.substring(1,c.length);
147
+      if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
148
+  }
149
+  return null;
150
+}
151
+function eraseCookie(name) {   
152
+  document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
153
+}
154
+
155
+function POST(theUrl, theData) {
156
+  const _url = API__DOMAIN + theUrl;
157
+  return fetch(_url, {
158
+    method: 'POST',
159
+    headers: {
160
+      'Content-Type': 'application/json'
161
+    },
162
+    body: JSON.stringify(theData)
163
+  })
164
+  .then((response) => {
165
+    return response.json(); 
166
+  }).then((jsonData) => {
167
+    const { success, msg } = jsonData;
168
+    if (!success) {
169
+      throw new Error(msg);
170
+    }
171
+    return jsonData;
172
+  }).catch((err) => {
173
+    throw new Error(err);
174
+  });
175
+}
176
+
177
+function GET(theUrl, theData) {
178
+  const _url = API__DOMAIN + theUrl +'?' + serialize(theData);
179
+  return fetch(_url, {})
180
+    .then((response) => {
181
+      return response.json(); 
182
+    }).then((jsonData) => {
183
+      const { success, msg } = jsonData;
184
+      if (!success) {
185
+        throw new Error(msg);
186
+      }
187
+      return jsonData;
188
+    }).catch((err) => {
189
+      throw new Error(err);
190
+  });
191
+}
192
+
193
+const PRE__LIFFID = '2000769399-lGpVNobN'; // 測試liffId待定
194
+const PRO__LIFFID = '2000844179-J80gOzVP'; // 正式liffId待定
195
+const LIFFID = (isLIVE) ? PRO__LIFFID : PRE__LIFFID;
196
+
197
+function liffInit() {
198
+  return new Promise((resolve, reject) => {
199
+    liff.init({
200
+      liffId: LIFFID,
201
+    }).then(() => {
202
+      if (!liff.isLoggedIn() && !liff.isInClient()) {
203
+        liff.login();
204
+      } else {
205
+        liff.getProfile().then((profile) => {
206
+          resolve(profile);
207
+        })
208
+        .catch((err)=>{
209
+          console.log(err)
210
+        });
211
+      }
212
+    }).catch((err) => {
213
+      reject(new Error(err));
214
+    });
215
+  });
216
+}
217
+
218
+function sleep(seconds) {
219
+  return new Promise((resolve, reject) => {
220
+    let _t = setTimeout(() => {
221
+      clearTimeout(_t);
222
+      _t - null;
223
+      resolve();
224
+    }, seconds);  
225
+  });
226
+}
227
+
228
+const _PRE__HOST = 'mortlach-com.diageoplatform.com';
229
+const _PRO__HOST = 'line.maltssociety.com.tw';
230
+const _URL = location.hostname;
231
+const _host = (_URL.indexOf(_PRO__HOST) != -1) ? _PRO__HOST : _PRE__HOST;
232
+const API__DOMAIN = 'https://' + _host;
233
+
234
+
235
+var isIE = false;
236
+
237
+utlis = function () {
238
+
239
+  //private menbers
240
+
241
+
242
+  //private methods
243
+  function init() {
244
+    console.log('all is loaded.');
245
+  }
246
+
247
+  //constructor
248
+
249
+  {
250
+    if ($('html').is('.ie6, .ie7, .ie8')) {
251
+      isIE = true;
252
+      // alert('.ie6, .ie7, .ie8');
253
+    }
254
+
255
+    $(document).ready(function () {
256
+      init();
257
+    });
258
+  }
259
+
260
+  //public
261
+
262
+  return {
263
+
264
+  }
265
+}
266
+
267
+utlis = new utlis();

+ 12
- 0
src/fe/lib/cookie.js Datei anzeigen

1
+function SetCookie(name,value)
2
+{
3
+    var Days = 30;
4
+    var exp  = new Date();
5
+    exp.setTime(exp.getTime() + Days*24*60*60*1000);
6
+    document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
7
+}
8
+function getCookie(name)    
9
+{
10
+    var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
11
+    if(arr != null) return unescape(arr[2]); return null;
12
+}

+ 6
- 0
src/fe/lib/current-device.min.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 11
- 0
src/fe/lib/gsap.min.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 2
- 0
src/fe/lib/jquery-3.5.1.min.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 320
- 0
src/fe/lib/jquery.mobile.touch.min.js Datei anzeigen

1
+/*! jQuery Mobile v1.4.5 | Copyright 2010, 2014 jQuery Foundation, Inc. | jquery.org/license */
2
+
3
+(function (e, t, n) {
4
+    typeof define == "function" && define.amd ? define(["jquery"], function (r) {
5
+        return n(r, e, t), r.mobile
6
+    }) : n(e.jQuery, e, t)
7
+})(this, document, function (e, t, n, r) {
8
+    (function (e, t, n, r) {
9
+        function T(e) {
10
+            while (e && typeof e.originalEvent != "undefined")e = e.originalEvent;
11
+            return e
12
+        }
13
+
14
+        function N(t, n) {
15
+            var i = t.type, s, o, a, l, c, h, p, d, v;
16
+            t = e.Event(t), t.type = n, s = t.originalEvent, o = e.event.props, i.search(/^(mouse|click)/) > -1 && (o = f);
17
+            if (s)for (p = o.length, l; p;)l = o[--p], t[l] = s[l];
18
+            i.search(/mouse(down|up)|click/) > -1 && !t.which && (t.which = 1);
19
+            if (i.search(/^touch/) !== -1) {
20
+                a = T(s), i = a.touches, c = a.changedTouches, h = i && i.length ? i[0] : c && c.length ? c[0] : r;
21
+                if (h)for (d = 0, v = u.length; d < v; d++)l = u[d], t[l] = h[l]
22
+            }
23
+            return t
24
+        }
25
+
26
+        function C(t) {
27
+            var n = {}, r, s;
28
+            while (t) {
29
+                r = e.data(t, i);
30
+                for (s in r)r[s] && (n[s] = n.hasVirtualBinding = !0);
31
+                t = t.parentNode
32
+            }
33
+            return n
34
+        }
35
+
36
+        function k(t, n) {
37
+            var r;
38
+            while (t) {
39
+                r = e.data(t, i);
40
+                if (r && (!n || r[n]))return t;
41
+                t = t.parentNode
42
+            }
43
+            return null
44
+        }
45
+
46
+        function L() {
47
+            g = !1
48
+        }
49
+
50
+        function A() {
51
+            g = !0
52
+        }
53
+
54
+        function O() {
55
+            E = 0, v.length = 0, m = !1, A()
56
+        }
57
+
58
+        function M() {
59
+            L()
60
+        }
61
+
62
+        function _() {
63
+            D(), c = setTimeout(function () {
64
+                c = 0, O()
65
+            }, e.vmouse.resetTimerDuration)
66
+        }
67
+
68
+        function D() {
69
+            c && (clearTimeout(c), c = 0)
70
+        }
71
+
72
+        function P(t, n, r) {
73
+            var i;
74
+            if (r && r[t] || !r && k(n.target, t))i = N(n, t), e(n.target).trigger(i);
75
+            return i
76
+        }
77
+
78
+        function H(t) {
79
+            var n = e.data(t.target, s), r;
80
+            !m && (!E || E !== n) && (r = P("v" + t.type, t), r && (r.isDefaultPrevented() && t.preventDefault(), r.isPropagationStopped() && t.stopPropagation(), r.isImmediatePropagationStopped() && t.stopImmediatePropagation()))
81
+        }
82
+
83
+        function B(t) {
84
+            var n = T(t).touches, r, i, o;
85
+            n && n.length === 1 && (r = t.target, i = C(r), i.hasVirtualBinding && (E = w++, e.data(r, s, E), D(), M(), d = !1, o = T(t).touches[0], h = o.pageX, p = o.pageY, P("vmouseover", t, i), P("vmousedown", t, i)))
86
+        }
87
+
88
+        function j(e) {
89
+            if (g)return;
90
+            d || P("vmousecancel", e, C(e.target)), d = !0, _()
91
+        }
92
+
93
+        function F(t) {
94
+            if (g)return;
95
+            var n = T(t).touches[0], r = d, i = e.vmouse.moveDistanceThreshold, s = C(t.target);
96
+            d = d || Math.abs(n.pageX - h) > i || Math.abs(n.pageY - p) > i, d && !r && P("vmousecancel", t, s), P("vmousemove", t, s), _()
97
+        }
98
+
99
+        function I(e) {
100
+            if (g)return;
101
+            A();
102
+            var t = C(e.target), n, r;
103
+            P("vmouseup", e, t), d || (n = P("vclick", e, t), n && n.isDefaultPrevented() && (r = T(e).changedTouches[0], v.push({touchID: E, x: r.clientX, y: r.clientY}), m = !0)), P("vmouseout", e, t), d = !1, _()
104
+        }
105
+
106
+        function q(t) {
107
+            var n = e.data(t, i), r;
108
+            if (n)for (r in n)if (n[r])return !0;
109
+            return !1
110
+        }
111
+
112
+        function R() {
113
+        }
114
+
115
+        function U(t) {
116
+            var n = t.substr(1);
117
+            return {
118
+                setup: function () {
119
+                    q(this) || e.data(this, i, {});
120
+                    var r = e.data(this, i);
121
+                    r[t] = !0, l[t] = (l[t] || 0) + 1, l[t] === 1 && b.bind(n, H), e(this).bind(n, R), y && (l.touchstart = (l.touchstart || 0) + 1, l.touchstart === 1 && b.bind("touchstart", B).bind("touchend", I).bind("touchmove", F).bind("scroll", j))
122
+                }, teardown: function () {
123
+                    --l[t], l[t] || b.unbind(n, H), y && (--l.touchstart, l.touchstart || b.unbind("touchstart", B).unbind("touchmove", F).unbind("touchend", I).unbind("scroll", j));
124
+                    var r = e(this), s = e.data(this, i);
125
+                    s && (s[t] = !1), r.unbind(n, R), q(this) || r.removeData(i)
126
+                }
127
+            }
128
+        }
129
+
130
+        var i = "virtualMouseBindings", s = "virtualTouchID", o = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split(" "), u = "clientX clientY pageX pageY screenX screenY".split(" "), a = e.event.mouseHooks ? e.event.mouseHooks.props : [], f = e.event.props.concat(a), l = {}, c = 0, h = 0, p = 0, d = !1, v = [], m = !1, g = !1, y = "addEventListener"in n, b = e(n), w = 1, E = 0, S, x;
131
+        e.vmouse = {moveDistanceThreshold: 10, clickDistanceThreshold: 10, resetTimerDuration: 1500};
132
+        for (x = 0; x < o.length; x++)e.event.special[o[x]] = U(o[x]);
133
+        y && n.addEventListener("click", function (t) {
134
+            var n = v.length, r = t.target, i, o, u, a, f, l;
135
+            if (n) {
136
+                i = t.clientX, o = t.clientY, S = e.vmouse.clickDistanceThreshold, u = r;
137
+                while (u) {
138
+                    for (a = 0; a < n; a++) {
139
+                        f = v[a], l = 0;
140
+                        if (u === r && Math.abs(f.x - i) < S && Math.abs(f.y - o) < S || e.data(u, s) === f.touchID) {
141
+                            t.preventDefault(), t.stopPropagation();
142
+                            return
143
+                        }
144
+                    }
145
+                    u = u.parentNode
146
+                }
147
+            }
148
+        }, !0)
149
+    })(e, t, n), function (e) {
150
+        e.mobile = {}
151
+    }(e), function (e, t) {
152
+        var r = {touch: "ontouchend"in n};
153
+        e.mobile.support = e.mobile.support || {}, e.extend(e.support, r), e.extend(e.mobile.support, r)
154
+    }(e), function (e, t, r) {
155
+        function l(t, n, i, s) {
156
+            var o = i.type;
157
+            i.type = n, s ? e.event.trigger(i, r, t) : e.event.dispatch.call(t, i), i.type = o
158
+        }
159
+
160
+        var i = e(n), s = e.mobile.support.touch, o = "touchmove scroll", u = s ? "touchstart" : "mousedown", a = s ? "touchend" : "mouseup", f = s ? "touchmove" : "mousemove";
161
+        e.each("touchstart touchmove touchend tap taphold swipe swipeleft swiperight scrollstart scrollstop".split(" "), function (t, n) {
162
+            e.fn[n] = function (e) {
163
+                return e ? this.bind(n, e) : this.trigger(n)
164
+            }, e.attrFn && (e.attrFn[n] = !0)
165
+        }), e.event.special.scrollstart = {
166
+            enabled: !0, setup: function () {
167
+                function s(e, n) {
168
+                    r = n, l(t, r ? "scrollstart" : "scrollstop", e)
169
+                }
170
+
171
+                var t = this, n = e(t), r, i;
172
+                n.bind(o, function (t) {
173
+                    if (!e.event.special.scrollstart.enabled)return;
174
+                    r || s(t, !0), clearTimeout(i), i = setTimeout(function () {
175
+                        s(t, !1)
176
+                    }, 50)
177
+                })
178
+            }, teardown: function () {
179
+                e(this).unbind(o)
180
+            }
181
+        }, e.event.special.tap = {
182
+            tapholdThreshold: 750, emitTapOnTaphold: !0, setup: function () {
183
+                var t = this, n = e(t), r = !1;
184
+                n.bind("vmousedown", function (s) {
185
+                    function a() {
186
+                        clearTimeout(u)
187
+                    }
188
+
189
+                    function f() {
190
+                        a(), n.unbind("vclick", c).unbind("vmouseup", a), i.unbind("vmousecancel", f)
191
+                    }
192
+
193
+                    function c(e) {
194
+                        f(), !r && o === e.target ? l(t, "tap", e) : r && e.preventDefault()
195
+                    }
196
+
197
+                    r = !1;
198
+                    if (s.which && s.which !== 1)return !1;
199
+                    var o = s.target, u;
200
+                    n.bind("vmouseup", a).bind("vclick", c), i.bind("vmousecancel", f), u = setTimeout(function () {
201
+                        e.event.special.tap.emitTapOnTaphold || (r = !0), l(t, "taphold", e.Event("taphold", {target: o}))
202
+                    }, e.event.special.tap.tapholdThreshold)
203
+                })
204
+            }, teardown: function () {
205
+                e(this).unbind("vmousedown").unbind("vclick").unbind("vmouseup"), i.unbind("vmousecancel")
206
+            }
207
+        }, e.event.special.swipe = {
208
+            scrollSupressionThreshold: 30, durationThreshold: 1e3, horizontalDistanceThreshold: 30, verticalDistanceThreshold: 30, getLocation: function (e) {
209
+                var n = t.pageXOffset, r = t.pageYOffset, i = e.clientX, s = e.clientY;
210
+                if (e.pageY === 0 && Math.floor(s) > Math.floor(e.pageY) || e.pageX === 0 && Math.floor(i) > Math.floor(e.pageX))i -= n, s -= r; else if (s < e.pageY - r || i < e.pageX - n)i = e.pageX - n, s = e.pageY - r;
211
+                return {x: i, y: s}
212
+            }, start: function (t) {
213
+                var n = t.originalEvent.touches ? t.originalEvent.touches[0] : t, r = e.event.special.swipe.getLocation(n);
214
+                return {time: (new Date).getTime(), coords: [r.x, r.y], origin: e(t.target)}
215
+            }, stop: function (t) {
216
+                var n = t.originalEvent.touches ? t.originalEvent.touches[0] : t, r = e.event.special.swipe.getLocation(n);
217
+                return {time: (new Date).getTime(), coords: [r.x, r.y]}
218
+            }, handleSwipe: function (t, n, r, i) {
219
+                if (n.time - t.time < e.event.special.swipe.durationThreshold && Math.abs(t.coords[0] - n.coords[0]) > e.event.special.swipe.horizontalDistanceThreshold && Math.abs(t.coords[1] - n.coords[1]) < e.event.special.swipe.verticalDistanceThreshold) {
220
+                    var s = t.coords[0] > n.coords[0] ? "swipeleft" : "swiperight";
221
+                    return l(r, "swipe", e.Event("swipe", {target: i, swipestart: t, swipestop: n}), !0), l(r, s, e.Event(s, {target: i, swipestart: t, swipestop: n}), !0), !0
222
+                }
223
+                return !1
224
+            }, eventInProgress: !1, setup: function () {
225
+                var t, n = this, r = e(n), s = {};
226
+                t = e.data(this, "mobile-events"), t || (t = {length: 0}, e.data(this, "mobile-events", t)), t.length++, t.swipe = s, s.start = function (t) {
227
+                    if (e.event.special.swipe.eventInProgress)return;
228
+                    e.event.special.swipe.eventInProgress = !0;
229
+                    var r, o = e.event.special.swipe.start(t), u = t.target, l = !1;
230
+                    s.move = function (t) {
231
+                        if (!o || t.isDefaultPrevented())return;
232
+                        r = e.event.special.swipe.stop(t), l || (l = e.event.special.swipe.handleSwipe(o, r, n, u), l && (e.event.special.swipe.eventInProgress = !1)), Math.abs(o.coords[0] - r.coords[0]) > e.event.special.swipe.scrollSupressionThreshold && t.preventDefault()
233
+                    }, s.stop = function () {
234
+                        l = !0, e.event.special.swipe.eventInProgress = !1, i.off(f, s.move), s.move = null
235
+                    }, i.on(f, s.move).one(a, s.stop)
236
+                }, r.on(u, s.start)
237
+            }, teardown: function () {
238
+                var t, n;
239
+                t = e.data(this, "mobile-events"), t && (n = t.swipe, delete t.swipe, t.length--, t.length === 0 && e.removeData(this, "mobile-events")), n && (n.start && e(this).off(u, n.start), n.move && i.off(f, n.move), n.stop && i.off(a, n.stop))
240
+            }
241
+        }, e.each({scrollstop: "scrollstart", taphold: "tap", swipeleft: "swipe.left", swiperight: "swipe.right"}, function (t, n) {
242
+            e.event.special[t] = {
243
+                setup: function () {
244
+                    e(this).bind(n, e.noop)
245
+                }, teardown: function () {
246
+                    e(this).unbind(n)
247
+                }
248
+            }
249
+        })
250
+    }(e, this)
251
+});
252
+
253
+(function() {
254
+    var supportTouch = $.support.touch,
255
+        scrollEvent = "touchmove scroll",
256
+        touchStartEvent = supportTouch ? "touchstart" : "mousedown",
257
+        touchStopEvent = supportTouch ? "touchend" : "mouseup",
258
+        touchMoveEvent = supportTouch ? "touchmove" : "mousemove";
259
+    $.event.special.swipeupdown = {
260
+        setup: function() {
261
+            var thisObject = this;
262
+            var $this = $(thisObject);
263
+            $this.bind(touchStartEvent, function(event) {
264
+                var data = event.originalEvent.touches ?
265
+                        event.originalEvent.touches[ 0 ] :
266
+                        event,
267
+                    start = {
268
+                        time: (new Date).getTime(),
269
+                        coords: [ data.pageX, data.pageY ],
270
+                        origin: $(event.target)
271
+                    },
272
+                    stop;
273
+
274
+                function moveHandler(event) {
275
+                    if (!start) {
276
+                        return;
277
+                    }
278
+                    var data = event.originalEvent.touches ?
279
+                        event.originalEvent.touches[ 0 ] :
280
+                        event;
281
+                    stop = {
282
+                        time: (new Date).getTime(),
283
+                        coords: [ data.pageX, data.pageY ]
284
+                    };
285
+
286
+                    // prevent scrolling
287
+                    if (Math.abs(start.coords[1] - stop.coords[1]) > 10) {
288
+                        event.preventDefault();
289
+                    }
290
+                }
291
+                $this
292
+                    .bind(touchMoveEvent, moveHandler)
293
+                    .one(touchStopEvent, function(event) {
294
+                        $this.unbind(touchMoveEvent, moveHandler);
295
+                        if (start && stop) {
296
+                            if (stop.time - start.time < 1000 &&
297
+                                Math.abs(start.coords[1] - stop.coords[1]) > 30 &&
298
+                                Math.abs(start.coords[0] - stop.coords[0]) < 75) {
299
+                                start.origin
300
+                                    .trigger("swipeupdown")
301
+                                    .trigger(start.coords[1] > stop.coords[1] ? "swipeup" : "swipedown");
302
+                            }
303
+                        }
304
+                        start = stop = undefined;
305
+                    });
306
+            });
307
+        }
308
+    };
309
+    $.each({
310
+        swipedown: "swipeupdown",
311
+        swipeup: "swipeupdown"
312
+    }, function(event, sourceEvent){
313
+        $.event.special[event] = {
314
+            setup: function(){
315
+                $(this).bind(sourceEvent, $.noop);
316
+            }
317
+        };
318
+    });
319
+
320
+})();

+ 2
- 0
src/fe/lib/jquery.nicescroll.min.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 1
- 0
src/fe/lib/line-sdk.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 14
- 0
src/fe/lib/swiper.min.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen