useOptions.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. import { reactive, computed, watch, ref, unref, isRef, nextTick } from 'vue'
  2. import useFetch from '@/hooks/useFetch'
  3. import useMainStore from '@/store/main'
  4. import { ExtractApiResponse } from '@/api/api'
  5. import { useRoute } from 'vue-router'
  6. import type { Ref } from 'vue'
  7. export interface DataModel {
  8. subject?: string
  9. question?: number | string
  10. group?: any
  11. }
  12. interface Group {
  13. label: string
  14. value: any
  15. }
  16. type QuestionList = ExtractApiResponse<'getMainQuestionList'>[0] & {
  17. label: string
  18. value: number
  19. }
  20. const useOptions = (
  21. types: (keyof DataModel)[],
  22. initModel?: DataModel | Ref<DataModel>,
  23. autoFill = true,
  24. subjectEnable: boolean | null = true,
  25. multGroup = false,
  26. isAiCheck = false,
  27. showAllLabel = true
  28. ) => {
  29. const mainStore = useMainStore()
  30. const route = useRoute()
  31. const _subjectCode = (route.query?._subjectCode || '') as string
  32. const _questionMainNumber = Number(route.query?._questionMainNumber || '')
  33. const userInfo = computed(() => {
  34. return mainStore?.myUserInfo
  35. })
  36. const isAdmin = computed(() => {
  37. return userInfo?.value?.role === 'ADMIN'
  38. })
  39. const isChief = computed(() => {
  40. return userInfo?.value?.role === 'CHIEF'
  41. })
  42. const isExpert = computed(() => {
  43. return userInfo?.value?.role === 'EXPERT'
  44. })
  45. const isLeader = computed(() => {
  46. return userInfo?.value?.role === 'SECTION_LEADER'
  47. })
  48. const isDeputy = computed(() => {
  49. return userInfo?.value?.role === 'DEPUTY'
  50. })
  51. const dataModel = reactive<DataModel>(unref(initModel) || {})
  52. if (isRef(initModel)) {
  53. watch(
  54. initModel,
  55. () => {
  56. Object.assign(dataModel, unref(initModel))
  57. },
  58. { deep: true }
  59. )
  60. }
  61. const changeModelValue = <T extends keyof DataModel>(key: T) => {
  62. return (v: DataModel[T]) => {
  63. // dataModel[key] = v
  64. if (multGroup && showAllLabel && key === 'group') {
  65. if (v.includes(undefined)) {
  66. if (dataModel[key]?.length === groupListWithAll.value.length) {
  67. //说明了原本是全选状态,取消勾选了某个不是“全部”的选项
  68. dataModel[key] = v.filter((item: any) => !!item)
  69. } else {
  70. //说明原本是非全选状态,而点击后包含了“全部”选项, 那么就触发全部勾选逻辑
  71. dataModel[key] = groupListWithAll.value.map((item: any) => item.value)
  72. }
  73. } else {
  74. if (v?.length === groupListWithAll.value.length - 1 && dataModel[key]?.includes(undefined)) {
  75. //说明在全部勾选的情况下,点了“全部”,则要全部取消勾选;
  76. dataModel[key] = []
  77. } else if (v?.length === groupListWithAll.value.length - 1) {
  78. //说明了在没有点击“全部”的情况下,逐步勾选完了除了“全部”以外的所有选项,那么就要出发全部勾选逻辑,同时给“全部”自动加上勾选
  79. dataModel[key] = groupListWithAll.value.map((item: any) => item.value)
  80. } else {
  81. dataModel[key] = v.filter((item: any) => !!item)
  82. }
  83. }
  84. } else {
  85. dataModel[key] = v
  86. }
  87. }
  88. }
  89. const { fetch: getSubjectList, result: subjectResult } = useFetch('getSubjectList')
  90. const {
  91. fetch: getMainQuestionList,
  92. result: mainQuestionListResult,
  93. reset: resetQuestionFetch,
  94. } = useFetch('getMainQuestionList')
  95. const {
  96. fetch: getQuestionGroupList,
  97. result: groupListResult,
  98. reset: resetGroupList,
  99. } = useFetch('getQuestionGroupList')
  100. const subjectList = computed(() => {
  101. // const arr: any =
  102. // subjectResult.value?.result?.map((subject) => {
  103. // return { ...subject, value: subject.code, label: `${subject.code}-${subject.name}` }
  104. // }) || []
  105. // if (isExpert.value) {
  106. // arr.unshift({ label: '全部', value: void 0 })
  107. // }
  108. // return arr
  109. return (
  110. subjectResult.value?.result?.map((subject) => {
  111. return { ...subject, value: subject.code, label: `${subject.code}-${subject.name}` }
  112. }) || []
  113. )
  114. })
  115. const mainQuestionList = computed<any[]>(() => {
  116. // const arr =
  117. // mainQuestionListResult.value?.map((v: any) => {
  118. // return {
  119. // ...v,
  120. // label: `${v.mainNumber}-${v.title}`,
  121. // value: v.mainNumber,
  122. // }
  123. // }) || []
  124. // if (isExpert.value || isLeader.value) {
  125. // arr.unshift({ label: '全部', value: void 0 })
  126. // }
  127. // return arr
  128. return (
  129. mainQuestionListResult.value?.map((v: any) => {
  130. return {
  131. ...v,
  132. label: `${v.mainNumber}-${v.title}`,
  133. value: v.mainNumber,
  134. }
  135. }) || []
  136. ).filter((v: any) => {
  137. if (isAiCheck) {
  138. return !!v.relationMainNumber
  139. } else {
  140. return v
  141. }
  142. })
  143. })
  144. const groupList = computed<Group[]>(() => {
  145. return dataModel.question
  146. ? groupListResult?.value?.map((n) => {
  147. return {
  148. value: n,
  149. label: `第${n}组`,
  150. }
  151. }) || []
  152. : []
  153. })
  154. const groupListWithAll = computed(() => {
  155. return groupList.value?.length &&
  156. (isAdmin.value || isChief.value || isExpert.value || isLeader.value) &&
  157. showAllLabel
  158. ? [{ label: '全部', value: void 0 } as unknown as Group].concat(groupList.value)
  159. : groupList.value
  160. })
  161. watch(
  162. userInfo,
  163. () => {
  164. if (!dataModel.subject && userInfo.value?.subjectCode) {
  165. dataModel.subject = userInfo.value.subjectCode
  166. }
  167. if (!dataModel.question && userInfo.value?.mainNumber) {
  168. dataModel.question = userInfo.value.mainNumber
  169. }
  170. if (!dataModel.group && userInfo.value?.markingGroupNumber && !(isAdmin.value || isChief.value)) {
  171. dataModel.group = multGroup
  172. ? userInfo.value.markingGroupNumber
  173. ? [userInfo.value.markingGroupNumber]
  174. : []
  175. : userInfo.value.markingGroupNumber
  176. }
  177. },
  178. { immediate: true }
  179. )
  180. watch(
  181. () => dataModel.subject,
  182. () => {
  183. if (types.includes('question') && dataModel.subject) {
  184. // resetQuestionFetch()
  185. // resetGroupList()
  186. // changeModelValue('question')(void 0)
  187. // changeModelValue('group')(void 0)
  188. getMainQuestionList({ subjectCode: dataModel.subject })
  189. // dataModel.question = undefined
  190. }
  191. },
  192. { immediate: true }
  193. )
  194. const watchQuestionHandle = () => {
  195. if (types.includes('group') && dataModel.subject && dataModel.question) {
  196. // resetGroupList()
  197. // changeModelValue('group')(void 0)
  198. getQuestionGroupList({ subjectCode: dataModel.subject, mainNumber: dataModel.question }).then((res: any) => {
  199. changeModelValue('group')(
  200. multGroup && showAllLabel
  201. ? // ? groupList.value?.length && (isAdmin.value || isChief.value || isExpert.value || isLeader.value)
  202. // ? // ? [void 0]
  203. // []
  204. // : []
  205. // : void 0
  206. userInfo.value?.markingGroupNumber
  207. ? [userInfo.value?.markingGroupNumber]
  208. : []
  209. : userInfo.value?.markingGroupNumber
  210. )
  211. })
  212. }
  213. }
  214. watch(
  215. // [() => dataModel.question, () => dataModel.question],
  216. () => dataModel.question,
  217. () => {
  218. watchQuestionHandle()
  219. },
  220. { immediate: true }
  221. )
  222. if (autoFill) {
  223. watch(
  224. [subjectList, userInfo],
  225. () => {
  226. if (userInfo.value?.subjectCode && !dataModel.subject) {
  227. changeModelValue('subject')(userInfo.value?.subjectCode)
  228. }
  229. //如果是专家进来,则用户信息里的subjectCode是没值的,这种情况,给专家默认选择科目列表里的第一个科目
  230. if (userInfo.value?.role === 'EXPERT' && !userInfo.value?.subjectCode) {
  231. if (subjectList.value.length) {
  232. changeModelValue('subject')(_subjectCode || subjectList.value[0].value)
  233. }
  234. }
  235. },
  236. { deep: true }
  237. )
  238. watch(
  239. [mainQuestionList, userInfo],
  240. () => {
  241. if (userInfo.value?.mainNumber && !dataModel.question) {
  242. changeModelValue('question')(userInfo.value?.mainNumber)
  243. }
  244. if (
  245. (userInfo.value?.role === 'EXPERT' ||
  246. userInfo.value?.role === 'SECTION_LEADER' ||
  247. userInfo.value?.role === 'ADMIN') &&
  248. !userInfo.value?.mainNumber
  249. ) {
  250. if (mainQuestionList.value.length) {
  251. const oldQuestionNumber = dataModel.question
  252. changeModelValue('question')(_questionMainNumber || mainQuestionList.value[0].value)
  253. if (oldQuestionNumber == mainQuestionList.value[0].value) {
  254. //防止切换科目前的大题号和切换科目后的大题号相同,watch question监听不执行
  255. watchQuestionHandle()
  256. }
  257. }
  258. }
  259. },
  260. { deep: true }
  261. )
  262. watch(
  263. [groupList, userInfo, isAdmin, isChief],
  264. () => {
  265. if (userInfo.value?.markingGroupNumber && !dataModel.question && !(isAdmin.value || isChief.value)) {
  266. changeModelValue('group')(
  267. multGroup
  268. ? userInfo.value?.markingGroupNumber
  269. ? [userInfo.value?.markingGroupNumber]
  270. : []
  271. : userInfo.value?.markingGroupNumber
  272. )
  273. }
  274. },
  275. { deep: true }
  276. )
  277. }
  278. const initFinish = ref<boolean>(false)
  279. const destroyInit = watch(
  280. [dataModel, isAdmin, isChief],
  281. () => {
  282. if (
  283. types.every((t) => {
  284. return (
  285. (Array.isArray(dataModel[t]) ? dataModel[t].length > 0 : !!dataModel[t]) ||
  286. (t === 'group' && (isAdmin.value || isChief.value || isExpert.value || isLeader.value))
  287. )
  288. })
  289. ) {
  290. nextTick(() => {
  291. initCallbacks.forEach((cb) => cb(dataModel))
  292. initFinish.value = true
  293. destroyInit()
  294. })
  295. }
  296. },
  297. { immediate: true }
  298. )
  299. const initCallbacks: ((d: DataModel) => void)[] = []
  300. const onOptionInit = (cb: (d?: DataModel) => void) => {
  301. initCallbacks.push(cb)
  302. }
  303. const forceRefresh = () => {
  304. getSubjectList({ pageNumber: 1, pageSize: 9999, enable: subjectEnable || void 0 })
  305. }
  306. if (types.includes('subject')) {
  307. forceRefresh()
  308. }
  309. return {
  310. getMainQuestionList,
  311. getQuestionGroupList,
  312. subjectList,
  313. mainQuestionList,
  314. groupList,
  315. groupListWithAll,
  316. dataModel,
  317. initFinish,
  318. onOptionInit,
  319. changeModelValue,
  320. forceRefresh,
  321. isExpert,
  322. isLeader,
  323. isDeputy,
  324. isAdmin,
  325. }
  326. }
  327. export default useOptions