Skip to content

feat: stage5 #96

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
213 changes: 113 additions & 100 deletions docs/.vuepress/config.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/.vuepress/enhanceApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import VueSelect from "vue-select";
import "vue-select/src/scss/vue-select.scss";
import Pagination from "vue-pagination-2";
import VTooltip from "v-tooltip";
import VueClipboard from "vue-clipboard2";

export default ({ Vue, options, router, siteData }) => {
Vue.use(VueNotification);
Vue.use(VTooltip);
Vue.use(VueClipboard);
Vue.component("v-select", VueSelect);
Vue.component("v-pagination", Pagination);
Vue.extend({
Expand Down
342 changes: 342 additions & 0 deletions docs/.vuepress/theme/components/FeedbackModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
<template>
<div>
<div
v-show="selectWordVisible"
class="select-word"
:style="{ top: selectY, left: selectX }"
>
<a href="#" @click.stop="showFeedback">
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style="display: inline-block; vertical-align: text-bottom"
>
<path
d="M4.3035 12.6667L1.3335 15V2.66667C1.3335 2.48986 1.40373 2.32029 1.52876 2.19526C1.65378 2.07024 1.82335 2 2.00016 2H14.0002C14.177 2 14.3465 2.07024 14.4716 2.19526C14.5966 2.32029 14.6668 2.48986 14.6668 2.66667V12C14.6668 12.1768 14.5966 12.3464 14.4716 12.4714C14.3465 12.5964 14.177 12.6667 14.0002 12.6667H4.3035ZM3.84216 11.3333H13.3335V3.33333H2.66683V12.2567L3.84216 11.3333ZM5.3335 6.66667H10.6668V8H5.3335V6.66667Z"
fill="#215AE5"
/>
</svg>

内容反馈
</a>
</div>

<div v-show="modalVisible" class="feedback-modal">
<div class="feedback-modal-mask" ref="mask"></div>
<div class="feedback-modal-content">
<!-- header -->
<div>
<h3 style="line-height: 24px; margin: 0; font-size: 16px">
内容反馈
<span
style="float: right; color: #4e5969; cursor: pointer"
@click="hideFeedback"
>
×
</span>
</h3>
<hr style="margin-left: -16px; margin-right: -16px" />
</div>
<!-- content -->
<div v-if="!submitted" style="font-size: 14px">
<div>
<p>问题类型:</p>
<div style="display: flex; justify-content: space-between">
<div class="option" v-for="reason in reasons" :key="reason.value">
<input
type="checkbox"
:id="reason.value"
:value="reason.desc"
v-model="selectedReasons"
class="checkbox"
/>
<label :for="reason.value">{{ reason.desc }}</label>
</div>
</div>
</div>
<div>
<p>问题描述:</p>
<textarea
class="textarea"
placeholder="请输入你遇到的问题"
v-model="customReason"
:class="{ focused: focused }"
@focus="focused = true"
@blur="focused = false"
></textarea>
</div>
<div>
<p>标记内容:</p>
<input
type="text"
disabled
:value="selectedWords"
style="width: 100%; line-height: 20px"
/>
</div>
</div>
<div
v-else
style="
font-size: 14px;
display: flex;
flex-direction: column;
height: 300px;
align-items: center;
justify-content: center;
"
>
<img
src="../assets/images/feedback-success.png"
class="feedback-success-icon"
/>
<div class="tips-box">
<img
src="../assets/images/checkbox-circle-fill.svg"
style="width: 20px; height: 20px; vertical-align: middle"
/>
<span>提交成功,感谢你的反馈</span>
</div>
</div>
<!-- footer -->
<div v-if="!submitted" class="feedback-footer">
<div
class="submit"
@click="hideFeedback"
style="background: #f2f3f5; color: #1d2129"
>
取消
</div>
<div class="submit" @click="submit">提交</div>
</div>
</div>
</div>
</div>
</template>

<script>
import { feishuFeedback } from "@theme/util/feishu";

export default {
data() {
return {
selectWordVisible: false,
selectX: 0,
selectY: 0,
modalVisible: false,
submitted: false,
container: document.querySelector(".theme-default-content"),
focused: false,
selectedWords: "",
selectedReasons: [],
customReason: "",
reasons: [
{
value: "A",
desc: "无有效信息",
},
{
value: "B",
desc: "说明不清晰",
},
{
value: "C",
desc: "内容有误",
},
{
value: "D",
desc: "其他",
},
],
};
},
mounted() {
this.container.addEventListener("mouseup", this.onSelected);
// this.$refs.mask.addEventListener("click", this.hideFeedback);
},
destroyed() {
this.container.removeEventListener("mouseup", this.onSelected);
// this.$refs.mask.removeEventListener("click", this.hideFeedback);
},
methods: {
hideFeedback() {
this.modalVisible = false;
this.selectedWords = "";
},
showFeedback() {
this.selectWordVisible = false;
this.modalVisible = true;
this.selectedReasons = [];
this.customReason = "";
this.submitted = false;
},
submit() {
const params = {
helpful: false,
docTitle: this.$page.title,
docUrl: window.location.href,
customReason: this.xssCheck(this.customReason),
selectedWords: this.selectedWords,
reasonList: this.selectedReasons,
};

feishuFeedback(params).then(() => {
this.submitted = true;
setTimeout(() => {
this.hideFeedback();
}, 1000);
});
},
xssCheck(str, reg) {
const map = {
"<": "&lt;",
"&": "&amp;",
'"': "&quot;",
">": "&gt;",
"'": "&#39;",
};
return str
? str.replace(
reg || /[&<">'](?:(amp|lt|quot|gt|#39|nbsp|#\d+);)?/g,
($0, $1) => {
return $1 ? $0 : map[$0];
}
)
: "";
},
onSelected(e) {
let word = window.getSelection().toString().trim().replace(/\n/g, ""); //选中的内容
if (word != "") {
this.selectedWords = word;
this.selectWordVisible = true;
this.selectX = e.pageX + "px";
this.selectY = e.pageY - 50 + "px";
} else {
this.selectWordVisible = false;
this.selectedWords = "";
}
},
},
};
</script>

<style lang="stylus" scoped>
.select-word
box-sizing border-box
position absolute
width: 96px;
height: 38px;
background: #FFFFFF;
padding: 8px
font-size 14px
display flex
vertical-align: bottom;
/* 分割线/line-medium */
border: 1px solid #E5E6EB;
/* 投影/大投影 */
box-shadow: 0px 16px 32px -10px rgba(4, 24, 115, 0.1);
border-radius: 8px;

.feedback-modal-mask
position fixed
z-index 99
top 0
left 0
right 0
bottom 0
background rgba(0,0,0,0.5)
.feedback-modal-content
position fixed
padding: 16px
z-index 100
box-sizing border-box
width: 640px;
height: 400px;
top 50%;
left 50%;
margin-top: -200px
margin-left: -320px
background: #FFFFFF;
border-radius: 8px;
p
line-height: 20px
label
min-width 80px
display inline-block
input[type="checkbox"]
position relative
margin-right 8px
&:focus
outline none
border none
&::before
position absolute
topp 0
left 0
width 100%
height 100%
content ""
background #FFFFFF
border 1px solid #E5E6EB
border-radius 2px
&:checked::before
position absolute
top 0
left 0
content "\2713"
display flex
align-items center
justify-content center
background-color #fff
width 100%
border 1px solid #EFEFEF
color #fff
font-size 12px
background-color #165DFF
.textarea
max-width 320px
width 320px
height 90px
left 16px
top 61px
padding 5px 12px
box-sizing border-box
background #F2F3F5
border-radius 2px
border none
color #1d2129
resize none
border 1px solid #F2F3F5
font-size 14px
&:focus
outline none
border none
&.focused
background-color #fff
border 1px solid #165DFF

.feedback-footer
display flex
flex-direction row
justify-content: end
margin-top: 16px
.submit
margin-left 16px
width 65px
height 28px
text-align center
line-height 28px
background #215AE5
font-size 14px
color #fff
border-radius 4px
cursor pointer

.feedback-success-icon
margin-bottom 19px
width 120px
height 92px
</style>
Loading