cascader.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <template>
  2. <div class="cascader">
  3. <div class="title" @click="showBox">{{ checkArray.length ? setCheckName(checkArray) : '点击选择教研室范围' }}</div>
  4. <div class="box" v-if="show" v-loading="loading">
  5. <div class="inputBox">
  6. <input v-model="searchTerm" placeholder="输入教师名字搜索" />
  7. <i class="search" @click="searchTeacher"></i>
  8. </div>
  9. <div class="options">
  10. <div v-if="filteredOptions.length" class="ul">
  11. <div @click="selectOption(option)" v-for="(option, index) in filteredOptions" :key="index"
  12. class="li" :class="{ active: checkF === option.id }">
  13. <span>{{ option.name }}</span>
  14. </div>
  15. </div>
  16. <div v-if="children.length" class="ul">
  17. <div v-for="(option, index) in children" :key="index" class="li" @click="selectOption2(option)"
  18. :class="{ active: checkF2 === option.id }">
  19. <span>{{ option.name }}</span>
  20. </div>
  21. </div>
  22. <div v-else-if="checkF" class="ul">
  23. <div class="liNone">无子分类</div>
  24. </div>
  25. <div v-if="teacher.length" class="ul">
  26. <div class="li" @click="checkAll()"
  27. :class="{ active: panCheckAll === 1 }"><span>全部</span> </div>
  28. <div v-for="(teacher, index) in teacher" :key="index" class="li" @click="selectOption3(teacher)"
  29. :class="{ active: checkTeacher(teacher) === 2 }">
  30. <span>{{ teacher.name }}</span>
  31. </div>
  32. </div>
  33. <div v-else-if="checkF2" class="ul">
  34. <div class="liNone">暂无教师</div>
  35. </div>
  36. </div>
  37. <div class="button">
  38. <el-button size="small" @click="reset">重置</el-button>
  39. <el-button type="primary" size="small" @click="confirm">确认</el-button>
  40. </div>
  41. </div>
  42. </div>
  43. </template>
  44. <script>
  45. export default {
  46. name: 'Cascader',
  47. props: {
  48. options: {
  49. type: Array,
  50. required: true
  51. }
  52. },
  53. data() {
  54. return {
  55. searchTerm: '',
  56. filteredOptions: this.options,
  57. checkF: "",
  58. checkF2: "",
  59. children: [],
  60. teacher: [],
  61. loading: false,
  62. show: false,
  63. checkArray: [],
  64. checkArray2: []
  65. };
  66. },
  67. computed: {
  68. setCheckName() {
  69. return function (arr) {
  70. let content = ''
  71. if(arr.length < 3){
  72. content = arr.map((item) => item.name).join(" 、 ");
  73. }else {
  74. content = arr.slice(0, 2).map((item) => item.name).join(" 、 ") + "...共"+arr.length+"位老师";
  75. }
  76. return content;
  77. };
  78. },
  79. checkTeacher() {
  80. return function (teacher) {
  81. let a = 1
  82. this.checkArray2.forEach(element => {
  83. if (element.userid == teacher.userid) {
  84. a = 2
  85. }
  86. });
  87. return a
  88. };
  89. },
  90. panCheckAll(){
  91. if(this.teacher.length && this.checkArray2.length){
  92. let userid = this.checkArray2.map((item) => item.userid)
  93. let userid2 = this.teacher.map((item) => item.userid)
  94. let userid3 = this.arrayToArray(userid, userid2)
  95. if(userid2.length == userid3.length){
  96. return 1
  97. }else{
  98. return 2
  99. }
  100. }else{
  101. return 2
  102. }
  103. }
  104. },
  105. methods: {
  106. showBox(){
  107. if(this.show){
  108. this.reset()
  109. }else{
  110. this.checkArray2 = JSON.parse(JSON.stringify(this.checkArray));
  111. }
  112. this.show = !this.show
  113. },
  114. arrayToArray(arrayo, arrayt) {
  115. let array1 = arrayo;
  116. let array2 = arrayt;
  117. let commonElements = [];
  118. for (let i = 0; i < array1.length; i++) {
  119. for (let j = 0; j < array2.length; j++) {
  120. if (array1[i] === array2[j]) {
  121. commonElements.push(array1[i]);
  122. }
  123. }
  124. }
  125. return commonElements;
  126. },
  127. reset() {
  128. this.checkArray2 = []
  129. this.checkF = ''
  130. this.checkF2 = ''
  131. this.teacher = [],
  132. this.children = []
  133. },
  134. confirm() {
  135. this.checkArray = JSON.parse(JSON.stringify(this.checkArray2));
  136. let array = this.checkArray.map(item => item.userid)
  137. this.$emit('setTeacher', array)
  138. this.show = false
  139. },
  140. selectOption(option) {
  141. console.log(option);
  142. this.checkF2 = '';
  143. this.teacher = []
  144. this.checkF = option.id;
  145. this.children = option.child;
  146. this.$forceUpdate();
  147. },
  148. selectOption2(option) {
  149. this.checkF2 = option.id;
  150. this.teacher = []
  151. this.loading = true
  152. let params = {
  153. cid: option.id,
  154. name: this.searchTerm,
  155. userid: this.$route.query.userid
  156. };
  157. this.ajax
  158. .get(this.$store.state.api + "getTypeTeacher", params)
  159. .then((res) => {
  160. this.teacher = res.data[0];
  161. this.loading = false
  162. })
  163. .catch((err) => {
  164. this.loading = false;
  165. console.error(err);
  166. });
  167. },
  168. searchTeacher() {
  169. if(!this.checkF2){
  170. this.$message.error('请先选择子分类');
  171. }
  172. this.teacher = []
  173. this.loading = true
  174. let params = {
  175. cid: this.checkF2,
  176. name: this.searchTerm,
  177. userid: this.$route.query.userid
  178. };
  179. this.ajax
  180. .get(this.$store.state.api + "getTypeTeacher", params)
  181. .then((res) => {
  182. this.teacher = res.data[0];
  183. this.loading = false
  184. })
  185. .catch((err) => {
  186. this.loading = false;
  187. console.error(err);
  188. });
  189. },
  190. selectOption3(teacher){
  191. if(this.checkTeacher(teacher) == 1){
  192. this.checkArray2.push(teacher)
  193. }else {
  194. this.checkArray2 = this.checkArray2.filter(item => item.userid != teacher.userid)
  195. }
  196. },
  197. checkAll(){
  198. let userid = this.checkArray2.map((item) => item.userid)
  199. let userid2 = this.teacher.map((item) => item.userid)
  200. if(this.panCheckAll == 1){
  201. this.checkArray2 = this.checkArray2.filter(item => !userid2.includes(item.userid))
  202. }else{
  203. let userAarray = this.arrayToArray(userid, userid2)
  204. let teacher = this.teacher.filter(item => !userAarray.includes(item.userid))
  205. teacher.forEach(item => {
  206. this.checkArray2.push(item)
  207. })
  208. }
  209. },
  210. }
  211. };
  212. </script>
  213. <style scoped>
  214. .cascader {
  215. position: relative;
  216. }
  217. .cascader>.title {
  218. min-width: 300px;
  219. background: #fff;
  220. border-radius: 5px;
  221. height: 30px;
  222. display: flex;
  223. align-items: center;
  224. padding: 0 10px;
  225. box-sizing: border-box;
  226. cursor: pointer;
  227. color: #00000066;
  228. }
  229. .box {
  230. position: absolute;
  231. z-index: 999;
  232. border-radius: 5px;
  233. overflow: hidden;
  234. background: #fff;
  235. box-shadow: 0 0 3px 2px #0000002b;
  236. }
  237. .inputBox {
  238. padding: 5px 8px;
  239. border-bottom: 1px solid #c4c4c4;
  240. display: flex;
  241. box-sizing: border-box;
  242. width: 100%;
  243. align-items: center;
  244. position: relative
  245. }
  246. .inputBox>input {
  247. width: 100%;
  248. background: #fff;
  249. border-radius: 5px;
  250. height: 30px;
  251. padding: 0 10px;
  252. border: 1px solid #c4c4c4;
  253. outline: none;
  254. }
  255. .inputBox>.search {
  256. position: absolute;
  257. right: 20px;
  258. top: 50%;
  259. transform: translateY(-50%);
  260. width: 13px;
  261. height: 13px;
  262. background: url("../../../../assets/icon/test/test_search.png") no-repeat;
  263. background-size: 100% 100%;
  264. cursor: pointer;
  265. }
  266. .options {
  267. height: 200px;
  268. display: flex;
  269. }
  270. .options>.ul {
  271. height: 100%;
  272. overflow-y: auto;
  273. list-style: none;
  274. padding: 0;
  275. width: 135px;
  276. border-right: 1px solid #c4c4c4;
  277. /* width: 100%; */
  278. text-align: center;
  279. }
  280. .options>.ul:nth-child(3) {
  281. border-right: none;
  282. }
  283. .options>.ul>.li.active,
  284. .options>.ul>.li:hover {
  285. color: #3681FC;
  286. }
  287. .options>.ul>.li,
  288. .options>.ul>.liNone {
  289. cursor: pointer;
  290. padding: 10px 8px;
  291. max-width: 100%;
  292. overflow: hidden;
  293. text-overflow: ellipsis;
  294. white-space: nowrap;
  295. }
  296. .button {
  297. padding: 5px 8px;
  298. border-top: 1px solid #c4c4c4;
  299. display: flex;
  300. justify-content: flex-end;
  301. box-sizing: border-box;
  302. width: 100%;
  303. }
  304. </style>