<script lang="ts" setup>
|
import { onMounted, reactive, toRefs, watch } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
|
import { cloneDeep } from 'lodash-es';
|
|
import { create, getCommonWordsSelector } from '#/api/system/commonWords';
|
|
import CommonWordsPopover from './CommonWordsPopover.vue';
|
|
interface State {
|
innerValue: any;
|
commonList: any[];
|
list: any[];
|
}
|
|
const props = defineProps({
|
value: { type: String, default: '' },
|
commonWordsCount: { type: Number, default: 5 },
|
placeholder: { type: String, default: '请输入' },
|
styleType: { type: Number, default: 0 },
|
messageText: { type: String, default: '' },
|
});
|
const emit = defineEmits(['update:value', 'change']);
|
const state = reactive<State>({
|
innerValue: '',
|
commonList: [],
|
list: [],
|
});
|
const { innerValue } = toRefs(state);
|
const { createMessage } = useMessage();
|
watch(
|
() => props.value,
|
(val) => {
|
state.innerValue = val;
|
},
|
{ immediate: true },
|
);
|
|
function initData() {
|
state.list = [];
|
getCommonWordsSelector().then((res) => {
|
const data = cloneDeep(res.data.list) || [];
|
state.commonList = data.splice(0, props.commonWordsCount);
|
state.list = data;
|
});
|
}
|
function insertOpinion(val) {
|
state.innerValue += val;
|
onChange(state.innerValue);
|
}
|
function onChange(value) {
|
emit('update:value', value);
|
emit('change', value);
|
}
|
function addCommonWord() {
|
const message = props.messageText || '请先填写审批意见';
|
if (!state.innerValue) return createMessage.warning(message);
|
const query = { commonWordsText: state.innerValue, commonWordsType: 1 };
|
create(query).then((res) => {
|
createMessage.success(res.msg);
|
initData();
|
});
|
}
|
|
onMounted(() => {
|
initData();
|
});
|
</script>
|
<template>
|
<div class="approval-opinion" :class="{ 'approval-opinion-style': styleType == 1 }">
|
<a-form-item-rest>
|
<jnpf-textarea class="opinion-textarea" v-model:value="innerValue" :placeholder="placeholder" @change="onChange" />
|
<div class="opinion-extra">
|
<div class="common-words">
|
<div v-for="item in state.commonList" :key="item" @click="insertOpinion(item.commonWordsText)" :title="item.commonWordsText">
|
{{ item.commonWordsText }}
|
</div>
|
</div>
|
<a-button type="link" class="btn" @click="addCommonWord">设为常用语</a-button>
|
<CommonWordsPopover :list="state.list" class="btn" @confirm="insertOpinion" />
|
</div>
|
</a-form-item-rest>
|
</div>
|
</template>
|
<style lang="scss">
|
.dark,
|
.dark[data-theme='custom'],
|
.dark[data-theme='default'] {
|
.approval-opinion {
|
background-color: rgb(255 255 255 / 8%);
|
border: 1px solid #424242;
|
}
|
}
|
|
.approval-opinion {
|
border: 1px solid #d9d9d9;
|
border-radius: 4px;
|
|
.opinion-textarea {
|
background: unset;
|
border-width: 0;
|
|
&:focus {
|
border-inline-end-width: 0 !important;
|
box-shadow: unset !important;
|
}
|
}
|
|
.opinion-extra {
|
display: flex;
|
padding: 0 10px 10px;
|
|
.common-words {
|
display: flex;
|
flex: 1;
|
flex-shrink: 0;
|
min-width: 0;
|
overflow-x: auto;
|
|
div {
|
flex-shrink: 0;
|
max-width: 160px;
|
height: 32px;
|
padding: 0 12px;
|
margin-right: 8px;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
line-height: 32px;
|
text-align: center;
|
white-space: nowrap;
|
cursor: pointer;
|
background-color: var(--component-background);
|
border: 1px dashed var(--border-color-base);
|
border-radius: 4px;
|
}
|
}
|
|
.btn {
|
flex-shrink: 0;
|
}
|
}
|
}
|
</style>
|