GroupBoard.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <template>
  2. <div class="group-board">
  3. <el-form
  4. ref="ruleFormRef"
  5. style="max-width: 600px"
  6. :model="ruleForm"
  7. label-width="auto"
  8. class="demo-ruleForm"
  9. >
  10. <el-form-item label="分组名称:" prop="name" v-if="props.drawerTitle === '查看人员分组'">
  11. <el-input
  12. v-model="ruleForm.name"
  13. type="textarea"
  14. :autosize="{ minRows: 1, maxRows: 2 }"
  15. autocomplete="off"
  16. disabled="true"
  17. />
  18. </el-form-item>
  19. <el-form-item
  20. label="分组名称:"
  21. prop="name"
  22. :rules="[{ required: true, message: '分组名称不能为空' }]"
  23. v-else
  24. >
  25. <el-input
  26. v-model="ruleForm.name"
  27. type="textarea"
  28. :autosize="{ minRows: 1, maxRows: 2 }"
  29. autocomplete="off"
  30. placeholder="请输入15字以内分组名称"
  31. maxlength="15"
  32. show-word-limit
  33. />
  34. </el-form-item>
  35. <el-form-item
  36. label="分组描述:"
  37. prop="description"
  38. v-if="props.drawerTitle === '查看人员分组'"
  39. >
  40. <el-input
  41. v-model="ruleForm.description"
  42. type="textarea"
  43. :rows="4"
  44. autocomplete="off"
  45. disabled="true"
  46. />
  47. </el-form-item>
  48. <el-form-item label="分组描述:" prop="description" v-else>
  49. <el-input
  50. v-model="ruleForm.description"
  51. type="textarea"
  52. :rows="4"
  53. maxlength="50"
  54. show-word-limit
  55. autocomplete="off"
  56. placeholder="请输入50字以内分组描述"
  57. />
  58. </el-form-item>
  59. <el-form-item label="组内成员:" prop="userList" v-if="props.drawerTitle === '查看人员分组'">
  60. <el-select
  61. v-model="ruleForm.userList"
  62. value-key="id"
  63. multiple
  64. disabled="true"
  65. >
  66. <el-option v-for="user in selectedUser" :key="user.id" :label="user.name" :value="user">
  67. </el-option>
  68. </el-select>
  69. <p
  70. >共<span>&nbsp;{{ total }}&nbsp;</span>人</p
  71. >
  72. </el-form-item>
  73. <el-form-item
  74. label="组内成员:"
  75. prop="userList"
  76. :rules="[{ required: true, message: '组内成员不能为空' }]"
  77. v-else
  78. >
  79. <el-select
  80. placeholder="请添加组内人员"
  81. v-model="ruleForm.userList"
  82. value-key="id"
  83. multiple
  84. @click="dialogVisible = true"
  85. >
  86. <el-option v-for="user in selectedUser" :key="user.id" :label="user.name" :value="user">
  87. </el-option>
  88. </el-select>
  89. <p
  90. >共<span>&nbsp;{{ total }}&nbsp;</span>人</p
  91. >
  92. </el-form-item>
  93. <el-form-item
  94. label="操作人:"
  95. prop="operator"
  96. v-if="props.drawerTitle === '查看人员分组' || props.drawerTitle === '编辑人员分组'"
  97. >
  98. <el-input v-model="ruleForm.operator" disabled="true" />
  99. </el-form-item>
  100. <el-form-item label="创建人:" prop="operator" v-else>
  101. <el-input v-model="ruleForm.operator" disabled="true" />
  102. </el-form-item>
  103. <el-form-item class="buttons" v-if="props.drawerTitle === '编辑人员分组'">
  104. <el-button @click="recoverForm(ruleFormRef)"> 重置 </el-button>
  105. <el-button type="primary" @click="changeForm(ruleFormRef)">提交</el-button>
  106. </el-form-item>
  107. <el-form-item class="buttons" v-if="props.drawerTitle === '新建人员分组'">
  108. <el-button @click="resetForm(ruleFormRef)"> 重置 </el-button>
  109. <el-button type="primary" @click="submitForm(ruleFormRef)">提交</el-button>
  110. </el-form-item>
  111. </el-form>
  112. <el-dialog
  113. v-model="dialogVisible"
  114. title="添加人员"
  115. align-center
  116. :close-on-click-modal="false"
  117. style="height: 583px"
  118. :width="731"
  119. :destroy-on-close="true"
  120. class="workShopDialog"
  121. >
  122. <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" />
  123. </el-dialog>
  124. </div>
  125. </template>
  126. <script lang="ts" setup>
  127. import { ref, reactive, watch } from 'vue';
  128. import SelectTree from './SelectTree.vue';
  129. import { storeToRefs } from 'pinia';
  130. import { useUserStore } from '@/store/modules/user';
  131. import type { FormInstance } from 'element-plus';
  132. import { ElMessage, ElMessageBox } from 'element-plus';
  133. import { debounce } from 'lodash-es';
  134. import {
  135. addUserGroup,
  136. addUserGroupParams,
  137. modifyUserGroup,
  138. modifyUserGroupParams,
  139. } from '../api/index';
  140. import { FormData } from '../type';
  141. const useUser = useUserStore();
  142. const { info } = storeToRefs(useUser);
  143. import userGroupList from '../store/index';
  144. const userGroup = userGroupList();
  145. const { getUserGroup } = userGroup;
  146. interface UserList {
  147. id: string;
  148. name: string;
  149. userId: number;
  150. }
  151. const selectedUser = ref<UserList[]>([]);
  152. const dialogVisible = ref<boolean>(false);
  153. const ruleFormRef = ref<FormInstance>();
  154. const ruleForm = reactive({
  155. name: '',
  156. description: '',
  157. userList: [] as UserList[],
  158. operator: info.value.nickname,
  159. });
  160. const handleCancle = () => {
  161. dialogVisible.value = false;
  162. };
  163. const total = ref<number>(0);
  164. const handleSubmit = (selectedData: UserList[]) => {
  165. selectedUser.value = selectedData;
  166. ruleForm.userList = selectedData;
  167. total.value = ruleForm.userList.length;
  168. dialogVisible.value = false;
  169. };
  170. const emit = defineEmits(['close']);
  171. const debounceEmit = debounce((addUserGroupParams) => {
  172. addUserGroup(addUserGroupParams)
  173. .then(() => {
  174. ElMessage({
  175. message: '创建分组成功!',
  176. type: 'success',
  177. });
  178. emit('close');
  179. getUserGroup();
  180. })
  181. .catch((e) => console.error(e));
  182. }, 500);
  183. const debounceChange = debounce((modifyUserGroupParams) => {
  184. modifyUserGroup(modifyUserGroupParams)
  185. .then(() => {
  186. ElMessage({
  187. message: '更新分组成功!',
  188. type: 'success',
  189. });
  190. emit('close');
  191. getUserGroup();
  192. })
  193. .catch((e) => console.error(e));
  194. }, 500);
  195. const submitForm = (formEl: FormInstance | undefined) => {
  196. if (!formEl) return;
  197. formEl.validate((valid) => {
  198. if (!valid) return;
  199. const params = ref<addUserGroupParams>();
  200. params.value = {
  201. name: ruleForm.name,
  202. description: ruleForm.description,
  203. userIdList: ruleForm.userList.map((user) => user.userId),
  204. total: total.value,
  205. };
  206. debounceEmit(params.value);
  207. });
  208. };
  209. const changeForm = (formEl: FormInstance | undefined) => {
  210. ElMessageBox.confirm('更新之后,引用该分组的“推送对象”将同步更新', '请确认是否更新', {
  211. confirmButtonText: '确定',
  212. cancelButtonText: '取消',
  213. type: 'warning',
  214. }).then(() => {
  215. if (!formEl) return;
  216. formEl.validate((valid) => {
  217. if (!valid) return;
  218. const params = ref<modifyUserGroupParams>();
  219. params.value = {
  220. userGroupId: props.formData.userGroupId,
  221. name: ruleForm.name,
  222. description: ruleForm.description,
  223. userIdList: ruleForm.userList.map((user) => user.userId),
  224. total: total.value,
  225. };
  226. debounceChange(params.value);
  227. });
  228. });
  229. };
  230. const resetForm = (formEl: FormInstance | undefined) => {
  231. if (!formEl) return;
  232. formEl.resetFields();
  233. };
  234. const userList = ref<UserList[]>();
  235. const recoverForm = (formEl: FormInstance | undefined) => {
  236. if (!formEl) return;
  237. ruleForm.name = props.formData.name;
  238. ruleForm.description = props.formData.description ? props.formData.description : '';
  239. userList.value = props.formData.userList.map((user) => ({
  240. id: `u${user.userId}`,
  241. userId: user.userId,
  242. name: `${user.loginName}-${user.nickname}`,
  243. }));
  244. selectedUser.value = userList.value;
  245. ruleForm.userList = userList.value;
  246. total.value = props.formData.userList.length;
  247. };
  248. const props = defineProps<{
  249. drawerTitle: string;
  250. formData: FormData;
  251. }>();
  252. watch(
  253. () => ruleForm.userList,
  254. (newUserList) => {
  255. total.value = newUserList.length;
  256. const ids = newUserList.map((user) => user.id);
  257. selectedUser.value = selectedUser.value.filter((user) => ids.includes(user.id));
  258. },
  259. { immediate: true },
  260. );
  261. watch(
  262. () => props.formData,
  263. (newForm) => {
  264. ruleForm.name = newForm.name;
  265. ruleForm.description = newForm.description ? newForm.description : '';
  266. if (props.drawerTitle === '查看人员分组') {
  267. ruleForm.operator = newForm.operator;
  268. }
  269. userList.value = newForm.userList.map((user) => ({
  270. id: `u${user.userId}`,
  271. userId: user.userId,
  272. name: `${user.loginName}-${user.nickname}`,
  273. }));
  274. selectedUser.value = userList.value;
  275. ruleForm.userList = userList.value;
  276. total.value = newForm.userList.length;
  277. },
  278. );
  279. </script>
  280. <style lang="scss" scoped>
  281. .el-form {
  282. display: flex;
  283. flex-direction: column;
  284. margin-top: 24px;
  285. gap: 20px;
  286. ::v-deep .el-select__selection {
  287. min-height: 25px;
  288. max-height: 60px;
  289. overflow-y: auto;
  290. }
  291. p {
  292. margin-top: 8px;
  293. font-weight: 400;
  294. font-size: 14px;
  295. color: rgba(0, 0, 0, 0.85);
  296. line-height: 22px;
  297. }
  298. span {
  299. font-weight: 400;
  300. font-size: 14px;
  301. color: #1890ff;
  302. line-height: 22px;
  303. }
  304. .buttons {
  305. display: flex;
  306. gap: 8px;
  307. position: absolute;
  308. bottom: 35px;
  309. right: 79px;
  310. .el-button {
  311. width: 65px;
  312. height: 32px;
  313. padding: 5px 16px 5px 16px;
  314. border-radius: 2px;
  315. }
  316. }
  317. }
  318. </style>