report-table.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <template>
  2. <div>
  3. <div class="mb10 fx-row fx-end-base">
  4. <div v-if="!readonly">
  5. <el-button v-if="aiButtonShow" type="primary" @click="toAiAnalysis">AI分析</el-button>
  6. <el-button>选科历史记录</el-button>
  7. </div>
  8. </div>
  9. <mx-table :propDefines="formatCols" :rows="formatRows">
  10. <template #underOver="{value}">
  11. <over-under-badge :value="value"></over-under-badge>
  12. </template>
  13. <template #temp="{row}">
  14. <span class="btn-blue mr5" @click="toSelectSub(row)">选择</span>
  15. <span class="btn-green" @click="toReport">查看记录</span>
  16. <!-- <el-button>查看</el-button>-->
  17. </template>
  18. <template #signUp="{row}">
  19. <span class="f-red" v-if="!row.allowSelect">无法报名</span>
  20. <div v-else>
  21. <span v-if="generation.current > 1">可报名</span>
  22. <div v-else>
  23. <span class="f-red btn-red" v-if="row.selected" @click="toUnSelect(row)">取消报名</span>
  24. <span class="btn-green" v-else @click="toSelect(row)">报名</span>
  25. </div>
  26. </div>
  27. </template>
  28. <template #subjects="{row}">
  29. <el-row>
  30. <el-col :span="8" v-for="subject in row.subjects">
  31. <el-popover
  32. placement="top"
  33. popper-class="zero-padding-popover"
  34. trigger="hover"
  35. >
  36. <div class="fx-column">
  37. <el-button plain type="text">{{ subject }}</el-button>
  38. </div>
  39. <el-tag type="success" slot="reference" class="mr10 mb10">{{ subject[0] }}</el-tag>
  40. </el-popover>
  41. </el-col>
  42. </el-row>
  43. </template>
  44. <template #colleges="{row}">
  45. <el-row>
  46. <el-col :span="12" v-for="college in row.colleges">
  47. <el-tag type="success" class="mb10">{{ college.major[0] }}</el-tag>
  48. :
  49. <span>{{ college.college }}</span>
  50. </el-col>
  51. </el-row>
  52. </template>
  53. </mx-table>
  54. <!-- 初录 多志愿拖拽 -->
  55. <div v-if="this.generation.current == 1">
  56. <p>您的选科志愿: <span v-for="(item,index) in selectedList">
  57. {{ item.groupName }}{{ index + 1 < selectedList.length ? '、' : '' }}</span>
  58. </p>
  59. <test-drage ref="drage" :sortList="selectedList"></test-drage>
  60. <el-button @click="commit" type="primary">提交</el-button>
  61. </div>
  62. <!-- 补录报名和二次补录报名和调剂报名 -->
  63. <div v-if="flagShow">
  64. <div v-for="item in singleList" class="mb5 mt5">
  65. <el-button @click="commit" type="primary">{{ `${item.groupName} : 报名` }}</el-button>
  66. </div>
  67. <div class="mb5 mt5">
  68. <el-popover
  69. placement="right"
  70. width="300"
  71. v-model="popoShow"
  72. trigger="click"
  73. >
  74. <div>
  75. <el-input
  76. type="textarea"
  77. :rows="4"
  78. placeholder="请输入原因"
  79. v-model="regInfo"
  80. >
  81. </el-input>
  82. <p class="fx-row jc-between mt10">
  83. <el-button type="primary" size="mini" @click="popoShow = false">取消</el-button>
  84. <el-button type="danger" size="mini">提交</el-button>
  85. </p>
  86. </div>
  87. <el-button slot="reference" type="danger">不同意</el-button>
  88. </el-popover>
  89. </div>
  90. {{ resolveDynamicTable }}
  91. </div>
  92. <esign-dialog ref="esignDialog"></esign-dialog>
  93. <choose-subject-dialog ref="chooseDialog"></choose-subject-dialog>
  94. <select-subject-report-dialog ref="reportDialog"></select-subject-report-dialog>
  95. <Ai-dialog ref="aiDialog" :generation="generation" :prevPreferences="prevPreferences"></Ai-dialog>
  96. </div>
  97. </template>
  98. <script>
  99. import AiDialog from './ai-analysis-dialog'
  100. import MxSelectTranslate from '@/components/Cache/modules/mx-select-translate-mixin.js'
  101. import TestDrage from './test-drage'
  102. import ChooseSubjectDialog from './choose-subject-dialog'
  103. import SelectSubjectReportDialog from '@/views/system/user/profile/components/select-subject-report-dialog'
  104. import EsignDialog from '@/views/system/user/profile/components/esign-dialog'
  105. import ReportStep from './report-step'
  106. import PrimaryResolverMixins
  107. from '@/views/system/user/profile/components/round-select-resolvers/primary-resolver-mixins'
  108. import PrimaryDMResolverMixins
  109. from '@/views/system/user/profile/components/round-select-resolvers/primaryDM-resolver-mixins'
  110. import BackTrackingResolverMixins
  111. from '@/views/system/user/profile/components/round-select-resolvers/backTracking-resolver-mixins'
  112. import BackTrackingDMResolverMixins
  113. from '@/views/system/user/profile/components/round-select-resolvers/backTrackingDM-resolver-mixins'
  114. import FinalAdjustResolverMixins
  115. from '@/views/system/user/profile/components/round-select-resolvers/finalAdjust-resolver-mixins'
  116. import FinalAdjustDMResolverMixins
  117. from '@/views/system/user/profile/components/round-select-resolvers/finalAdjustDM-resolver-mixins'
  118. import ForceAdjustResolverMixins
  119. from '@/views/system/user/profile/components/round-select-resolvers/forceAdjust-resolver-mixins'
  120. import OverUnderBadge from '@/views/elective/publish/components/steps/fauclty/over-under-badge'
  121. export default {
  122. props: {
  123. generation: Object,
  124. readonly: Boolean, // 校长端不允许操作
  125. optionalMajors: { type: Array, default: () => [] }
  126. },
  127. components: {
  128. OverUnderBadge,
  129. SelectSubjectReportDialog,
  130. ReportStep,
  131. EsignDialog,
  132. TestDrage,
  133. ChooseSubjectDialog,
  134. AiDialog
  135. },
  136. mixins: [
  137. MxSelectTranslate,
  138. PrimaryResolverMixins,
  139. PrimaryDMResolverMixins,
  140. BackTrackingResolverMixins,
  141. BackTrackingDMResolverMixins,
  142. FinalAdjustDMResolverMixins,
  143. FinalAdjustResolverMixins,
  144. ForceAdjustResolverMixins
  145. ],
  146. data() {
  147. return {
  148. popoShow: false,
  149. activeStep: '',
  150. regInfo: '',
  151. prevPreferences: [1], // 选科前一轮报名的group
  152. dialogVisible: false,
  153. selectedList: [],
  154. singleList: [], // 单志愿列表
  155. rows: []
  156. }
  157. },
  158. computed: {
  159. flagShow() {
  160. return (this.generation.current == 3 && this.generation.active == 3) ||
  161. (this.generation.current == 5 && this.generation.active == 5) ||
  162. (this.generation.current == 5 && this.generation.active == 7)
  163. },
  164. aiButtonShow() {
  165. const aiButtonShow = !this.generation.activeOpt?.decisionMaking && this.generation.activeOpt?.key != 'primary'
  166. return aiButtonShow
  167. },
  168. resolveTablePrefix() {
  169. return {
  170. index: {
  171. type: 'index',
  172. label: '编号'
  173. },
  174. groupName: {
  175. label: '选科组合'
  176. },
  177. scoreSumGroup: {
  178. label: '组合成绩'
  179. },
  180. classCount: {
  181. label: '开设班级数'
  182. },
  183. personCount: {
  184. label: '人数设置'
  185. }
  186. }
  187. },
  188. resolveTableSuffix() {
  189. const stepMatched = this.generation.active == this.generation.current
  190. const enableApply = !this.generation.currentOpt.decisionMaking
  191. const enableSignUp = stepMatched && enableApply && !this.readonly
  192. return {
  193. allowSelectTips: {
  194. label: '报名状态'
  195. },
  196. temp: {
  197. label: '选择专业',
  198. width: '140',
  199. slot: 'temp'
  200. },
  201. subjects: {
  202. label: '自选专业',
  203. slot: 'subjects',
  204. width: '150'
  205. },
  206. colleges: {
  207. label: '院校',
  208. slot: 'colleges',
  209. width: '250'
  210. },
  211. signUp: {
  212. label: '操作',
  213. slot: 'signUp',
  214. width: '100',
  215. fixed: 'right',
  216. hidden: !enableSignUp
  217. }
  218. }
  219. },
  220. resolveDynamicTable() {
  221. if (!this.formatRows) return {}
  222. const options = this.generation.options
  223. if (!options || !this.generation.active) return {}
  224. const optValues = Object.values(options)
  225. const dynamicColumns = {}
  226. for (let gen = options.primary.value; gen <= this.generation.active; gen++) {
  227. const opt = optValues.find(opt => opt.value == gen)
  228. const resolverKey = opt.key + 'Resolver'
  229. const resolver = this[resolverKey]
  230. if (typeof resolver === 'function') {
  231. const genColumns = resolver(gen, this.generation.active)
  232. Object.assign(dynamicColumns, genColumns)
  233. }
  234. }
  235. return dynamicColumns
  236. },
  237. // 初始化 rows 填充固定数据
  238. formatRows() {
  239. if (!this.optionalMajors) return []
  240. if (!this.generation.roundGroups?.length) return []
  241. if (!this.generation.activeModels?.length) return []
  242. const generationModels = this.generation.activeModels.last()?.models || []
  243. return this.generation.roundGroups.map(rg => {
  244. const row = generationModels.find(item => item.groupId == rg.groupId) || {}
  245. row.allowSelectTips = row.allowSelect ? '报名中' : row.disabledReason || '无法报名'
  246. row.subjects = this.optionalMajors.filter(college => {
  247. if (college.matchedGroupIds.indexOf(row.groupId) != -1) return college.majorCategoryName
  248. }).map(item => item.majorCategoryName)
  249. row.colleges = this.optionalMajors.filter(college => {
  250. if (college.matchedGroupIds.indexOf(row.groupId) != -1) return college.majorCategoryName
  251. }).map(item => {
  252. return {
  253. college: item.collegeName,
  254. major: item.majorCategoryName
  255. }
  256. })
  257. const matchedMajors = this.optionalMajors.filter(college => college.matchedGroupIds.includes(row.groupId))
  258. return {
  259. groupId: row.groupId,
  260. groupName: row.groupName,
  261. selected: row.selected,
  262. scoreSumGroup: row.scoreSumGroup,
  263. classCount: row.classCount,
  264. personCount: row.personCount,
  265. allowSelectTips: row.allowSelectTips,
  266. colleges: matchedMajors.map(m => ({ college: m.collegeName, major: m.majorCategoryName })),
  267. subjects: matchedMajors.map(m => m['majorCategoryName']),
  268. allowSelect: row.allowSelect
  269. }
  270. })
  271. },
  272. formatCols() {
  273. return {
  274. ...this.resolveTablePrefix,
  275. ...this.resolveDynamicTable,
  276. ...this.resolveTableSuffix
  277. }
  278. }
  279. },
  280. methods: {
  281. getModelsByStep() {
  282. return this.models.findIndex()
  283. },
  284. toReport() {
  285. this.$refs.reportDialog.open()
  286. },
  287. toAiAnalysis() {
  288. // AI 分析 跳转
  289. console.log(this.formatRows)
  290. this.$refs.aiDialog.open(this.formatRows)
  291. },
  292. commit() {
  293. console.log(this.selectedList)
  294. if (this.generation == 0) {
  295. const real = this.selectedList.filter(item => {
  296. return item.selected == true
  297. })
  298. if (real.length < this.preferenceCount) {
  299. this.$message.warning(`初录报名需要选择${this.preferenceCount}个志愿`)
  300. return
  301. }
  302. }
  303. this.$refs.esignDialog.open()
  304. },
  305. toSelect(row) {
  306. const preferenceCount = this.generation.status.preferenceCount
  307. const count = this.formatRows.reduce((prev, cur) => {
  308. return prev += cur.selected ? 1 : 0
  309. },0)
  310. if (count >= preferenceCount) {
  311. this.$message.warning(`最多选择${preferenceCount}个志愿`)
  312. return
  313. }
  314. row.selected = true
  315. this.selectedList.push(row)
  316. this.$refs.drage.init(this.selectedList)
  317. },
  318. toUnSelect(row) {
  319. this.$confirm(`是否解除选科组合【${row.groupName}】`, '警告', {
  320. confirmButtonText: '确定',
  321. cancelButtonText: '取消',
  322. type: 'warning'
  323. }).then(() => {
  324. row.selected = false
  325. const start = this.selectedList.indexOf(this.selectedList.find((selected) => {
  326. return selected.groupId == row.groupId
  327. }))
  328. this.selectedList.splice(start, 1)
  329. }).catch(() => {
  330. this.$message({
  331. type: 'info',
  332. message: '已取消'
  333. })
  334. })
  335. },
  336. toSelectSub(row) {
  337. // 打开选科弹窗
  338. const course0 = this.translateCourse0(row.groupId)
  339. const course1 = this.translateCourse1(row.groupId)
  340. this.$refs.chooseDialog.open(course0, course1)
  341. },
  342. initOption(optionalMajors) {
  343. console.log(optionalMajors)
  344. this.optionalMajors = optionalMajors
  345. }
  346. }
  347. }
  348. </script>
  349. <style scoped>
  350. .cell .el-tag {
  351. margin-right: 5px;
  352. }
  353. </style>