selectObjectNoDedup.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <template>
  2. <view class="page_body">
  3. <!-- 头部 -->
  4. <nav-bar :class="{'item_width':pageType=='edit'}" height="320" title="选择采集对象" :defaultTabBtnValue="targetType" :tabBtns="state.tabBtns" :onlyTitle="false" :showHeadSearchInput="false" :showFilterPicker="false" :showTabs="false" :showTabBtns="true" rightWidth="0rpx" @CommonFilterData="CommonFilterData" @GoBack="GoBack">
  5. <template #tabs_bottom_content>
  6. <!-- 搜索框单独一行 -->
  7. <view class="nav_head row_search_box">
  8. <uni-easyinput class="search_box" v-model="state.searchWord" trim="all" :styles="state.searchInputStyles"
  9. :placeholderStyle="state.searchInputPlaceholderStyle" placeholder="请输入关键字搜索">
  10. <template #left>
  11. <image src="@/static/image/overview/search.png" class="search_icon"></image>
  12. </template>
  13. </uni-easyinput>
  14. </view>
  15. </template>
  16. </nav-bar>
  17. <!-- https://ofreshman.github.io/uni-tree-view/guide/quick-start -->
  18. <!-- expand-on-click-node: 点击整行是否展开/收起-->
  19. <view class="tree_node">
  20. <uni-tree-view
  21. selectable
  22. multiple
  23. ref="treeRef"
  24. theme-color="#2E64FA"
  25. v-model="state.defaultCheckedKeys"
  26. :default-expand-all="true"
  27. :expand-on-click-node="true"
  28. :checked-disabled="true"
  29. :filter-value="state.searchWord"
  30. highlight-filter
  31. :data="state.treeData"
  32. @check-change="HandleCheckChange"
  33. >
  34. <template #append="{ data,node }">
  35. <!-- data 是你传入的原始数据项,可读任意业务字段 -->
  36. <text v-if="data?.children?.length" style="color:#87918b; font-size:17rpx;">
  37. <uni-icons :type="node.expanded?'down':'right'" style="font-size: 28rpx;color: #999999;"></uni-icons>
  38. </text>
  39. </template>
  40. </uni-tree-view>
  41. </view>
  42. <view class="foot_btn">
  43. <view class="btn_submit" @click="SaveCheckedTreeData">确定{{state.checkedValue.length?`(已选${state.checkedValue.length}人)`:''}}</view>
  44. </view>
  45. </view>
  46. </template>
  47. <script setup>
  48. import navBar from '@/components/navBar.vue';
  49. import uniEasyinput from '@/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue';
  50. import uniTreeView from '@/uni_modules/KieranYin9527-tree/components/uni-tree-view/uni-tree-view.vue';
  51. import {findDepartContainUser,findCollectPersonalInfo} from '@/reqApi/notification.js';
  52. import {getDeptTreeData,subjectTreeData,gradTreeData,permTreeData} from '@/common/common.js';
  53. import {onLoad} from '@dcloudio/uni-app';
  54. import {reactive,ref,onUnmounted,nextTick} from 'vue';
  55. const state = reactive({
  56. tabBtns:[{
  57. label:'按部门',
  58. value:1,
  59. },{
  60. label:'按学科',
  61. value:2,
  62. },{
  63. label:'按年级',
  64. value:3,
  65. },{
  66. label:'按权限',
  67. value:4,
  68. }],
  69. defaultCheckedKeys:[],//初始选中key
  70. checkedDisabled:[],
  71. checkedValue:[],//勾选的项
  72. treeData:[],
  73. deptTreeData:[],//部门tree
  74. gradeTreeList:[],//年级tree
  75. permissionTreeList:[],//权限tree
  76. subjectTreeList:[]//学科tree
  77. });
  78. const schoolYearId = ref('');//学年学期id
  79. const targetType = ref('');//采集对象 1-按部门,2-按学科,3-按年级,4-按权限,5-按学生
  80. const pageType = ref('');//添加或修改
  81. const treeRef = ref('');
  82. onLoad((option) => {
  83. schoolYearId.value = option.schoolYearId;
  84. targetType.value = Number(option.targetType);
  85. pageType.value = option.type;
  86. const taskTargetsTreeData = uni.getStorageSync('taskTargetsTreeData');
  87. const taskTargets = taskTargetsTreeData?.taskTargets || [];
  88. state.checkedValue = taskTargets;
  89. state.defaultCheckedKeys = taskTargets?.map(item=>item.id) || [];
  90. state.checkedDisabled = taskTargets.filter(item=>item.disabled && item.checked=='checked');
  91. if(pageType.value == 'add'){
  92. GetDepartContainUser();
  93. GetCollectPersonalInfo();
  94. }else{//编辑
  95. state.tabBtns = state.tabBtns.filter(item=>item.value == targetType.value);
  96. state.treeData = taskTargetsTreeData?.taskTargetsTree || [];
  97. }
  98. })
  99. //查询本学校下的当前学年的所有部门及部门下的人
  100. const GetDepartContainUser = () => {
  101. findDepartContainUser(schoolYearId.value).then(res=>{
  102. if(res.code == 200){
  103. const resData = res.data || [];
  104. state.deptTreeData = getDeptTreeData(resData);
  105. CurrentTreeData();
  106. }
  107. })
  108. }
  109. //查询本学校下的当前学年的所有学科、年级、权限数据及下的人
  110. const GetCollectPersonalInfo = async () => {
  111. const res = await findCollectPersonalInfo(schoolYearId.value);
  112. const { collectGradePersonVos, collectPermissionPersonVos, subjectPersonVoList } = res.data;
  113. state.gradeTreeList = gradTreeData(collectGradePersonVos);
  114. state.permissionTreeList = permTreeData(collectPermissionPersonVos);
  115. state.subjectTreeList = subjectTreeData(subjectPersonVoList);
  116. CurrentTreeData();
  117. }
  118. const CommonFilterData = (filterOptions,type) => {
  119. if(type=='tabBtns' && pageType.value == 'add'){
  120. targetType.value = filterOptions.tabBtnSelected;
  121. CurrentTreeData();
  122. }
  123. }
  124. const CurrentTreeData = () => {
  125. // 1-按部门,2-按学科,3-按年级,4-按权限,5-按学生
  126. if(targetType.value == 1){
  127. state.treeData = [...state.deptTreeData];
  128. }else if(targetType.value == 2){
  129. state.treeData = [...state.subjectTreeList];
  130. }else if(targetType.value == 3){
  131. state.treeData = state.gradeTreeList;
  132. }else if(targetType.value == 4){
  133. state.treeData = state.permissionTreeList;
  134. }else{
  135. state.treeData = [];
  136. }
  137. }
  138. //选择的值
  139. const HandleCheckChange = ({keys,node,nodes,value}) => {
  140. // 不可取消的节点 key 列表
  141. const lockedKeys = state.checkedDisabled.map(el=>el.id)
  142. const merged = [...new Set([...keys, ...lockedKeys])];//去重
  143. state.defaultCheckedKeys = merged;
  144. const nodesList = nodes.filter(item => item.isLeaf).map(el => ({ ...el.source }));
  145. //去重
  146. state.checkedValue = [...new Map([...nodesList, ...state.checkedDisabled].map(item => [item.id, item])).values()];
  147. }
  148. //保存选择值
  149. const SaveCheckedTreeData = () => {
  150. if(state.checkedValue.length == 0){
  151. uni.showToast({
  152. title: '请选择采集对象!',
  153. icon: 'none'
  154. })
  155. return false
  156. }
  157. uni.setStorageSync('taskTargetsTreeData',{
  158. targetType:targetType.value,
  159. taskTargets:state.checkedValue//采集对象
  160. });//返回上一页并传值
  161. GoBack()
  162. }
  163. //返回
  164. const GoBack = () => {
  165. uni.navigateBack({
  166. delta: 1
  167. });
  168. }
  169. </script>
  170. <style scoped lang="scss">
  171. :deep(.item_width){
  172. .scroll_tab_btn{
  173. .tab_item{
  174. width: 122rpx;
  175. flex: 0;
  176. }
  177. }
  178. }
  179. :deep(.scroll_tab_btn){
  180. margin-top: 24rpx;
  181. .tab_item{
  182. &.selected{
  183. background-color: #2E64FA;
  184. color: #FFFFFF;
  185. }
  186. }
  187. }
  188. .page_body{
  189. display: flex;
  190. flex-direction: column;
  191. height: 100%;
  192. min-width: auto;
  193. .row_search_box{
  194. height: 96rpx;
  195. align-items: flex-start;
  196. }
  197. .tree_node{
  198. display: flex;
  199. width: 100%;
  200. padding: 0 24rpx;
  201. box-sizing: border-box;
  202. flex:1;
  203. overflow: auto;
  204. :deep(.utv-tree-item__arrow-icon){
  205. display: none;
  206. }
  207. }
  208. .foot_btn{
  209. width: 100%;
  210. padding: 40rpx 24rpx;
  211. flex-shrink: 0;
  212. box-sizing: border-box;
  213. .btn_submit{
  214. background-color: #2E64FA;
  215. border-radius: 8rpx;
  216. width: 100%;
  217. height: 90rpx;
  218. font-weight: 500;
  219. font-size: 28rpx;
  220. color: #FFFFFF;
  221. display: flex;
  222. align-items: center;
  223. justify-content: center;
  224. }
  225. }
  226. }
  227. </style>