Comment.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. <template>
  2. <div class="textarea w100">
  3. <el-input v-model="value" type="textarea" :autosize="{ minRows: 10, maxRows: 20 }" :placeholder="placeholder" maxlength="2000"> </el-input>
  4. <span class="bttons">
  5. <el-button @click="showComents" class="default-button" :loading="loading">常用意见</el-button>
  6. <el-button type="primary" @click="onAddComments" :loading="loading">添加到常用意见</el-button>
  7. </span>
  8. <el-drawer v-model="state.showDrawer" size="35%" title="" :show-close="false" :modal="modal">
  9. <template #header="{ close }">
  10. <div class="comments-header">
  11. <div>
  12. <el-button link @click="state.active = 'default'" :class="{ active: state.active === 'default' }"> 常用意见 </el-button>
  13. <el-button link @click="state.active = 'add'" :class="{ active: state.active === 'add' }"> 新增意见 </el-button>
  14. <span></span>
  15. </div>
  16. </div>
  17. <div class="flex-center-align">
  18. <el-button link @click="state.manage = true" v-if="!state.manage && state.active === 'default' && state.commentsList.length"
  19. >管理</el-button
  20. >
  21. <el-button link @click="state.manage = false" type="primary" v-if="state.manage && state.active === 'default'">返回</el-button>
  22. <el-button link @click="close">
  23. <SvgIcon name="ele-Close" class="mr5" @click="close" size="16px" />
  24. </el-button>
  25. </div>
  26. </template>
  27. <div class="comments-container" v-loading="state.loading">
  28. <template v-if="state.commentsList.length">
  29. <!-- 默认状态 -->
  30. <template v-if="state.active === 'default' && !state.manage">
  31. <ul class="comments-box">
  32. <li class="comments-item" v-for="(item, index) in state.commentsList" :key="index" @click="chooseComment(item)">
  33. <p class="text-ellipsis2" :title="item.content">{{ item.content }}</p>
  34. </li>
  35. </ul>
  36. </template>
  37. <!-- 管理 -->
  38. <template v-if="state.active === 'default' && state.manage">
  39. <ul class="comments-box">
  40. <li
  41. class="comments-item"
  42. v-for="(item, index) in state.commentsList"
  43. :class="[item.ischeck === true ? 'choosed' : '']"
  44. :key="index"
  45. @click="handelComent(item, index)"
  46. >
  47. <p class="text-ellipsis2" :title="item.content">{{ item.content }}</p>
  48. <el-checkbox v-model="item.ischeck" class="check-icon" label="" v-if="item.ischeck" size="large" />
  49. </li>
  50. </ul>
  51. </template>
  52. </template>
  53. <template v-if="!state.commentsList.length && state.active !== 'add'">
  54. <Empty description="暂无常用语" />
  55. </template>
  56. <!-- 新增意见 -->
  57. <template v-if="state.active === 'add'">
  58. <div>
  59. <el-form :model="state.commentsForm" ref="commentsFormRef">
  60. <el-form-item label="" prop="content" :rules="[{ required: true, message: '请填写新增常用意见', trigger: 'blur' }]">
  61. <el-input
  62. v-model="state.commentsForm.content"
  63. type="textarea"
  64. :autosize="{ minRows: 10, maxRows: 10 }"
  65. placeholder="请填写新增常用意见"
  66. clearable
  67. >
  68. </el-input>
  69. </el-form-item>
  70. </el-form>
  71. </div>
  72. </template>
  73. </div>
  74. <template #footer v-if="state.active === 'add' || state.manage">
  75. <div style="flex: auto">
  76. <el-button @click="deleteComment" class="default-button" v-if="state.active === 'default' && state.manage">删 除</el-button>
  77. <el-button type="primary" @click="commentSave" v-if="state.active === 'add'">保 存</el-button>
  78. </div>
  79. </template>
  80. </el-drawer>
  81. </div>
  82. </template>
  83. <script setup lang="ts" name="commentManage">
  84. import { reactive, ref, computed } from 'vue';
  85. import { ElMessage, ElMessageBox } from 'element-plus';
  86. import { commonList, addCommon, deleteCommon } from '/@/api/business/commonP';
  87. import { commonEeum } from '/@/utils/tools';
  88. const emit = defineEmits(['chooseComment', 'update:modelValue']);
  89. const props = defineProps({
  90. modal: {
  91. type: Boolean,
  92. default: false,
  93. },
  94. modelValue: {
  95. type: String,
  96. default: '',
  97. },
  98. placeholder: {
  99. type: String,
  100. default: '请填写内容',
  101. },
  102. loading: {
  103. type: Boolean,
  104. default: false,
  105. },
  106. commonEeum: {
  107. type: String,
  108. default: commonEeum.Seat,
  109. },
  110. });
  111. const value = computed({
  112. get() {
  113. return props.modelValue;
  114. },
  115. set(value) {
  116. emit('update:modelValue', value);
  117. },
  118. });
  119. // 定义变量内容
  120. const state = reactive<any>({
  121. showDrawer: false,
  122. commentsList: [],
  123. commentsForm: {
  124. content: '',
  125. },
  126. chooseCommentList: [],
  127. active: 'default',
  128. manage: false,
  129. loading: false,
  130. typecode: '',
  131. });
  132. const commentsFormRef = ref();
  133. // 打开常用意见管理
  134. const showComents = () => {
  135. openDialog();
  136. };
  137. // 添加到常用意见
  138. const onAddComments = async () => {
  139. if (!props.modelValue) {
  140. ElMessage.warning(props.placeholder);
  141. return;
  142. }
  143. await addCommon({
  144. typeCode: props.commonEeum,
  145. content: props.modelValue,
  146. });
  147. ElMessage.success('操作成功');
  148. closeDialog();
  149. };
  150. // 打开弹窗
  151. const openDialog = async () => {
  152. state.typecode = props.commonEeum;
  153. state.active = 'default';
  154. commentsFormRef.value?.resetFields();
  155. state.manage = false;
  156. getList();
  157. state.showDrawer = true;
  158. };
  159. const getList = async () => {
  160. try {
  161. state.loading = true;
  162. const res: any = await commonList({ typecode: props.commonEeum });
  163. state.commentsList = res.result;
  164. state.loading = false;
  165. } catch (error) {
  166. state.loading = false;
  167. }
  168. };
  169. // 选中常用意见(管理)
  170. const handelComent = (item: any, index: number) => {
  171. const repeatData = [...state.commentsList];
  172. const repeatSelarr = [...state.chooseCommentList];
  173. if (!repeatData[index].ischeck) {
  174. repeatData[index].ischeck = true;
  175. repeatSelarr.push(item);
  176. } else {
  177. repeatData[index].ischeck = false;
  178. if (!repeatSelarr || repeatSelarr.length == 0) {
  179. return '';
  180. }
  181. repeatSelarr.splice(index, 1);
  182. }
  183. state.chooseCommentList = repeatSelarr.filter((item: any) => item.ischeck);
  184. };
  185. // 重置状态
  186. const resetState = () => {
  187. state.active = 'default';
  188. state.manage = false;
  189. state.chooseCommentList = [];
  190. state.commentsForm.content = '';
  191. getList();
  192. };
  193. // 删除常用意见
  194. const deleteComment = () => {
  195. if (!state.chooseCommentList.length) {
  196. ElMessage.warning('请选择要删除的常用意见');
  197. return;
  198. }
  199. ElMessageBox.confirm(`确定要删除选中的常用意见,是否继续?`, '提示', {
  200. confirmButtonText: '确认',
  201. cancelButtonText: '取消',
  202. draggable: true,
  203. cancelButtonClass: 'default-button',
  204. type: 'warning',
  205. })
  206. .then(() => {
  207. const chooseCommentList = state.chooseCommentList.map((item: any) => {
  208. return item.id;
  209. });
  210. deleteCommon({ ids: chooseCommentList }).then(() => {
  211. ElMessage.success('操作成功');
  212. resetState();
  213. state.loading = false;
  214. });
  215. })
  216. .catch(() => {});
  217. };
  218. // 添加常用意见 保存
  219. const commentSave = () => {
  220. commentsFormRef.value.validate((valid: boolean) => {
  221. if (valid) {
  222. state.loading = true;
  223. addCommon({
  224. typeCode: state.typecode,
  225. content: state.commentsForm.content,
  226. }).then(() => {
  227. ElMessage.success('操作成功');
  228. resetState();
  229. state.loading = false;
  230. });
  231. } else {
  232. return false;
  233. }
  234. });
  235. };
  236. // 选择常用意见 填入填写框
  237. const chooseComment = (item: any) => {
  238. emit('chooseComment', item);
  239. closeDialog();
  240. };
  241. // 关闭弹窗
  242. const closeDialog = () => {
  243. state.showDrawer = false;
  244. };
  245. // 暴露变量
  246. defineExpose({
  247. openDialog,
  248. closeDialog,
  249. });
  250. </script>
  251. <style lang="scss" scoped>
  252. .textarea {
  253. position: relative;
  254. .bttons {
  255. position: absolute;
  256. right: 10px;
  257. bottom: 10px;
  258. }
  259. :deep(.el-textarea__inner) {
  260. padding-bottom: 40px;
  261. }
  262. }
  263. .comments-container {
  264. .comments-box {
  265. .comments-item {
  266. border: var(--el-border);
  267. border-radius: var(--el-border-radius-base);
  268. margin-bottom: 10px;
  269. padding: 8px 15px;
  270. cursor: pointer;
  271. position: relative;
  272. line-height: 18px;
  273. &:hover {
  274. box-shadow: 0 0 0 1px var(--el-color-primary) inset;
  275. background-color: var(--hotline-bg-main-color);
  276. }
  277. .check-icon {
  278. position: absolute;
  279. right: 0;
  280. top: -13px;
  281. }
  282. }
  283. .choosed {
  284. box-shadow: 0 0 0 1px var(--el-color-primary) inset;
  285. }
  286. }
  287. }
  288. .comments-header {
  289. .active {
  290. color: var(--el-color-primary);
  291. font-size: var(--el-font-size-medium);
  292. }
  293. }
  294. :deep(.el-drawer__footer) {
  295. box-shadow: 0px -4px 10px 0px rgb(0 0 0 / 10%);
  296. border-radius: 0px 0px 8px 0px;
  297. padding: 10px 20px;
  298. }
  299. </style>