selectObjectNoDedup.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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 uniIcons from '@/uni_modules/uni-icons/components/uni-icons/uni-icons.vue';
  50. import uniEasyinput from '@/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue';
  51. import uniTreeView from '@/uni_modules/KieranYin9527-tree/components/uni-tree-view/uni-tree-view.vue';
  52. import {findDepartContainUser,findCollectPersonalInfo} from '@/reqApi/notification.js';
  53. import {getDeptTreeData,subjectTreeData,gradTreeData,permTreeData} from '@/common/common.js';
  54. import {onLoad} from '@dcloudio/uni-app';
  55. import {reactive,ref,onUnmounted,nextTick} from 'vue';
  56. const state = reactive({
  57. tabBtns:[{
  58. label:'按部门',
  59. value:1,
  60. },{
  61. label:'按学科',
  62. value:2,
  63. },{
  64. label:'按年级',
  65. value:3,
  66. },{
  67. label:'按权限',
  68. value:4,
  69. }],
  70. defaultCheckedKeys:[],//初始选中key
  71. checkedDisabled:[],
  72. checkedValue:[],//勾选的项
  73. treeData:[],
  74. deptTreeData:[],//部门tree
  75. gradeTreeList:[],//年级tree
  76. permissionTreeList:[],//权限tree
  77. subjectTreeList:[]//学科tree
  78. });
  79. const schoolYearId = ref('');//学年学期id
  80. const targetType = ref('');//采集对象 1-按部门,2-按学科,3-按年级,4-按权限,5-按学生
  81. const pageType = ref('');//添加或修改
  82. const treeRef = ref('');
  83. onLoad((option) => {
  84. schoolYearId.value = option.schoolYearId;
  85. targetType.value = Number(option.targetType);
  86. pageType.value = option.type;
  87. const taskTargetsTreeData = uni.getStorageSync('taskTargetsTreeData');
  88. const taskTargets = taskTargetsTreeData?.taskTargets || [];
  89. state.checkedValue = taskTargets;
  90. state.defaultCheckedKeys = taskTargets?.map(item=>item.id) || [];
  91. state.checkedDisabled = taskTargets.filter(item=>item.disabled && item.checked=='checked');
  92. if(pageType.value == 'add'){
  93. GetDepartContainUser();
  94. GetCollectPersonalInfo();
  95. }else{//编辑
  96. state.tabBtns = state.tabBtns.filter(item=>item.value == targetType.value);
  97. state.treeData = taskTargetsTreeData?.taskTargetsTree || [];
  98. }
  99. })
  100. //查询本学校下的当前学年的所有部门及部门下的人
  101. const GetDepartContainUser = () => {
  102. findDepartContainUser(schoolYearId.value).then(res=>{
  103. if(res.code == 200){
  104. const resData = res.data || [];
  105. state.deptTreeData = getDeptTreeData(resData);
  106. CurrentTreeData();
  107. }
  108. })
  109. }
  110. //查询本学校下的当前学年的所有学科、年级、权限数据及下的人
  111. const GetCollectPersonalInfo = async () => {
  112. const res = await findCollectPersonalInfo(schoolYearId.value);
  113. const { collectGradePersonVos, collectPermissionPersonVos, subjectPersonVoList } = res.data;
  114. state.gradeTreeList = gradTreeData(collectGradePersonVos);
  115. state.permissionTreeList = permTreeData(collectPermissionPersonVos);
  116. state.subjectTreeList = subjectTreeData(subjectPersonVoList);
  117. CurrentTreeData();
  118. }
  119. const CommonFilterData = (filterOptions,type) => {
  120. if(type=='tabBtns' && pageType.value == 'add'){
  121. targetType.value = filterOptions.tabBtnSelected;
  122. CurrentTreeData();
  123. }
  124. }
  125. const CurrentTreeData = () => {
  126. // 1-按部门,2-按学科,3-按年级,4-按权限,5-按学生
  127. if(targetType.value == 1){
  128. state.treeData = [...state.deptTreeData];
  129. }else if(targetType.value == 2){
  130. state.treeData = [...state.subjectTreeList];
  131. }else if(targetType.value == 3){
  132. state.treeData = state.gradeTreeList;
  133. }else if(targetType.value == 4){
  134. state.treeData = state.permissionTreeList;
  135. }else{
  136. state.treeData = [];
  137. }
  138. }
  139. //选择的值
  140. const HandleCheckChange = ({keys,node,nodes,value}) => {
  141. // 不可取消的节点 key 列表
  142. const lockedKeys = state.checkedDisabled.map(el=>el.id)
  143. const merged = [...new Set([...keys, ...lockedKeys])];//去重
  144. state.defaultCheckedKeys = merged;
  145. const nodesList = nodes.filter(item => item.isLeaf).map(el => ({ ...el.source }));
  146. //去重
  147. state.checkedValue = [...new Map([...nodesList, ...state.checkedDisabled].map(item => [item.id, item])).values()];
  148. }
  149. //保存选择值
  150. const SaveCheckedTreeData = () => {
  151. if(state.checkedValue.length == 0){
  152. uni.showToast({
  153. title: '请选择采集对象!',
  154. icon: 'none'
  155. })
  156. return false
  157. }
  158. uni.setStorageSync('taskTargetsTreeData',{
  159. targetType:targetType.value,
  160. taskTargets:state.checkedValue//采集对象
  161. });//返回上一页并传值
  162. GoBack()
  163. }
  164. //返回
  165. const GoBack = () => {
  166. uni.navigateBack({
  167. delta: 1
  168. });
  169. }
  170. </script>
  171. <style scoped lang="scss">
  172. :deep(.item_width){
  173. .scroll_tab_btn{
  174. .tab_item{
  175. width: 122rpx;
  176. flex: 0;
  177. }
  178. }
  179. }
  180. :deep(.scroll_tab_btn){
  181. margin-top: 24rpx;
  182. .tab_item{
  183. &.selected{
  184. background-color: #2E64FA;
  185. color: #FFFFFF;
  186. }
  187. }
  188. }
  189. .page_body{
  190. display: flex;
  191. flex-direction: column;
  192. height: 100%;
  193. min-width: auto;
  194. .row_search_box{
  195. height: 96rpx;
  196. align-items: flex-start;
  197. }
  198. .tree_node{
  199. display: flex;
  200. width: 100%;
  201. padding: 0 24rpx;
  202. box-sizing: border-box;
  203. flex:1;
  204. overflow: auto;
  205. :deep(.utv-tree-item__arrow-icon){
  206. display: none;
  207. }
  208. }
  209. .foot_btn{
  210. width: 100%;
  211. padding: 40rpx 24rpx;
  212. flex-shrink: 0;
  213. box-sizing: border-box;
  214. .btn_submit{
  215. background-color: #2E64FA;
  216. border-radius: 8rpx;
  217. width: 100%;
  218. height: 90rpx;
  219. font-weight: 500;
  220. font-size: 28rpx;
  221. color: #FFFFFF;
  222. display: flex;
  223. align-items: center;
  224. justify-content: center;
  225. }
  226. }
  227. }
  228. </style>