Commit dc7417ed authored by yuwenwen's avatar yuwenwen

修改BUG,PC端添加表情展示

parent e7445cb8
@font-face {
font-family: "iconfont"; /* Project id 5028537 */
src: url('iconfont.woff2?t=1758609551078') format('woff2'),
url('iconfont.woff?t=1758609551078') format('woff'),
url('iconfont.ttf?t=1758609551078') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 40rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-chijing:before {
content: "\e600";
}
.icon-dai:before {
content: "\e601";
}
.icon-mogui:before {
content: "\e602";
}
.icon-ganga:before {
content: "\e603";
}
.icon-qin:before {
content: "\e604";
}
.icon-nu:before {
content: "\e605";
}
.icon-shengqi:before {
content: "\e606";
}
.icon-ma:before {
content: "\e607";
}
.icon-bishi:before {
content: "\e608";
}
.icon-maimeng:before {
content: "\e609";
}
.icon-jingdai:before {
content: "\e60a";
}
.icon-kulian:before {
content: "\e60b";
}
......@@ -7,6 +7,7 @@ import './assets/styles/element-variables.scss'
import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
import '../public/iconfont/iconfont.css'
import App from './App'
import store from './store'
import router from './router'
......
const emotions = [{
code: 'icon-chijing',
name: '吃惊',
symbol: '[吃惊]'
},
{
code: 'icon-dai',
name: '',
symbol: '[呆]'
},
{
code: 'icon-mogui',
name: '魔鬼',
symbol: '[魔鬼]'
},
{
code: 'icon-ganga',
name: '尴尬',
symbol: '[尴尬]'
},
{
code: 'icon-qin',
name: '',
symbol: '[亲]'
},
{
code: 'icon-nu',
name: '',
symbol: '[怒]'
},
{
code: 'icon-shengqi',
name: '生气',
symbol: '[生气]'
},
{
code: 'icon-ma',
name: '',
symbol: '[骂]'
},
{
code: 'icon-bishi',
name: '鄙视',
symbol: '[鄙视]'
},
{
code: 'icon-maimeng',
name: '卖萌',
symbol: '[卖萌]'
},
{
code: 'icon-jingdai',
name: '惊呆',
symbol: '[惊呆]'
},
{
code: 'icon-kulian',
name: '哭脸',
symbol: '[哭脸]'
},
]
export default emotions;
\ No newline at end of file
......@@ -12,7 +12,7 @@
</template>
</div>
<div class="dynamic-content-box">
<div class="text">{{ form.content }}</div>
<div class="text" v-html="formatContent(form.content)"></div>
<div class="imgs" v-if="form.type == 'IMAGE' && form.attachments && form.attachments.length > 0">
<template v-for="(item, index) in form.attachments">
<el-image class="item" :src="item.url" :preview-src-list="[item.url]"></el-image>
......@@ -31,7 +31,7 @@
<img src="@/assets/images/favorite-active.png" v-if="form.isLike == 1" class="icon"></img>
<div class="num">{{ form.likeCount }}</div>
</div>
<div class="comment-box">
<div class="comment-box" style="border-top: 0;">
<img class="icon" src="@/assets/images/comment-icon.png"></img>
<div class="text">评论</div>
</div>
......@@ -63,18 +63,18 @@
<div class="datetime">{{ item.createTime }}</div>
</div>
<div class="content">
<div class="text" v-if="!item.replyNickName" >
{{item.content}}
</div>
<div class="text" v-else>
回复<span style="color: #0058B6;">{{item.replyNickName}}:</span>{{item.content}}
</div>
<div class="operation-text">
<div v-if="item.isFeatured==1" style="color: #F2AC39;margin-right: 10rpx;">精选</div>
<div v-if="item.isSelf==1" @click.stop="handleDelete(item)">删除</div>
</div>
</div>
<div class="text" v-if="!item.replyNickName">
{{ item.content }}
</div>
<div class="text" v-else>
回复<span style="color: #0058B6;">{{ item.replyNickName }}:</span>{{ item.content }}
</div>
<div class="operation-text">
<div v-if="item.isFeatured == 1" style="color: #F2AC39;margin-right: 10rpx;">精选</div>
<div @click.stop="handleDelete(item)">删除</div>
</div>
</div>
</div>
<div class="show-more-box" v-if="commentList.length < total" @click="loadMore">
加载更多
......@@ -86,6 +86,8 @@
</template>
<script>
import { detailData, getMomentComments } from '@/api/moments'
import { delData } from '@/api/comment';
import emotions from '@/utils/emjo';
export default {
data() {
return {
......@@ -97,14 +99,21 @@ export default {
},
commentList: [],
total: 0,
currentRow:{}
currentRow: {},
emotions,
// 预创建表情符号到iconfont的映射表,提高性能
emotionMap: {}
}
},
methods: {
openModal(row) {
this.visible = true;
this.currentRow = {...row}
this.currentRow = { ...row }
this.queryParams.pageNum = 1;
// 初始化表情映射表
this.emotions.forEach(emotion => {
this.emotionMap[emotion.symbol] = emotion.code;
});
this.commentList = [];
this.getData();
this.getComments()
......@@ -128,9 +137,83 @@ export default {
this.queryParams.pageNum += 1;
this.getComments()
},
// 删除评论
handleDelete(){
// 删除
handleDelete(row) {
this.$modal.confirm('确认要删除评论内容为:' + row.content + '的数据吗?').then(function () {
return delData(row.id);
}).then(() => {
this.$modal.msgSuccess("删除成功");
this.commentList = [];
this.getComments()
this.$emit('refresh')
})
},
/**
* 将内容中的表情符号转换为iconfont标签
* @param {string} content - 原始内容
* @returns {string} 转换后的HTML字符串
*/
formatContent(content) {
if (!content) return '';
let result = '';
let remainingContent = content;
// 提取所有表情符号并按长度排序(长表情优先匹配)
const emotionSymbols = Object.keys(this.emotionMap).sort((a, b) => b.length - a.length);
while (remainingContent.length > 0) {
let found = false;
// 查找是否有表情符号
for (const symbol of emotionSymbols) {
if (remainingContent.startsWith(symbol)) {
// 添加表情标签
result += `<i class="iconfont ${this.emotionMap[symbol]} emotion-icon"></i>`;
remainingContent = remainingContent.slice(symbol.length);
found = true;
break;
}
}
// 如果没有找到表情,提取普通文本
if (!found) {
// 找到下一个表情的位置
let nextEmotionIndex = remainingContent.length;
for (const symbol of emotionSymbols) {
const index = remainingContent.indexOf(symbol);
if (index !== -1 && index < nextEmotionIndex) {
nextEmotionIndex = index;
}
}
// 提取文本并进行HTML转义,防止XSS
const text = this.escapeHtml(remainingContent.slice(0, nextEmotionIndex));
result += text;
remainingContent = remainingContent.slice(nextEmotionIndex);
}
}
return result;
},
/**
* HTML转义处理,防止XSS攻击
* @param {string} str - 需要转义的字符串
* @returns {string} 转义后的字符串
*/
escapeHtml(str) {
if (!str) return '';
return str.replace(/[&<>"']/g, char => {
const entities = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;'
};
return entities[char] || char;
});
}
}
......@@ -369,29 +452,33 @@ export default {
}
}
.content{
color: black;
margin: 5px 0;
display: flex;
.text {
width: calc(100% - 90px);
}
.operation-text {
width:90px;
text-align: right;
font-size: 12px;
display: flex;
align-items: center;
justify-content: flex-end;
}
.mr10{
margin-right: 6px;
}
.add-text {
color: #0058B6;
}
}
.content {
color: black;
margin: 5px 0;
display: flex;
.text {
width: calc(100% - 90px);
}
.operation-text {
width: 90px;
text-align: right;
font-size: 12px;
display: flex;
align-items: center;
justify-content: flex-end;
cursor: pointer;
}
.mr10 {
margin-right: 6px;
}
.add-text {
color: #0058B6;
}
}
.tips {
font-size: 12px;
......
......@@ -8,8 +8,8 @@
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker placeholder="请选择" type="daterange" format="yyyy-MM-dd" value-format="yyyy-MM-dd"
v-model="dateRange" range-separator="至" start-placeholder="开始时间"
end-placeholder="结束时间" @change="dateChange"></el-date-picker>
v-model="dateRange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间"
@change="dateChange"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">查询</el-button>
......@@ -21,7 +21,11 @@
</el-row>
<el-table :data="tableList">
<el-table-column label="序号" width="55" type="index" align="center"></el-table-column>
<el-table-column label="动态内容" prop="content" align="center"></el-table-column>
<el-table-column label="动态内容" prop="content" align="center">
<template #default="{ row }">
<div v-html="formatContent(row.content)" class="content-container"></div>
</template>
</el-table-column>
<el-table-column label="话题" align="center" prop="topicNames" width="240"></el-table-column>
<el-table-column label="帐号" prop="userName" align="center" width="140"></el-table-column>
<el-table-column label="姓名" prop="nickName" align="center" width="120"></el-table-column>
......@@ -39,13 +43,14 @@
:limit.sync="queryParams.pageSize" @pagination="getList" />
</div>
<!-- 动态详情 -->
<detail-dialog ref="detailDialogRef"></detail-dialog>
<detail-dialog ref="detailDialogRef" @refresh="getList"></detail-dialog>
</div>
</template>
<script>
import { listData, delData } from '@/api/moments';
import DetailDialog from './DetailDialog.vue';
import emotions from '@/utils/emjo';
export default {
name: 'Moments',
data() {
......@@ -57,13 +62,19 @@ export default {
tableList: [],
total: 0,
dateRange: [],
emotions,
// 预创建表情符号到iconfont的映射表,提高性能
emotionMap: {}
}
},
components: {
DetailDialog
},
created() {
// 初始化表情映射表
this.emotions.forEach(emotion => {
this.emotionMap[emotion.symbol] = emotion.code;
});
},
mounted() {
this.getList()
......@@ -77,7 +88,6 @@ export default {
this.total = res.total
})
},
// 新增
handleDetail(row) {
this.$refs.detailDialogRef.openModal(row)
......@@ -91,8 +101,8 @@ export default {
this.getList()
})
},
dateChange(val){
if(val.length > 0){
dateChange(val) {
if (val.length > 0) {
this.queryParams['params[startTime]'] = val[0]
this.queryParams['params[endTime]'] = val[1]
}
......@@ -110,6 +120,73 @@ export default {
}
this.dateRange = []
this.getList()
},
/**
* 将内容中的表情符号转换为iconfont标签
* @param {string} content - 原始内容
* @returns {string} 转换后的HTML字符串
*/
formatContent(content) {
if (!content) return '';
let result = '';
let remainingContent = content;
// 提取所有表情符号并按长度排序(长表情优先匹配)
const emotionSymbols = Object.keys(this.emotionMap).sort((a, b) => b.length - a.length);
while (remainingContent.length > 0) {
let found = false;
// 查找是否有表情符号
for (const symbol of emotionSymbols) {
if (remainingContent.startsWith(symbol)) {
// 添加表情标签
result += `<i class="iconfont ${this.emotionMap[symbol]} emotion-icon"></i>`;
remainingContent = remainingContent.slice(symbol.length);
found = true;
break;
}
}
// 如果没有找到表情,提取普通文本
if (!found) {
// 找到下一个表情的位置
let nextEmotionIndex = remainingContent.length;
for (const symbol of emotionSymbols) {
const index = remainingContent.indexOf(symbol);
if (index !== -1 && index < nextEmotionIndex) {
nextEmotionIndex = index;
}
}
// 提取文本并进行HTML转义,防止XSS
const text = this.escapeHtml(remainingContent.slice(0, nextEmotionIndex));
result += text;
remainingContent = remainingContent.slice(nextEmotionIndex);
}
}
return result;
},
/**
* HTML转义处理,防止XSS攻击
* @param {string} str - 需要转义的字符串
* @returns {string} 转义后的字符串
*/
escapeHtml(str) {
if (!str) return '';
return str.replace(/[&<>"']/g, char => {
const entities = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;'
};
return entities[char] || char;
});
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment