123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- <template>
- <div :class="{'comment-active': commentActive}" style="border: 1px solid #eee; margin: 0; position: relative" @click="handleClickBlank">
- <textarea ref="commentRef" v-model="myComment" @input="handleCommentChange" @blur="handleBlur" class="comment-content" :rows="3" placeholder="请输入你的评论,可以@成员" />
- <div class="comment-content comment-html-shower" :class="{'no-content':noConent, 'top-div': showHtml, 'bottom-div': showHtml == false }" v-html="commentHtml" @click="handleClickHtmlShower"></div>
- <div class="comment-buttons" v-if="commentActive">
- <div style="cursor: pointer">
- <Tooltip title="选择@用户">
- <user-add-outlined @click="openSelectUser" />
- </Tooltip>
- <Tooltip title="上传附件">
- <PaperClipOutlined @click="uploadVisible = !uploadVisible" />
- </Tooltip>
- <span title="表情" style="display: inline-block">
- <SmileOutlined ref="emojiButton" @click="handleShowEmoji" />
- <div style="position: relative" v-show=""> </div>
- </span>
- </div>
- <div v-if="commentActive">
- <a-button v-if="inner" @click="noComment" style="margin-right: 10px">取消</a-button>
- <a-button type="primary" @click="sendComment" :loading="buttonLoading" :disabled="disabledButton">发 送</a-button>
- </div>
- </div>
- <upload-chunk ref="uploadRef" :visible="uploadVisible" @select="selectFirstFile"></upload-chunk>
- </div>
- <UserSelectModal labelKey="realname" rowKey="username" @register="registerModal" @getSelectResult="setValue" isRadioSelection></UserSelectModal>
- <a-modal v-model:visible="visibleEmoji" :footer="null" wrapClassName="emoji-modal" :closable="false" :width="490">
- <template #title>
- <span></span>
- </template>
- <Picker
- :pickerStyles="pickerStyles"
- :i18n="optionsName"
- :data="emojiIndex"
- emoji="grinning"
- :showPreview="false"
- :infiniteScroll="false"
- :showSearch="false"
- :showSkinTones="false"
- set="apple"
- @select="showEmoji">
- </Picker>
- </a-modal>
- </template>
- <script lang="ts">
- import { ref, watch, computed } from 'vue';
- import { propTypes } from '/@/utils/propTypes';
- import { UserAddOutlined, PaperClipOutlined, SmileOutlined } from '@ant-design/icons-vue';
- import { Tooltip } from 'ant-design-vue';
- import UserSelectModal from '/@/components/Form/src/jeecg/components/modal/UserSelectModal.vue';
- import { useModal } from '/@/components/Modal';
- import UploadChunk from './UploadChunk.vue';
- import { Picker } from 'emoji-mart-vue-fast/src';
- import 'emoji-mart-vue-fast/css/emoji-mart.css';
- import { useEmojiHtml } from './useComment';
- const optionsName = {
- categories: {
- recent: '最常用的',
- smileys: '表情选择',
- people: '人物&身体',
- nature: '动物&自然',
- foods: '食物&饮料',
- activity: '活动',
- places: '旅行&地点',
- objects: '物品',
- symbols: '符号',
- flags: '旗帜',
- },
- };
- export default {
- name: 'MyComment',
- components: {
- UserAddOutlined,
- Tooltip,
- UserSelectModal,
- PaperClipOutlined,
- UploadChunk,
- SmileOutlined,
- Picker,
- },
- props: {
- inner: propTypes.bool.def(false),
- inputFocus: {
- type: Boolean,
- default: false,
- },
- },
- emits: ['cancel', 'comment'],
- setup(props, { emit }) {
- const uploadVisible = ref(false);
- const uploadRef = ref();
- //注册model
- const [registerModal, { openModal }] = useModal();
- const buttonLoading = ref(false);
- const myComment = ref<string>('');
- function sendComment() {
- console.log(myComment.value);
- let content = myComment.value;
- if (!content && content !== '0') {
- disabledButton.value = true;
- } else {
- buttonLoading.value = true;
- let fileList = [];
- if (uploadVisible.value == true) {
- fileList = uploadRef.value.getUploadFileList();
- }
- emit('comment', content, fileList);
- setTimeout(() => {
- buttonLoading.value = false;
- }, 350);
- }
- }
- const disabledButton = ref(false);
- watch(myComment, () => {
- let content = myComment.value;
- if (!content && content !== '0') {
- disabledButton.value = true;
- } else {
- disabledButton.value = false;
- }
- });
- function noComment() {
- emit('cancel');
- }
- const commentRef = ref();
- watch(
- () => props.inputFocus,
- (val) => {
- if (val == true) {
- // commentRef.value.focus()
- myComment.value = '';
- if (uploadVisible.value == true) {
- uploadRef.value.clear();
- uploadVisible.value = false;
- }
- }
- },
- { deep: true, immediate: true }
- );
- function openSelectUser() {
- openModal(true, {
- isUpdate: false,
- });
- }
- function setValue(options) {
- console.log('setValue', options);
- if (options && options.length > 0) {
- const { label, value } = options[0];
- if (label && value) {
- let str = `${label}[${value}]`;
- let temp = myComment.value;
- if (!temp) {
- myComment.value = '@' + str;
- } else {
- if (temp.endsWith('@')) {
- myComment.value = temp + str;
- } else {
- myComment.value = '@' + str + ' ' + temp;
- }
- }
- }
- }
- }
- function handleCommentChange() {
- //console.log(1,e)
- }
- watch(
- () => myComment.value,
- (val) => {
- if (val && val.endsWith('@')) {
- openSelectUser();
- }
- }
- );
- const emojiButton = ref();
- function onSelectEmoji(emoji) {
- let temp = myComment.value || '';
- temp += emoji;
- myComment.value = temp;
- emojiButton.value.click();
- }
-
- const visibleEmoji = ref(false);
- function showEmoji(e) {
- let temp = myComment.value || '';
- let str = e.colons;
- if (str.indexOf('::') > 0) {
- str = str.substring(0, str.indexOf(':') + 1);
- }
- myComment.value = temp + str;
- visibleEmoji.value = false;
- handleBlur();
- }
- const pickerStyles = {
- width: '490px'
- /* height: '350px',
- top: '0px',
- left: '-75px',
- position: 'absolute',
- 'z-index': 9999*/
- };
- function handleClickBlank(e) {
- console.log('handleClickBlank');
- e.preventDefault();
- e.stopPropagation();
- visibleEmoji.value = false;
- commentActive.value = true;
- }
- function handleShowEmoji(e) {
- console.log('handleShowEmoji');
- e.preventDefault();
- e.stopPropagation();
- visibleEmoji.value = !visibleEmoji.value;
- }
- const { emojiIndex, getHtml } = useEmojiHtml();
- const commentHtml = computed(() => {
- let temp = myComment.value;
- if (!temp) {
- return '请输入你的评论,可以@成员';
- }
- return getHtml(temp);
- });
- const showHtml = ref(false);
- function handleClickHtmlShower(e) {
- e.preventDefault();
- e.stopPropagation();
- showHtml.value = false;
- commentRef.value.focus();
- console.log(234);
- commentActive.value = true;
- }
- function handleBlur() {
- showHtml.value = true;
- }
-
- const commentActive = ref(false);
- const noConent = computed(()=>{
- if(myComment.value.length>0){
- return false;
- }
- return true;
- });
- function changeActive(){
- if(myComment.value.length==0){
- commentActive.value = false
- uploadVisible.value = false;
- }
- }
-
- function selectFirstFile(fileName){
- if(myComment.value.length==0){
- myComment.value = fileName;
- }
- }
-
- return {
- myComment,
- sendComment,
- noComment,
- disabledButton,
- buttonLoading,
- commentRef,
- registerModal,
- openSelectUser,
- setValue,
- handleCommentChange,
- uploadRef,
- uploadVisible,
- onSelectEmoji,
- optionsName,
- emojiButton,
- emojiIndex,
- showEmoji,
- pickerStyles,
- visibleEmoji,
- handleClickBlank,
- handleShowEmoji,
- commentHtml,
- showHtml,
- handleClickHtmlShower,
- handleBlur,
- commentActive,
- noConent,
- changeActive,
- selectFirstFile
- };
- },
- };
- </script>
- <style lang="less">
- .comment-content {
- box-sizing: border-box;
- margin: 0;
- padding: 0;
- font-variant: tabular-nums;
- list-style: none;
- font-feature-settings: tnum;
- position: relative;
- display: inline-block;
- width: 100%;
- padding: 4px 11px;
- color: rgba(0, 0, 0, 0.85);
- font-size: 15px;
- line-height: 1.5715;
- background-color: #fff;
- background-image: none;
- border: 1px solid #d9d9d9;
- border-radius: 2px;
- transition: all 0.3s;
- width: 100%;
- border: solid 0px;
- outline: none;
- .emoji-item {
- display: inline-block !important;
- width: 0 !important;
- }
- }
- .comment-buttons {
- padding: 10px;
- display: flex;
- justify-content: space-between;
- border-top: 1px solid #d9d9d9;
- .anticon {
- margin: 5px;
- }
- }
- .comment-html-shower {
- position: absolute;
- top: 0;
- left: 0;
- height: 70px;
- &.bottom-div {
- z-index: -99;
- }
- &.top-div {
- z-index: 9;
- }
- }
- .emoji-modal {
- > .ant-modal{
- right: 25% !important;
- margin-right: 16px !important;
- }
- .ant-modal-header{
- padding: 0 !important;
- }
- .emoji-mart-bar{
- display: none;
- }
- h3.emoji-mart-category-label{
- /* display: none;*/
- border-bottom: 1px solid #eee;
- }
- }
-
- .comment-active{
- border-color: #1e88e5 !important;
- box-shadow: 0 1px 1px 0 #90caf9, 0 1px 6px 0 #90caf9;
- }
- .no-content{
- color: #a1a1a1
- }
-
-
- .emoji-type-image.emoji-set-apple {
- background-image: url("./image/emoji.png");
- }
- </style>
|