huangyinfeng
4 天以前 db42d08c39ae6129e2b95cd24c0d57c6769282e5
提交 | 用户 | age
2c1249 1 <template>
H 2   <div class="p-2">
3     <vxe-toolbar>
4       <template #buttons>
5         <div style="display: flex; align-items: flex-end">
6           <span style="font-size: 1.25rem; font-weight: 600">快速文本</span
7           ><span style="margin-left: 5px; padding-bottom: 4px; font-size: 12px"
8             >作为模板使用,在写信时快速创建内容</span
9           >
10         </div>
11       </template>
12       <template #tools>
13         <a-button type="primary" @click="showDrawer('add', '')">新建文本</a-button>
14       </template>
15     </vxe-toolbar>
16
17     <vxe-table ref="xTable" style="margin: 10px 0" :data="demo.tableData" @mounted="onMounted">
18       <vxe-column width="60">
19         <template #default>
20           <span class="drag-btn">
21             <HolderOutlined />
22           </span>
23         </template>
24       </vxe-column>
25       <vxe-column field="userName" title="标题" width="250"></vxe-column>
26       <vxe-column field="content" title="内容" min-width="250"></vxe-column>
27       <vxe-column field="age" title="操作" width="150">
28         <template #default="{ row }">
29           <a style="margin-right: 10px" @click="showDrawer('update', row)">编辑</a>
30           <a style="margin-right: 10px" @click="fnDelete(row)">删除</a>
31         </template>
32       </vxe-column>
33     </vxe-table>
34     <a-drawer :title="`${title}文本`" placement="right" :open="open" @close="onClose" width="600">
35       <a-form ref="formRef" :model="form" style="margin-top: 20px">
36         <a-form-item
37           label="标题"
38           name="textName"
39           :rules="[{ required: true, message: '请输入名称', trigger: 'blur' }]"
40         >
41           <a-input v-model:value="form.textName" placeholder="请输入名称" />
42         </a-form-item>
43         <a-form-item
44           label="内容"
45           name="content"
46           :rules="[{ required: true, message: '请输入内容', trigger: 'blur' }]"
47         >
48           <Tinymce v-model="form.content" :isElse="false" :isText="false" :isImg="false"></Tinymce>
49         </a-form-item>
50       </a-form>
51       <template #footer>
52         <div style="margin-top: 20px; text-align: center">
53           <div style="margin-bottom: 20px"
54             >写邮件时,输入
55             <span style="color: red">&</span>标题关键词,联想出快速文本,快捷插入</div
56           >
57           <a-button style="margin-right: 8px" @click="onClose">取消</a-button>
58           <a-button type="primary" @click="onOk">保存</a-button>
59         </div>
60       </template>
61     </a-drawer>
62   </div>
63 </template>
64
65 <script lang="ts" setup>
66   import { ref, computed, onMounted, nextTick, onUnmounted, reactive } from 'vue';
67   import { Tinymce } from '@/components/Tinymce';
68   import {
69     getQuickTextApi,
70     addQuickTextApi,
71     updateQuickTextApi,
72     deleteQuickTextApi,
73   } from '@/api/email/userList';
74   
75   // 排序
76   import { HolderOutlined } from '@ant-design/icons-vue';
77   import Sortable from 'sortablejs';
78   let sortable: any;
79   const demo = reactive({
80     showHelpTip: false,
81     tableData: [],
82   });
83   const xTable = ref();
84   const rowDrop = () => {
85     const $table = xTable.value;
86     sortable = Sortable.create($table.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
87       handle: '.drag-btn',
88       onEnd: (sortableEvent) => {
89         const newIndex = sortableEvent.newIndex as number;
90         const oldIndex = sortableEvent.oldIndex as number;
91         const currRow:Record<string, any> = demo.tableData.splice(oldIndex, 1)[0];
92         // demo.tableData.splice(newIndex, 0, currRow);
93         updateQuickTextApi({
94           textId: currRow.textId,
95           textName: currRow.textName,
96           content: currRow.content,
97           sortId: newIndex,
98         }).then(() => {
99           fnGetList();
100         }).catch(()=>{});
101       },
102     });
103   };
104
105   let initTime: any;
106   nextTick(() => {
107     // 加载完成之后在绑定拖动事件
108     initTime = setTimeout(() => {
109       rowDrop();
110     }, 500);
111   });
112
113   onUnmounted(() => {
114     clearTimeout(initTime);
115     if (sortable) {
116       sortable.destroy();
117     }
118   });
119
120   const form = ref<Record<string, any>>({});
121   const title = ref('新建');
122   const open = ref<boolean>(false);
123   const handleType = ref('add');
124   const formRef = ref();
125   const showDrawer = (type, row) => {
126     handleType.value = type;
127     open.value = true;
128     if (type == 'add') {
129       form.value = {
130         textName: '',
131         content: '',
132       };
133     } else {
134       title.value = '编辑';
135       nextTick(() => {
136         formRef.value.resetFields();
137         form.value = Object.assign(form.value, row);
138       });
139     }
140   };
141   const api = computed(() => {
142     return handleType.value == 'add' ? addQuickTextApi : updateQuickTextApi;
143   });
144
145   function fnDelete(row) {
146     deleteQuickTextApi({ textId: row.textId }).then((res) => {
147       if (res.code == 0) {
148         fnGetList();
149       }
150     });
151   }
152   function fnGetList() {
153     getQuickTextApi({}).then((res) => {
154       console.log(res);
155       demo.tableData = res.data;
156     });
157   }
158   const onClose = () => {
159     open.value = false;
160   };
161   import { useMessage } from '@/hooks/web/useMessage';
162   const { createMessage } = useMessage();
163   const onOk = () => {
164     formRef.value.validate().then(() => {
165       const data: Record<string, any> = {
166         textName: form.value.textName,
167         content: form.value.content,
168       };
169       if (handleType.value != 'add') {
170         data.textId = form.value.textId;
171       }
172       api
173         .value(data)
174         .then((res) => {
175           if (res.code === 0) {
176             createMessage.success(res.msg);
177           }
178           fnGetList();
179           onClose();
180         })
181         .catch((e) => {
182           createMessage.warning(e);
183         });
184     });
185   };
186
187   onMounted(() => {
188     fnGetList();
189   });
190 </script>
191
192 <style scoped>
193   .sortable-row-demo .drag-btn {
194     font-size: 12px;
195     cursor: move;
196   }
197
198   .sortable-row-demo .vxe-body--row.sortable-ghost,
199   .sortable-row-demo .vxe-body--row.sortable-chosen {
200     background-color: #dfecfb;
201   }
202 </style>