no message

This commit is contained in:
A1300399510
2024-01-12 19:12:30 +08:00
commit 6a7d5f221e
67 changed files with 14829 additions and 0 deletions

397
pages/details/[id].vue Normal file
View File

@@ -0,0 +1,397 @@
<template>
<TopHead></TopHead>
<div class="content flexflex" :style="{ '--main-color': colourValue[uniqidIndex]['main'], '--bg-color': colourValue[uniqidIndex]['bg'], '--bc-color': colourValue[uniqidIndex]['bc'] }">
<div class="header flexacenter">
<span>{{ info.title }}</span>
<span class="views flexcenter">
<img class="eye-icon" src="@/assets/img/eye-icon.svg" />
{{ info.views }}
</span>
</div>
<div class="left">
<div class="info flexacenter">
<div class="info-left flexacenter">
<el-popover placement="bottom-start" :width="140" trigger="click" popper-class="avatar-box-popper" :show-arrow="false">
<template #reference>
<div class="flexcenter">
<img class="avatar" v-if="info.avatar" :src="info.avatar" />
<div class="username">{{ info.nickname }}</div>
</div>
</template>
<div class="avatar-box flexflex" v-if="info['uin']">
<a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(info['uin'])">
<img class="avatar-icon" src="@/assets/img/send-messages-icon.png" />
发送信息
</a>
<a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(info['uin'])">
<img class="avatar-icon" src="@/assets/img/homepage-icon.png" />
TA的主页
</a>
</div>
</el-popover>
<div class="post-time">{{ handleDate(info.releasetime) }}发布</div>
</div>
<div class="info-right flexacenter" v-if="info['status'] == 1">
<div class="cut-off">{{ handleDeadline(info.deadline) }}结束</div>
<div class="state">进行中</div>
</div>
<div class="info-right flexacenter" v-else>
<div class="cut-off" v-if="info.deadline">已于{{ info.deadline }}结束</div>
<div class="state over">已结束</div>
</div>
</div>
<div class="message">{{ info.message }}</div>
<!-- 共有 58 人参与你已投票 -->
<div class="hint">{{ info.status == 1 && isvote == 0 ? `已有 ${info.votes} 人参与,` : `共有 ${info.votes} 人参与` }} {{ `${isvote == 1 ? "你已投票" : info.status == 1 ? "参与投票即可查看实时结果" : ""}` }}</div>
<div class="option-list flexflex" v-if="info['status'] == 1">
<div class="option-item flexflex" v-for="(item, index) in option" :key="item.id">
<div class="serial flexcenter">{{ index + 1 }}</div>
<span class="flex1">{{ item.value }} </span>
</div>
</div>
<div class="option-area" v-else>
<div class="option-item flexflex" :class="{ 'pitch': item.selected }" v-for="(item, index) in option" :key="item.id">
<div class="flexflex" style="padding: 2px 0px;">
<div class="option-number flexcenter">{{ index + 1 }}</div>
<img class="tick-icon" src="@/assets/img/tick-black.svg" />
<div class="option-content flex1">{{ item.value }}</div>
</div>
<div class="option-progress flexacenter">
<div class="option-progress-step" :style="{ width: item.percentage + '%' }"></div>
<div class="option-progress-value">{{ item.count }}</div>
</div>
</div>
</div>
</div>
<div class="right"><DetailsComments :token="token"></DetailsComments></div>
</div>
<DetailsArea></DetailsArea>
</template>
<script setup>
import { useRoute } from "vue-router"
import { ElMessage } from "element-plus"
const route = useRoute()
// console.log(route, "route")
let isNeedLogin = inject("isNeedLogin")
const goLogin = inject("goLogin")
let id = route.params.id
const uniqidEnd = id.charAt(id.length - 1)
const uniqidIndex = base62ToDecimal(uniqidEnd) % 6
onMounted(() => getinit())
let info = ref({})
let qrcode = ref("") // 分享二维码
let iscollection = ref(0) // 是否收藏
let islike = ref(0) // 是否点赞
let ismyself = ref(0) // 是否是作者
let detailsLoading = ref(false) // 详情加载中
let isvote = ref(0) // 是否已经投票
let option = ref([])
let token = ref("")
provide("info", info)
provide("islike", islike)
provide("iscollection", iscollection)
provide("token", token)
provide("qrcode", qrcode)
const getinit = () => {
detailsHttp({ uniqid: id }).then(res => {
console.log(res)
if (res.code != 200) {
ElMessage.error(res.message)
return
}
let data = res.data
info.value = data["info"]
isvote.value = data["isvote"]
iscollection.value = data["iscollection"]
islike.value = data["islike"]
ismyself.value = data["ismyself"]
option.value = data["option"]
qrcode.value = data.share?.qrcode
token.value = data["token"]
console.log(data.share?.qrcode, "data.share?.qrcode")
})
}
// 点击发送信息
const sendMessage = uin => {
redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&showmsg=1&uid=${uin}`)
}
// 点击ta的主页
const TAHomePage = uin => {
redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&uid=${uin}`)
}
// 跳转 url
const redirectToExternalWebsite = url => {
const link = document.createElement("a")
link.href = url
link.target = "_blank"
link.click()
}
provide("sendMessage", sendMessage)
provide("TAHomePage", TAHomePage)
</script>
<style scoped lang="less">
.content {
width: 1200px;
// height: 500px;
margin: 0 auto;
border-radius: 16px;
background: #fff;
flex-wrap: wrap;
--main-color: rgba(44, 186, 230, 1);
--bg-color: rgba(234, 245, 248, 1);
--bc-color: rgba(213, 235, 242, 1);
.header {
width: 100%;
height: 80px;
padding: 0 30px;
border-bottom: 1px solid #ebebeb;
font-weight: 650;
font-size: 20px;
color: #000000;
line-height: 20px;
justify-content: space-between;
.views {
font-size: 12px;
color: #aaa;
font-weight: 400;
.eye-icon {
margin-right: 5px;
}
}
}
.left {
width: 658px;
// height: 500px;
padding: 30px 42px 100px 30px;
border-right: 16px solid #f6f6f6;
.info {
font-size: 13px;
justify-content: space-between;
margin-bottom: 24px;
.info-left {
.avatar {
width: 24px;
height: 24px;
margin-right: 10px;
cursor: pointer;
border-radius: 50%;
}
.username {
color: #333;
margin-right: 10px;
cursor: pointer;
}
.post-time {
line-height: 22px;
color: #aaa;
}
}
.info-right {
.cut-off {
color: #aaa;
}
.state {
height: 20px;
line-height: 20px;
padding: 0 7px;
color: #fff;
background: var(--main-color);
border-radius: 25px;
font-size: 12px;
margin-left: 10px;
&.over {
background: rgba(51, 51, 51, 1);
}
}
}
}
.message {
font-size: 14px;
line-height: 24px;
color: #333;
margin-bottom: 30px;
}
.hint {
font-size: 13px;
line-height: 22px;
color: #aaaaaa;
margin-bottom: 16px;
}
.tick-icon {
width: 14px;
height: 14px;
margin-top: 3px;
margin-right: 6px;
}
.option-list {
flex-direction: column;
.option-item {
width: 570px;
// height: 40px;
// background-color: var(--bg-color);
border: 1px solid var(--bc-color);
border-radius: 10px;
word-break: break-all;
font-size: 14px;
line-height: 20px;
color: #333333;
padding: 9px 15px;
cursor: pointer;
position: relative;
overflow: hidden;
z-index: 1;
&::after {
background-color: var(--bg-color);
content: "";
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: -1;
// border: 1px solid var(--bc-color);
}
&:hover::after {
background-color: var(--main-color);
opacity: 0.156862745098039;
}
&:not(:last-of-type) {
margin-bottom: 10px;
}
&.pitch {
.option-number {
display: none;
}
.tick-icon {
display: block;
}
.option-content {
color: #000000;
font-weight: 650;
}
}
.serial {
width: 14px;
height: 14px;
border-radius: 50%;
background: var(--main-color);
font-size: 11px;
color: #ffffff;
margin-top: 3px;
margin-right: 6px;
}
}
}
.option-area {
width: 570px;
// height: 318px;
background-color: var(--bg-color);
border: 1px solid var(--bc-color);
border-radius: 10px;
padding: 8px 0;
.option-item {
padding: 7px 15px 10px;
flex-direction: column;
word-break: break-all;
&:not(:last-of-type) {
border-bottom: 1px solid var(--bc-color);
}
&.pitch {
.option-number {
display: none;
}
.tick-icon {
display: block;
}
.option-content {
font-weight: 650;
color: #000000;
}
}
.option-number {
font-size: 11px;
color: #ffffff;
width: 14px;
height: 14px;
background-color: var(--main-color);
border-radius: 50%;
margin-right: 6px;
margin-top: 3px;
}
.tick-icon {
display: none;
}
.option-content {
font-size: 14px;
color: #333;
line-height: 20px;
word-break: break-word;
}
.option-progress {
height: 5px;
width: 100%;
justify-content: flex-end;
// display: none;
margin-top: 3px;
.option-progress-step {
width: 24%;
background-color: var(--main-color);
opacity: 0.49803922;
height: 4px;
border-radius: 66px;
margin-right: 14px;
}
.option-progress-value {
font-size: 12px;
color: var(--main-color);
line-height: 20px;
}
}
}
}
}
.right {
flex: 1;
padding-top: 22px;
padding-left: 42px;
}
}
</style>

326
pages/index.html/index.vue Normal file
View File

@@ -0,0 +1,326 @@
<template>
<TopHead></TopHead>
<div class="search-info flexacenter" v-if="keyword">
<div class="flexacenter" @click="closeKeyword">
{{ keyword }}
<img class="round-fork-fork" src="@/assets/img/round-fork-fork.png" />
</div>
<div class="halving-line"></div>
<div class="search-result"> {{ count }} 条搜索数据</div>
</div>
<div class="vote-list-box" ref="gridContainer">
<a class="vote-item" target="_blank" :href="`/details/${item['uniqid']}`" v-for="(item, index) in list" :key="index" :class="{ 'isvote': item['isvote'] == 1 || item['status'] == 0 }" :style="{ '--main-color': colourValue[item.uniqidIndex]['main'], '--bg-color': colourValue[item.uniqidIndex]['bg'], '--bc-color': colourValue[item.uniqidIndex]['bc'] }">
<div class="vote-title">
<div class="vote-state" v-if="item['status'] == 1">进行中</div>
<div class="vote-state finish" v-else>已结束</div>
{{ item["title"] }}
</div>
<div class="vote-explain">{{ item["message"] }}</div>
<div class="vote-option-list flexflex">
<div class="vote-option-item flexflex" :class="{ 'pitch': index == 1 }" v-for="(item, index) in item?.option" :key="index">
<div class="flexflex" style="padding: 2px 0;">
<div class="vote-option-number flexcenter">{{ index + 1 }}</div>
<img class="tick-icon" src="@/assets/img/tick-black.svg" />
<div class="vote-option-content flex1">{{ item["value"] }}</div>
</div>
<div class="vote-option-progress flexacenter">
<div class="vote-option-progress-step" :style="{ width: item['percentage'] + '%' }"></div>
<div class="vote-option-progress-value">{{ item["count"] }}</div>
</div>
</div>
</div>
<div class="vote-data flexacenter">
<div class="vote-data-left flexacenter">
18人参与 <template v-if="item['deadline']">| {{ handleDeadline(item["deadline"]) }}结束</template>
</div>
<div class="vote-data-right flexacenter">
<div class="vote-data-item flexacenter"><img class="vote-data-icon" src="@/assets/img/eye-icon.svg" />&nbsp; {{ 96 }}</div>
<div class="vote-data-item flexacenter" @click="handleLike(item['token'])">
<img v-if="item['islike'] == 0" class="vote-data-icon" src="@/assets/img/like-no.svg" />
<img v-else class="vote-data-icon" src="@/assets/img/like-yes.png" />&nbsp; {{ item["likes"] }}
</div>
<div class="vote-data-item flexacenter"><img class="vote-data-icon" src="@/assets/img/comment-icon.svg" />&nbsp; {{ item["comments"] }}</div>
</div>
</div>
</a>
</div>
</template>
<script setup>
import { useRoute } from "vue-router"
const route = useRoute()
const router = useRouter()
let keyword = ref("")
let page = 1 // 投票页数从 1 开始
let count = ref(0)
let list = ref([])
let loading = false // 加载中
keyword.value = route.query["keyword"]
const gridContainer = ref(null)
let masonryInstance = null
onMounted(async () => {
let Masonry = await import("masonry-layout")
masonryInstance = new Masonry.default(gridContainer.value, {
itemSelector: ".vote-item",
gutter: 22.5,
})
getList()
window.addEventListener("scroll", handleScroll)
})
const getList = () => {
if (page == 0 || loading) return
loading = true
getListHttp({ page, keyword: keyword.value })
.then(res => {
if (res.code != 200) {
page = 0
ElMessage.error(res.message)
return
}
let data = res.data
data.data.forEach(element => {
let uniqidEnd = element["uniqid"].charAt(element["uniqid"].length - 1)
element["uniqidIndex"] = base62ToDecimal(uniqidEnd) % 6
})
list.value = list.value.concat(data.data)
count.value = data.count
if (data.count > list.value.length) page++
else page = 0
nextTick(() => {
masonryInstance.reloadItems()
masonryInstance.layout()
})
})
.finally(() => (loading = false))
}
const handleScroll = () => {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
const scrollHeight = document.documentElement.scrollHeight
const clientHeight = document.documentElement.clientHeight
// 列表下 滑动到底部 获取新数据
if (scrollTop + clientHeight >= scrollHeight - 40) getList()
}
// 处理点赞
const handleLike = token => {
console.log("handleLike", token)
}
// 点击关闭搜索
const closeKeyword = () => {
// keyword.value = ""
router.push("./index.html")
}
watch(
() => route.query,
() => {
keyword.value = route.query["keyword"]
page = 1
list.value = []
count.value = 0
getList()
}
)
</script>
<style lang="less" scoped>
.vote-item {
--main-color: rgba(44, 186, 230, 1);
--bg-color: rgba(234, 245, 248, 1);
--bc-color: rgba(213, 235, 242, 1);
}
.search-info {
font-size: 14px;
color: #72db86;
width: 1200px;
margin: 0 auto 31px;
.round-fork-fork {
width: 14px;
height: 14px;
margin-left: 8px;
cursor: pointer;
}
.halving-line {
width: 1px;
height: 13px;
background-color: #d7d7d7;
margin: 0 20px;
}
.search-result {
font-size: 13px;
color: #7f7f7f;
}
}
.vote-list-box {
width: 1200px;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
.vote-item {
width: 385px;
background-color: rgba(255, 255, 255, 1);
border-radius: 16px;
padding: 25px 22px 24px;
margin-bottom: 20px;
cursor: pointer;
&.isvote {
.vote-option-list {
.vote-option-item {
.vote-option-progress {
display: flex;
}
}
}
}
.vote-title {
.vote-state {
background-color: var(--main-color);
border-radius: 25px;
font-size: 12px;
margin-right: 6px;
height: 20px;
color: #ffffff;
padding: 0 6px;
display: inline-flex;
justify-content: center;
align-items: center;
&.finish {
color: #ffffff;
background: #000;
}
}
font-weight: 650;
font-style: normal;
font-size: 16px;
color: #000000;
line-height: 26px;
margin-bottom: 10px;
word-break: break-all;
}
.vote-explain {
color: #555555;
line-height: 22px;
font-size: 13px;
word-break: break-word;
margin-bottom: 14px;
}
.vote-option-list {
width: 340px;
background-color: var(--bg-color);
border: 1px solid var(--bc-color);
border-radius: 13px;
flex-direction: column;
padding: 8px 0;
margin-bottom: 16px;
.vote-option-item {
padding: 10px 15px;
flex-direction: column;
&:not(:last-of-type) {
border-bottom: 1px solid var(--bc-color);
}
&.pitch {
.vote-option-number {
display: none;
}
.tick-icon {
display: block;
}
.vote-option-content {
color: #000;
font-weight: 650;
}
}
.vote-option-number {
font-size: 11px;
color: #ffffff;
width: 14px;
height: 14px;
background-color: var(--main-color);
border-radius: 50%;
margin-right: 6px;
margin-top: 3px;
}
.tick-icon {
width: 14px;
height: 14px;
margin-top: 3px;
margin-right: 6px;
display: none;
}
.vote-option-content {
font-size: 14px;
color: #333;
line-height: 20px;
}
.vote-option-progress {
height: 5px;
width: 100%;
justify-content: flex-end;
display: none;
margin-top: 5px;
.vote-option-progress-step {
// background-color: rgba(49, 215, 46, 0.498039215686275);
background-color: var(--main-color);
opacity: 0.49039;
// width: 150px;
height: 4px;
border-radius: 66px;
margin-right: 14px;
}
.vote-option-progress-value {
font-size: 12px;
color: var(--main-color);
line-height: 20px;
}
}
}
}
.vote-data {
justify-content: space-between;
font-size: 12px;
color: #aaaaaa;
line-height: 22px;
.vote-data-item {
margin-left: 16px;
.vote-data-icon {
width: 13px;
cursor: pointer;
}
}
}
}
}
</style>

5
pages/index.vue Normal file
View File

@@ -0,0 +1,5 @@
<template></template>
<script setup>
const router = useRouter()
router.replace("/index.html")
</script>

650
pages/publish/index.vue Normal file
View File

@@ -0,0 +1,650 @@
<template>
<Head>
<Title>寄托天下 - 面经发布</Title>
<Meta name="keyword" content="留学资讯,留学交流论坛,留学面经,面试经验,寄托天下" />
</Head>
<div class="content-box">
<div class="flexacenter save-box save-left" @click="submit(0)">
<img class="save-icon" src="@/assets/img/arrow-gray.png" />
保存并退出
</div>
<div class="flexacenter save-box save-right" @click="abandonSaving">
放弃保存
<img class="save-icon" src="@/assets/img/cross-icon.png" />
</div>
<div class="contentcontent flex1">
<div class="header flexacenter">发起投票</div>
<div class="box flex1 flexflex">
<div class="box-left">
<div class="item">
<div class="titletitle flexacenter">
标题
<div class="asterisk">*</div>
</div>
<el-input class="item-input headline-textarea" type="textarea" placeholder="请输入" maxlength="24" show-word-limit v-model="info.title" autosize></el-input>
</div>
<div class="item">
<div class="titletitle flexacenter">详细说明</div>
<el-input class="item-input explain-textarea" type="textarea" placeholder="请输入" maxlength="1000" show-word-limit v-model="info.message" autosize></el-input>
</div>
<div class="item">
<div class="titletitle flexacenter">
截止投票日期
<div class="asterisk">*</div>
</div>
<div class="time-box item-input-box flexacenter">
<el-config-provider :locale="zhCn">
<el-date-picker v-model="info.deadline" type="date" placeholder="请选择" size="large" class="flex1 flexacenter" :clear-icon="{}" value-format="YYYY-MM-DD" :disabled-date="setDisabled" />
</el-config-provider>
<img class="calendar-icon" src="@/assets/img/calendar-icon.svg" />
</div>
</div>
</div>
<div class="box-right flex1">
<div class="item">
<div class="titletitle flexacenter">
选项
<div class="asterisk">*</div>
</div>
<div class="option-list flexflex">
<div class="" ref="draggableContainer">
<template v-if="optionList.length == 0">
<div class="option-item flexacenter" v-for="(item, index) in 2" :key="index">
<div class="option-content flexacenter">
<div class="option-text flexcenter">{{ index + 1 }}</div>
<input class="option-input flex1" placeholder="请输入" />
</div>
<div class="option-drag flexcenter">
<img class="option-icon" src="@/assets/img/option-icon.svg" />
</div>
</div>
</template>
<template v-else>
<div class="option-item flexacenter" v-for="(item, index) in optionList" :key="item.id">
<div class="option-content flexacenter">
<div class="option-text flexcenter">{{ index + 1 }}</div>
<input class="option-input flex1" placeholder="请输入" v-model="optionList[index]['message']" />
<img class="option-cross" v-if="optionList[index]['message']" @click="clearMessage(index)" src="@/assets/img/cross-undertint-icon.svg" />
</div>
<div class="option-drag flexcenter">
<img class="option-icon" src="@/assets/img/option-icon.svg" />
</div>
<img class="rubbish-icon" v-if="optionList.length > 2" @click="deleteOption(index)" src="@/assets/img/rubbish-icon.svg" />
</div>
</template>
</div>
<div class="option-item option-circusee flexacenter" :class="{ 'hascontent': optionList.length > 2 }">
<div class="option-content flexacenter">
<div class="option-text flexcenter">{{ optionList.length + 1 }}</div>
<input class="option-input flex1" disabled value="不懂,围观学习" />
</div>
</div>
</div>
<div class="flexcenter" style="padding-right: 26px;">
<div class="add-box flexcenter" @click="addOption()">
<img class="add-icon" src="@/assets/img/add-green-icon.svg" />
添加选项
</div>
</div>
</div>
</div>
</div>
<div class="hint-box flexcenter">请确保以上内容已正确填写发布后将不能修改</div>
</div>
</div>
<div class="floor-box">
<div class="box flexacenter">
<div class="anonymous-box flexacenter" @click="cutAnonymous()">
<img class="anonymous-icon" v-if="info.anonymous == 0" src="@/assets/img/frame-no.svg" />
<img class="anonymous-icon" v-else src="@/assets/img/frame-pitch.svg" />
匿名发表
<div class="text">发布后可修改</div>
</div>
<div class="issue-btn flexcenter" @click="submit()">发布</div>
</div>
</div>
</template>
<script setup>
import { useRouter } from "vue-router"
import { ElMessage } from "element-plus"
import zhCn from "element-plus/dist/locale/zh-cn.mjs"
import Sortable from "sortablejs"
const router = useRouter()
const goLogin = inject("goLogin")
const setDisabled = time => {
return time.getTime() < Date.now() // 可选历史天、可选当前天、不可选未来天
}
onMounted(() => {})
onBeforeMount(() => {
clearBottom()
// clearTop()
})
// 清除底部的次数
let clearBottomCount = 0
// 清除 底部
const clearBottom = () => {
const indexFooter = document.querySelector("section.index-footer")
if (!indexFooter) {
clearBottomCount++
setTimeout(() => clearBottom(), 50)
return
}
if (clearBottomCount == 15) return
indexFooter.style.display = "none"
}
// 清除顶部的次数
let clearTopCount = 0
// 清除 顶部
const clearTop = () => {
const indexHeader = document.querySelector("header.page-header")
if (!indexHeader) {
clearTopCount++
setTimeout(() => clearTop(), 50)
return
}
if (clearTopCount == 5) return
indexHeader.style.display = "none"
}
let info = ref({})
let token = ""
// 切换匿名状态
const cutAnonymous = () => {
info.value["anonymous"] = info.value["anonymous"] == 0 ? 1 : 0
}
let loading = false // 加载中
// 提交发布
const submit = (status = 1) => {
// status = 0
if (loading) return
loading = true
let option = []
optionList.value.forEach(element => {
if (element["message"].trim() !== "") option.push(element["message"])
})
if (status == 1) {
if (option.length < 2) {
ElMessage.error("请设置至少2个选项~")
return
}
option.push("不懂,围观学习")
}
info.value["option"] = option
// return
publishSubmitHttp({ info: info.value, token, status })
.then(res => {
if (res.code != 200) {
ElMessage.error(res.message)
return
}
const data = res.data
ElMessage.success(res.message)
// router.push(`/details/${data["uniqid"]}`)
if (status == 0) goToURL(`/index.html`, false)
else goToURL(`/details/${data["uniqid"]}`, false)
})
.finally(() => (loading = false))
}
// 放弃保存 跳跃上一页或者首页
const abandonSaving = () => {
if (router.currentRoute.value.meta.previousPage) router.go(-1)
else goToURL("./index.html", false) // 跳转到首页
// else router.push("./index.html") // 跳转到首页
}
let draggableContainer = ref(null)
const sortable = ref(null)
onMounted(() => {
getinit()
initDraggable()
})
const getinit = () => {
publishInitHttp().then(res => {
if (res.code != 200) {
ElMessage.error(res.message)
if (res.code == 401) goLogin()
return
}
const data = res.data
// data.info.option = []
const option = data.info?.option || []
if (option.length == 0) {
for (let index = 0; index < 2; index++) {
optionList.value.push({ id: index, message: "" })
}
} else {
option.forEach((message, index) => {
optionList.value.push({ id: index, message })
})
}
let deadline = data["info"]["deadline"] || 0
if (deadline) data["info"]["deadline"] = handleDate(deadline)
info.value = data.info
token = data.token
})
}
// 处理初始化 面试时间的 时间戳格式
const handleDate = timestamp => {
// 使用Date对象将时间戳转换为日期对象
var date = new Date(timestamp * 1000)
// 获取年份、月份和日期
var year = date.getFullYear()
var month = ("0" + (date.getMonth() + 1)).slice(-2) // 月份从0开始需要加1并补0
var day = ("0" + date.getDate()).slice(-2) // 获取日期并补0
// 拼接为yyyy-mm-dd格式的日期字符串
var formattedDate = year + "-" + month + "-" + day
return formattedDate
}
// 初始化拖拽
const initDraggable = () => {
if (!draggableContainer.value) {
console.warn("容器不能为空")
return
}
sortable.value = Sortable.create(draggableContainer.value, {
handle: ".option-drag",
draggable: ".option-item", // 允许拖拽的项目类名
direction: "horizontal",
forceFallback: true,
animation: 300,
onUpdate(e) {
if (e.oldIndex !== undefined && e.newIndex !== undefined) {
// 删除拖拽的元素
const list = [...optionList.value]
const item = list.splice(e.oldIndex, 1)[0]
// 把删除的元素放到新的位置
list.splice(e.newIndex, 0, item)
optionList.value = list
}
},
})
}
let optionList = ref([]) // 特殊的 选项 列表
// 点击添加选项
const addOption = () => {
optionList.value.push({
id: optionList.value.length,
message: "",
})
}
// 点击删除选项
const deleteOption = index => {
optionList.value.splice(index, 1)
optionList.value.forEach((element, index) => {
element["id"] = index
})
}
// 点进清除选项
const clearMessage = index => {
optionList.value[index]["message"] = ""
}
</script>
<style scoped lang="less">
.content-box {
display: flex;
justify-content: center;
padding: 0 122px;
}
@media (max-width: 920px) {
.content-box {
display: block;
padding: 0 10px;
// padding: 0 122px;
}
}
.contentcontent {
// width: 1200px;
max-width: 1200px;
min-width: 900px;
min-height: calc(100vh - 120px);
background: #fff;
margin: 30px auto 90px;
border-radius: 16px;
display: flex;
flex-direction: column;
position: relative;
.header {
font-weight: 650;
font-size: 20px;
color: #000000;
border-bottom: 1px solid #ebebeb;
height: 88px;
padding-left: 30px;
}
.box {
.titletitle {
color: #666666;
font-size: 14px;
margin-bottom: 10px;
}
.box-left {
border-right: 16px solid #f6f6f6;
width: 48.176%;
// .area-box {
padding: 30px;
padding-right: 50px;
border-bottom: 1px solid #ebebeb;
.item {
&:not(:last-of-type) {
margin-bottom: 30px;
}
.item-input {
border-radius: 5px;
outline: none;
// width: 482px;
width: 100%;
// padding: 13px 14px;
font-size: 14px;
/deep/ .el-textarea__inner {
padding: 13px 14px;
border-radius: 5px;
box-shadow: none;
border: 1px solid rgba(215, 215, 215, 1);
}
}
.headline-textarea {
/deep/ .el-textarea__inner {
min-height: 70px !important;
}
}
.explain-textarea {
/deep/ .el-textarea__inner {
min-height: 300px !important;
}
}
}
.item-input-box {
// width: 482px;S
height: 46px;
border: 1px solid rgba(215, 215, 215, 1);
border-radius: 5px;
cursor: pointer;
/deep/ .el-input {
height: 100%;
.el-input__wrapper {
height: 100%;
box-shadow: none;
}
}
}
.time-box {
.calendar-icon {
width: 15px;
height: 16px;
margin: 0 12px;
cursor: auto;
}
/deep/ .el-input {
.el-input__prefix {
display: none;
}
}
}
// }
.visible-box {
margin: 30px;
font-size: 14px;
color: #555555;
cursor: pointer;
user-select: none;
.visible-icon {
width: 18px;
height: 18px;
margin-right: 5px;
}
}
}
.box-right {
padding-top: 30px;
padding-left: 56px;
padding-right: 30px;
.option-list {
flex-direction: column;
margin-bottom: 53px;
.option-item {
// transition: all linear 0.3s;
&:not(:first-of-type) {
margin-top: 20px;
}
&.option-circusee {
// margin-bottom: 53px;
transition: all 0.3s;
padding-right: 33px;
&.hascontent {
padding-right: 66px;
}
.option-content {
background: rgba(246, 246, 246, 1);
.option-input {
background: transparent;
}
}
}
.option-content {
// width: 470px;
// width: 87.69%;
flex: 1;
height: 46px;
border: 1px solid rgba(215, 215, 215, 1);
border-radius: 5px;
.option-text {
width: 14px;
height: 14px;
color: #333;
font-size: 11px;
position: relative;
margin: 0 10px;
border-radius: 50%;
border: 1px solid #797979;
}
.option-input {
height: 100%;
border: none;
outline: none;
border-radius: 5px;
color: #333;
}
.option-cross {
width: 12px;
height: 12px;
cursor: pointer;
margin: 0 10px;
}
}
.option-drag {
padding-left: 15px;
.option-icon {
width: 18px;
height: 16px;
}
// cursor: move;
}
.rubbish-icon {
width: 13px;
height: 14px;
margin-left: 20px;
cursor: pointer;
}
}
}
.add-box {
.add-icon {
width: 14px;
height: 14px;
margin-right: 6px;
}
font-size: 14px;
color: #333;
cursor: pointer;
// max-width: max-content;
}
}
}
.hint-box {
height: 58px;
background-color: rgba(246, 246, 246, 1);
color: #555555;
font-size: 13px;
}
}
.asterisk {
color: #fa9183;
margin-left: 5px;
}
.floor-box {
width: 100vw;
min-width: 1200px;
height: 90px;
background-color: rgba(255, 255, 255, 1);
-moz-box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.192156862745098);
-webkit-box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.192156862745098);
box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.192156862745098);
position: fixed;
bottom: 0;
.box {
width: 1200px;
height: 100%;
margin: 0 auto;
justify-content: space-between;
padding: 0 30px;
.anonymous-box {
cursor: pointer;
color: #333333;
font-size: 14px;
user-select: none;
.text {
color: rgb(170, 170, 170);
font-size: 13px;
}
.anonymous-icon {
width: 18px;
height: 18px;
}
}
.issue-btn {
width: 200px;
height: 46px;
background-color: rgba(114, 219, 134, 1);
border-radius: 190px;
font-size: 16px;
color: #fff;
cursor: pointer;
}
}
}
// @media (max-width: 1300px) {
// .save-box.save-left {
// left: 0 !important;
// }
// .save-box.save-right {
// right: 0 !important;
// }
// }
.save-box {
font-size: 14px;
color: #666666;
position: absolute;
// position: fixed;
top: 30px;
cursor: pointer;
transition: all 0.3s;
z-index: 1;
&.save-left {
left: 0px;
// left: calc((1200px - 100vw) / 2 + 25px);
}
&.save-right {
right: 0px;
// right: calc((1200px - 100vw) / 2 + 25px);
.save-icon {
width: 16px;
height: 16px;
margin-left: 10px;
}
}
.save-icon {
width: 22px;
height: 22px;
margin-right: 10px;
transform: rotate(180deg);
}
}
</style>
<style scoped>
/* .list-transition-enter-active,
.list-transition-leave-active {
transition: all 0.3s;
}
.list-transition-enter,
.list-transition-leave-to {
opacity: 0;
transform: translateY(20px);
} */
</style>