index.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <template>
  2. <div class="mainContentBox">
  3. <avue-crud
  4. ref="crudRef"
  5. v-model="form"
  6. v-model:page="page"
  7. v-model:search="search"
  8. :data="data"
  9. :option="option"
  10. @row-save="createRow"
  11. @row-update="updateRow"
  12. @row-del="deleteRow"
  13. @search-change="searchChange"
  14. @search-reset="resetChange"
  15. @size-change="dataList"
  16. @current-change="dataList"
  17. @selection-change="selectionChange"
  18. :before-open="onCrudBeforOpen"
  19. >
  20. <template #photoLists-form>
  21. <MultiUpload ref="multiuploadRef" v-model="form.photoLists" />
  22. </template>
  23. <template #fileLists-form>
  24. <FilesUpload
  25. ref="filesUploadRef"
  26. v-model:file-name-list="photoNameList"
  27. v-model:src-list="photoUrlList"
  28. :limit="1"
  29. :size="3000"
  30. :showTip="false"
  31. @finished="photoChange"
  32. />
  33. </template>
  34. <template #menu="{ row }">
  35. <el-button
  36. v-if="row.state == '0'"
  37. style="color: dodgerblue"
  38. link
  39. @click="sendMsg(row)"
  40. >
  41. <el-icon>
  42. <Promotion />
  43. </el-icon>
  44. 发送
  45. </el-button>
  46. </template>
  47. </avue-crud>
  48. <CommonTable
  49. ref="userTableRef"
  50. :multiple="true"
  51. tableTitle="用户"
  52. tableType="USERS"
  53. @select-multiple-sure="onSelectedFinish"
  54. />
  55. </div>
  56. </template>
  57. <script setup>
  58. import { ref } from "vue";
  59. import { useCrud } from "@/hooks/userCrud";
  60. import { useDictionaryStore } from "@/store";
  61. import MultiUpload from "@/components/Upload/MultiUpload.vue";
  62. import FilesUpload from "@/components/Upload/FilesUpload.vue";
  63. import { sendMessage } from "@/api/message/index.ts";
  64. import { treeList } from "@/api/user/index";
  65. import { getMessageOrgList } from "@/api/messageOrg/index";
  66. const userTableRef = ref(null);
  67. const photoUrlList = ref([]);
  68. const photoNameList = ref([]);
  69. const deptList = ref([]); //部门列表
  70. const getDeptList = async () => {
  71. let res = await treeList();
  72. if (res && res.code == 200) {
  73. deptList.value = res.data ?? []; //获取部门列表
  74. }
  75. };
  76. const photoChange = () => {
  77. if (photoUrlList.value.length > 0) {
  78. form.value.fileLists = [
  79. {
  80. name: photoNameList.value[0],
  81. path: photoUrlList.value[0],
  82. },
  83. ];
  84. } else {
  85. form.value.fileLists = [];
  86. }
  87. };
  88. // 数据字典相关
  89. const { dicts } = useDictionaryStore();
  90. // 传入一个url,后面不带/
  91. const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
  92. useCrud({
  93. src: "/api/v1/sys/message",
  94. });
  95. const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
  96. Methords; //增删改查
  97. const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
  98. const crudRef = ref(null); //crudRef.value 获取avue-crud对象
  99. const messageType = ref("");
  100. const route = useRoute();
  101. const messageOrgList = ref([]); //组织列表
  102. const getMessageOrgsList = async () => {
  103. let res = await getMessageOrgList();
  104. if (res && res.code == 200) {
  105. messageOrgList.value = res.data ?? []; //获取组织列表
  106. console.log(messageOrgList.value, "组织列表");
  107. }
  108. };
  109. const messageChoseType = ref([
  110. {
  111. label: "系统公告",
  112. value: "2",
  113. },
  114. {
  115. label: "个人消息",
  116. value: "0",
  117. },
  118. ]);
  119. const sendMsg = (row) => {
  120. sendMessage(row.id).then(() => {
  121. page.value.currentPage = 1;
  122. dataList();
  123. });
  124. };
  125. // 设置表格列或者其他自定义的option
  126. option.value = Object.assign(option.value, {
  127. selection: true,
  128. editBtn: true,
  129. viewBtn: false,
  130. delBtn: true,
  131. column: [
  132. {
  133. label: "创建人",
  134. prop: "creator",
  135. search: true,
  136. addDisplay: false,
  137. editDisplay: false,
  138. },
  139. {
  140. label: "消息标题",
  141. prop: "title",
  142. search: true,
  143. rules: [{ required: true }],
  144. },
  145. {
  146. label: "用户名称 ",
  147. prop: "receiveUsers",
  148. overHidden: true,
  149. click: ({ value, column }) => {
  150. userTableRef.value.startSelect();
  151. },
  152. },
  153. {
  154. label: "用户ID",
  155. prop: "receiveUser",
  156. overHidden: true,
  157. search: false,
  158. addDisplay: false,
  159. editDisplay: false,
  160. hide: true,
  161. },
  162. {
  163. label: "创建时间",
  164. prop: "created",
  165. addDisplay: false,
  166. editDisplay: false,
  167. width: 180,
  168. },
  169. {
  170. label: "已读",
  171. prop: "readState",
  172. search: false,
  173. type: "radio", //类型为单选框
  174. dicData: [
  175. {
  176. label: "否",
  177. value: "0",
  178. },
  179. {
  180. label: "是",
  181. value: "1",
  182. },
  183. ],
  184. value: "0",
  185. addDisplay: false,
  186. editDisplay: false,
  187. hide: true,
  188. },
  189. {
  190. label: "发送状态",
  191. prop: "state",
  192. search: false,
  193. type: "radio",
  194. dicData: [
  195. {
  196. label: "暂存",
  197. value: "0",
  198. },
  199. {
  200. label: "直接发送",
  201. value: "1",
  202. },
  203. ],
  204. value: "1",
  205. },
  206. {
  207. label: "msgId",
  208. prop: "msgId",
  209. addDisplay: false,
  210. editDisplay: false,
  211. value: "10",
  212. hide: true,
  213. },
  214. {
  215. label: "发送部门",
  216. prop: "deptIds",
  217. overHidden: true,
  218. type: "tree",
  219. dicData: deptList, // 使用树形结构数据
  220. props: {
  221. label: "deptName", // 显示的字段
  222. value: "id", // 传递给后端的字段
  223. children: "children", // 子节点字段
  224. },
  225. multiple: true, // 支持多选
  226. showCheckbox: true, // 显示复选框
  227. search: true,
  228. valueformat: "array", // 确保值是数组格式
  229. // nodeKey: "id",
  230. // formatter: (row) => {
  231. // if (!row.deptIds) return "";
  232. // return row.deptIds.map(id => {
  233. // const dept = findDeptById(deptList.value, id);
  234. // return dept ? dept.deptName : id;
  235. // }).join(", ");
  236. // }
  237. },
  238. {
  239. label: "消息组织",
  240. prop: "messageOrgIds",
  241. type: "select",
  242. dicData: messageOrgList, // 组织列表
  243. overHidden: true,
  244. props: {
  245. label: "messageOrgName",
  246. value: "id",
  247. },
  248. multiple: true, // 支持多选
  249. },
  250. {
  251. label: "消息内容",
  252. prop: "content",
  253. search: true,
  254. type: "textarea",
  255. overHidden: true,
  256. required: true,
  257. rules: [{ required: true }],
  258. },
  259. {
  260. label: "消息类型",
  261. prop: "type",
  262. search: false,
  263. type: "radio",
  264. dicData: messageChoseType.value,
  265. value: "0",
  266. },
  267. {
  268. label: "图片列表",
  269. prop: "photoLists",
  270. type: "array",
  271. span: 24,
  272. hide: true,
  273. },
  274. {
  275. label: "文件列表",
  276. prop: "fileLists",
  277. type: "array",
  278. span: 24,
  279. hide: true,
  280. },
  281. ],
  282. });
  283. // const findDeptById = (nodes, id) => {
  284. // // 递归查找部门
  285. // for (const node of nodes) {
  286. // if (node.id === id) return node;
  287. // if (node.children) {
  288. // const found = findDeptById(node.children, id);
  289. // if (found) return found;
  290. // }
  291. // }
  292. // return null;
  293. // };
  294. const onSelectedFinish = (selectedRowIds) => {
  295. form.value.receiveUsers = selectedRowIds;
  296. console.log(selectedRowIds, form.value);
  297. };
  298. onMounted(() => {
  299. search.value.messageId = "10";
  300. search.value.type = messageType.value = route.params.type;
  301. option.value.column.forEach((item) => {
  302. if (item.prop === "type") {
  303. item.value = messageType.value;
  304. item.dicData = messageChoseType.value.filter(
  305. (item) => item.value === messageType.value
  306. );
  307. }
  308. if (item.prop === "receiveUsers") {
  309. item.addDisplay = messageType.value === "0";
  310. item.editDisplay = messageType.value === "0";
  311. }
  312. if (item.prop === "deptIds") {
  313. item.viewDisplay = false;
  314. }
  315. });
  316. dataList();
  317. getDeptList();
  318. getMessageOrgsList();
  319. });
  320. const filesUploadRef = ref();
  321. const multiuploadRef = ref();
  322. const onCrudBeforOpen = (done, type) => {
  323. done();
  324. if (type === "edit") {
  325. nextTick(() => {
  326. multiuploadRef.value &&
  327. multiuploadRef.value.initList(form.value.photoLists);
  328. filesUploadRef.value &&
  329. filesUploadRef.value.setFileList(form.value.fileLists);
  330. });
  331. }
  332. };
  333. </script>