useOptions.ts 10 KB

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