You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
customAgent/src/components/appraise-popup.vue

452 lines
13 KiB

<template>
<div class="appraise-popup-content">
<div class="wrapper-content" :class="elder ? 'elder-wrapper' : ''">
<van-icon
v-if="elder"
class="close-btn"
name="cross"
size="22"
color="#D0D2DB"
@click.stop="handleClose"
/>
<a v-else class="appraise-close-btn" href="javascript:;" @click.stop="handleClose">关闭</a>
<div v-if="elder" class="appraise-header-main-title">意见反馈</div>
<div class="appraise-header-title">您的反馈对我们完善服务十分重要</div>
<div class="appraise-main">
<div class="appraise-item-box flex flex-1">
<a
v-for="(item, index) in checkBoxList"
:key="index"
href="javascript:;"
class="cells-check-label"
@change.stop="changeCheck(item)"
>
<input
:id="'s' + index"
v-model="item.checked"
type="radio"
class="check-radio"
name="radio1"
/>
<label class="cell-ft text-checked" :for="'s' + index">
<span class="icon-checked-txt">{{ item.content }}</span>
</label>
</a>
</div>
<div class="appraise-item-other">
<textarea
v-model="appraiseOther"
rows="2"
cols="2"
placeholder="请输入您的建议"
maxlength="100"
></textarea>
</div>
<div class="appraise-submit">
<van-button
class="appraise-submit-btn"
:loading="isResubmit"
:disabled="isResubmit"
type="info"
:loading-text="isResubmit ? '提交中...' : ''"
@click.stop="submitForm('submit')"
>立即提交</van-button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, getCurrentInstance } from 'vue'
import { useAppStore } from '@/store/app.js'
import { showToast, showLoadingToast, closeToast, Button, Icon } from 'vant'
import { isJSON } from '@/utils'
const props = defineProps({
baseHandle: {
type: Object,
required: true
}
})
const emit = defineEmits(['handleAppraiseClose'])
const store = useAppStore()
// Vue 2 中通过 this.$post 访问的全局属性,
// 在 Vue 3 的 <script setup> 中通过 appContext.config.globalProperties 读取
const { appContext } = getCurrentInstance()
const globalProps = appContext.config.globalProperties
const $post = globalProps.$post
// 关爱版标识(原 globalProps.$elder,改为响应式的 store.elder)
const elder = computed(() => !!store.elder)
// —— 响应式状态 ——
const checkedItem = ref('')
const appraiseOther = ref('')
const isResubmit = ref(false)
const baseItem = ref(props.baseHandle)
const appraiseDisBtn = ref(props.baseHandle.event)
const checkBoxList = ref([])
// —— Pinia state ——(按需映射)
const userId = computed(() => store.userId)
const sessionId = computed(() => store.sessionId)
const source = computed(() => store.source)
const mescrollContent = computed(() => store.mescrollContent)
// —— 方法 ——
const changeCheck = (item) => {
// 选中的值
checkedItem.value = item
}
const scrollTopBody = () => {
setTimeout(() => {
try {
const el = mescrollContent.value
if (!el || typeof el !== 'object') return
el.scrollTop = el.scrollHeight || 0
} catch (err) {
console.log(err.message)
}
}, 300)
}
const handleClose = () => {
submitForm()
emit('handleAppraiseClose', false)
appraiseBtnDisabled()
// 重置
if (checkBoxList.value.length > 0) {
checkedItem.value = ''
checkBoxList.value.forEach((item) => { item.checked = false })
}
}
const appraiseBtnDisabled = () => {
const current = appraiseDisBtn.value
if (!current) return
const settled = current.parentNode.children[1] // 有帮助
const unsettled = current.parentNode.children[0] // 没有帮助
try {
current.disabled = true
current.classList.add('active')
if (current.innerText === '有帮助') {
unsettled.disabled = true
} else if (current.innerText === '没有帮助') {
settled.disabled = true
}
} catch (err) {
console.log(err.message)
}
}
const verifyForm = () => {
if (!checkedItem.value && !appraiseOther.value) {
showToast('请对我们的服务进行评价,您的反馈对我们完善服务十分重要')
return false
}
return true
}
const getReasonList = () => {
showLoadingToast({
message: '加载中...',
duration: 0,
forbidClick: true
})
$post('config/reason', {})
.then((res) => {
closeToast()
console.log('获取原因列表==', res)
if (res.code && res.code !== 0) {
showToast(res.msg)
return
}
if (res.data && isJSON(res.data)) {
const dataList = JSON.parse(res.data)
checkBoxList.value = []
if (dataList && dataList.length > 0) {
dataList.forEach((item, index) => {
item.id = index
item.checked = false
checkBoxList.value.push(item)
})
}
}
})
.catch((err) => {
closeToast()
console.log(err)
})
}
const submitForm = (type) => {
isResubmit.value = true
const param = {
fromFlag: 1,
userId: userId.value,
sessionId: sessionId.value,
source: source.value,
qaId: baseItem.value.qaId,
evaluation: baseItem.value.evaluation,
reason: checkedItem.value?.content || '',
reasonDesc: appraiseOther.value || '',
reqAndResType: '3',
timestamp: new Date().valueOf()
}
// 校验
if (type === 'submit') {
if (!verifyForm()) {
isResubmit.value = false
return
}
} else {
param.reason = ''
param.reasonDesc = ''
showLoadingToast({
message: '加载中...',
duration: 0,
forbidClick: true
})
}
console.log('评价入参', param)
// 满意度调查系统需求
store.dispatch('savePaperResult', param).then(() => {}).catch((err) => { console.log(err) })
$post('evaluation/evaluateAnswer', param)
.then((res) => {
closeToast()
isResubmit.value = false
if (res.code && res.code !== 0) {
showToast(res.msg)
appraiseDisBtn.value.disabled = false
return
}
appraiseBtnDisabled()
emit('handleAppraiseClose', false) // 关闭弹层
store.commit('set_chatList', res.data)
scrollTopBody()
})
.catch((err) => {
closeToast()
isResubmit.value = false
appraiseDisBtn.value.disabled = false
console.log(err)
})
}
// 进入组件即拉取原因列表(等价于原 created 钩子)
getReasonList()
</script>
<style scoped>
.appraise-popup-content {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
padding: 0 20.5rem;
}
.wrapper-content {
width: 100%;
background-color: #fff;
border-radius: 12rem;
position: relative;
padding: 14rem 0 24rem 0;
}
.wrapper-content .appraise-close-btn {
display: block;
position: absolute;
right: 10rem;
top: 14rem;
text-indent: -9999rem;
width: 16rem;
height: 16rem;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAgCAYAAAB3j6rJAAAAAXNSR0IArs4c6QAABXlJREFUWAmtl31InVUcx7texbBaYVt5jTIoZro5Ih3RG5HaqD9K+yOHa/1RgZl653WZKURIBCuCdctp6h+1YFskg5K0P4YvxXKNQqIXeqEVvZDTstHE99c+39tznp57fe71mXjgcM75vXx/3+d3fs95zuO76AJaRUVFit/vv3tpaanE5/NtX1lZyWTMFATzEeYjjN9g043Nx52dnQte4X1eDKurq69cXFx8jiCPYX85fYqgwya4MJhHSDHms7yEfh6bt5KTk19sbW39WzaJWkIiXV1d/r6+vmcAbCKAwI8lJSV1ZWRk9DU3N8+6ASO/eHR0tHh5ebkM/R58p/A9UFxc/EpZWdmSm49kcYmEQqErpqen38VmF2DdpLupra3tu3hAbvKqqqoctugARErQn0hLS9sdDof/cbN1JcJWZC0sLJzA4Xoy8FR7e/ubbs5eZZWVlY+ToTew/yUlJWUXW/VrrO8qIjzFpdTDKQyvpT9AwX0S67SeNYV+J34f0H+nbm4nu5NOnCTnghT6SOURZLlsR9lGkVAMYQlT2IqhWJKb5jcTjWNjY49i0ITD/o6OjmNO3UbMh4eHfy4oKDhPjFBvb+8Z1l8ZXJtVMBhMnZub+wES49TETsYVY8Qe68wI0Rt5snEjTzSyFQEwwvSXwPvC2ILhA+9zxs2pqanZLS0tc9LZWwOJJ1ln4djgJCEjCi0LxyeY9hNgs2SJGnWWAcYgPg/ju8VpK2zFQJZlxYyobSIoH6F/BvsBp6PmZKGXt2c/0x30hGRqa2uvpthFYqveOHz19kU1xVAsxTSKCJGamppMHHfS3zOK2BHnV3EMIY9LhpRfNTs7qwfJtl77jlgcs1YsxVRsySJEODPuZ+7jteo2hm4jBfwaZPahW0VGJNiGAcBz1iIhbCuWz4pt18gN6OY5aL6XUaIGmRYCBbGxyVDoWyDQjyzXCwnhW7HmmSq2TSTA/CxPa78pUsZrbNMhbKvR59H7Kbp+iGzzSkK4VqyzTBU7esioBF4bmWkDrAl7ZSYPEo0QjFsTcXAVM0O6SI3wNJOA6uvquek1xm8PDsriCvWxV1vkGQBDxQRjSj4RIgh0oYlUrxcg6yxRTeThW6UtYb59fn5+QEXrBUM2iqnYmpuMaJFeX1+/ZlYcJHYAUsMWsSPtHSID8Db6oM4SgSdq+riiT8f+fyKAnJbTxMTEvYmcnSTwCapOjL2DTM7MzMygTlejcxs59IolN7EjGSksLDyJ7By9VEq35iSBvpbAh2LtDBnkN+l0XYOMYp2zYv+3NbrCkeYeFCUE1J00qtXV1aUjUE3oDanj2H49ysCxcJDJ5nP/kVvN6PaHiy7gPeb6GMmIhXMQxSa6XsmoRqofRKCaeBoS4Sily8KQYf+30u+LNQGvUbGQHzQ6mwj7/SVOR1Hs01XRGGjk1TzKkZyLje3o1LvNRQafrEAgoIuW3YRNnFrFUkyjsO8jErAt18H0a4zOsLyLp582hhsxgp8Gzkli3EiMPPB/M7h2RiSwFOUY3szyML8GUXrjtJ7RwjpsYZc7SQjPHwvK9e1HrnPKRGhycjK/qKioZ2hoSB+ndbeGhobLxsfHjwPwEEQa2JK3Y8FWEZEBZE7l5+f/iVOQ+0Up89PI9IG64MZ23MJH8UMcb6XXkAnXNy6qRmKjAHIPMv1k6Xr4Dv15gH5iXLPhq8/7C/Ryuu65u/EdZHRtCYnIgw/ZJi4vz/LmhFimkaVhxvcptiF+lv5gjBzRyDOxu4bxDvSlyPUPPM3JGcbuZS7JE6zjtjWJGE+eMMB8L4H0+3gbgVwLGf0y+k/R67Z3hCx42lLPRAC1mz73HOG5ZEl33chXGwIjPP0IZ8e3PP1ftrHHyb/+R6X+8I7cugAAAABJRU5ErkJggg==")
no-repeat center;
background-size: 100% 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.wrapper-content .appraise-close-btn:active {
opacity: 0.65;
}
.wrapper-content .appraise-header-title {
font-family: NotoSansHans-Bold;
font-size: 15rem;
line-height: 23rem;
color: #333333;
padding: 0 20rem;
}
.appraise-item-box {
align-items: flex-end;
flex-wrap: wrap;
margin: 16rem 0 9rem 0;
padding: 0 10rem 0 15rem;
}
.appraise-item-box .cells-check-label {
position: relative;
height: 28rem;
line-height: 28rem;
margin-left: 4rem;
margin-right: 4rem;
margin-bottom: 10rem;
display: inherit;
}
.appraise-item-box .cells-check-label .cell-ft {
border: 1rem solid #5a9cff;
border-radius: 4rem;
font-family: NotoSansHans-Medium;
font-size: 15rem;
line-height: 15rem;
color: #5a9cff;
text-align: center;
padding: 6rem 2rem;
display: inline-block;
}
.appraise-item-box .cells-check-label .cell-ft .icon-checked-txt {
pointer-events: none;
}
.appraise-item-box .cells-check-label .check-radio {
display: none;
}
.appraise-item-box .cells-check-label .check-radio:checked + .text-checked {
color: #fff;
background-color: #5a9cff;
}
.appraise-item-other {
padding: 0 20rem;
}
.appraise-item-other textarea {
display: block;
width: 100%;
min-height: 60rem;
max-height: 150rem;
background: #f7f7f7;
border-radius: 4rem;
font-family: NotoSansHans-Regular;
font-size: 14rem;
line-height: 21rem;
border: 0;
padding: 7.5rem 8.2rem;
box-sizing: border-box;
}
.appraise-item-other textarea::placeholder,
.appraise-item-other textarea::-moz-placeholder,
.appraise-item-other textarea::-ms-input-placeholder {
font-family: NotoSansHans-Regular;
font-size: 14rem;
color: #cccccc;
background: #f7f7f7;
}
.appraise-submit {
padding: 20rem 20rem 0 20rem;
}
.appraise-submit-btn {
display: block;
width: 100%;
height: 40rem;
line-height: 40rem;
border: 0;
background: #579aff;
box-shadow: 1rem 2rem 5rem 0 rgba(10, 75, 173, 0.42),
inset 0 -4rem 15rem 0 rgba(164, 203, 255, 0.25);
border-radius: 6rem;
font-family: NotoSansHans-Regular;
font-size: 16rem;
color: #ffffff;
text-align: center;
}
.elder-wrapper .appraise-header-main-title {
font-family: PingFangSC-Medium;
font-size: 22rem;
color: #000000;
letter-spacing: 0;
text-align: center;
margin-bottom: 16rem;
}
.elder-wrapper .appraise-header-title {
font-family: PingFangSC-Regular;
font-size: 18rem;
color: #7e849f;
letter-spacing: 0;
text-align: center;
}
.elder-wrapper .appraise-item-box label {
padding: 0 12rem !important;
display: flex !important;
align-items: center;
height: 36rem;
}
.elder-wrapper .appraise-item-box label span {
line-height: 1.4;
}
.elder-wrapper .appraise-item-box .cells-check-label {
height: 36rem;
}
.elder-wrapper .appraise-item-box .cells-check-label .cell-ft {
background: #f7f8fa;
font-family: PingFangSC-Regular;
font-size: 20rem;
letter-spacing: 0;
color: #2c3562;
border: unset;
}
.elder-wrapper
.appraise-item-box
.cells-check-label
.check-radio:checked
+ .text-checked {
font-family: PingFangSC-Medium;
font-size: 20rem;
color: #025cea;
letter-spacing: 0;
background: #f8f9fb;
border: 0.5rem solid #025cea;
border-radius: 4rem;
}
.elder-wrapper .appraise-close-btn {
/* background: url() no-repeat; */
background-size: 100%;
}
.elder-wrapper .appraise-item-other textarea {
font-family: PingFangSC-Medium;
font-size: 20rem;
background: #f8f9fb;
min-height: 82rem;
}
.elder-wrapper .appraise-item-other textarea::placeholder,
.elder-wrapper .appraise-item-other textarea::-moz-placeholder,
.elder-wrapper .appraise-item-other textarea::-ms-input-placeholder {
font-family: PingFangSC-Medium;
font-size: 20rem;
color: #d0d2db;
}
.elder-wrapper .appraise-submit-btn {
background: #025cea;
font-family: PingFangSC-Medium;
font-size: 18rem;
color: #ffffff;
}
.close-btn {
position: absolute;
right: 10rem;
top: 14rem;
}
</style>