Step4Component.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. <template>
  2. <div class="page_item end_item">
  3. <div class="page_search">
  4. <div class="search_content">
  5. <div class="content_left">
  6. <el-checkbox v-model="evaluationManageData.isGenerateAccountByGender"
  7. @change="(val)=>GenerateAccountByGenderOrNot(val)" >
  8. 按男女生成
  9. </el-checkbox>
  10. </div>
  11. <div class="content_right">
  12. <el-button class="delete_button_border_no_bg" @click="ClearReviewAccount">全部清空</el-button>
  13. <el-button class="button_border" @click="OpenBatchEditForm">批量编辑</el-button>
  14. <el-button class="button_refresh" @click="">批量导出</el-button>
  15. <el-button class="button_refresh" @click="">批量导入</el-button>
  16. <el-button class="button_background" @click="GoToGenerateCodePage">生成评价码</el-button>
  17. </div>
  18. </div>
  19. </div>
  20. <div class="page_jg_20"></div>
  21. <Table
  22. :currentPage="1" :pageSize="200"
  23. :tableColumns="tableColumns"
  24. :tableData="tableData"
  25. :totalNum="0"
  26. :hidePagination="true"
  27. >
  28. <template v-for="item in Object.values(originReviewAccount)"
  29. v-slot:[`class_${item.evaluationGradeId}`]="{row}" :key="item">
  30. {{ row[`class_${item.evaluationGradeId}`]?.className }}
  31. </template>
  32. <template v-for="item in Object.values(originReviewAccount)"
  33. v-slot:[`num_${item.evaluationGradeId}`]="{row}" :key="item">
  34. <!-- 没有班级的行不渲染 -->
  35. <el-input v-if="row[`class_${item.evaluationGradeId}`]?.classId" type="number" v-model="row[`num_${item.evaluationGradeId}`]" placeholder="请输入"/>
  36. </template>
  37. <template v-for="item in Object.values(originReviewAccount)"
  38. v-slot:[`male_${item.evaluationGradeId}`]="{row}" :key="item">
  39. <el-input v-if="row[`class_${item.evaluationGradeId}`]?.classId" type="number" v-model="row[`male_${item.evaluationGradeId}`]" placeholder="请输入"/>
  40. </template>
  41. <template v-for="item in Object.values(originReviewAccount)"
  42. v-slot:[`female_${item.evaluationGradeId}`]="{row}" :key="item">
  43. <el-input v-if="row[`class_${item.evaluationGradeId}`]?.classId" type="number" v-model="row[`female_${item.evaluationGradeId}`]" placeholder="请输入"/>
  44. </template>
  45. </Table>
  46. <FormDialog
  47. width="800px"
  48. :visible="batchEditFormVisible" :defaultFormData="{}"
  49. title="批量编辑" :submitLoading="batchEditFormLoading"
  50. @close="CloseBatchEditForm"
  51. @confirm="SaveBatchEditForm">
  52. <template #form_pre>
  53. <ul class="grade_form_item">
  54. <li v-for="grade in batchEditGradeList" :key="grade.evaluationGradeId">
  55. <div class="grade_name">{{ grade.evaluationGradeName }}</div>
  56. <div class="class_list">
  57. <el-checkbox
  58. v-model="grade.isSelectAll"
  59. :indeterminate="grade.selectedClassList?.length < grade.classList?.length && grade.selectedClassList?.length !==0 ? true : false"
  60. @change="(val)=>HandleGradeSelectAllOrNot(grade,val)"
  61. >
  62. 全选
  63. </el-checkbox>
  64. <el-checkbox
  65. v-model="grade.selectedClassList "
  66. v-for="checkItem in grade.classList"
  67. :key="checkItem.value"
  68. :label="checkItem.label"
  69. :value="checkItem.value"
  70. @change="(val)=>HandleGradeClassSelectChange(grade,val)"
  71. />
  72. </div>
  73. </li>
  74. </ul>
  75. </template>
  76. <template #footerRight="{formRef}">
  77. <div v-if="!evaluationManageData.isGenerateAccountByGender" class="batch_num">
  78. <span>数量:<el-input type="number" v-model="batchAccountNum" placeholder="请输入"/></span>
  79. </div>
  80. <div v-else class="group_batch_num">
  81. <span>男生:<el-input type="number" v-model="batchMaleNum" placeholder="请输入"/></span>
  82. <span>女生:<el-input type="number" v-model="batchFemaleNum" placeholder="请输入"/></span>
  83. </div>
  84. </template>
  85. </FormDialog>
  86. </div>
  87. </template>
  88. <script setup lang="ts">
  89. import { onMounted, inject,ref,watch } from 'vue';
  90. import { useRoute,useRouter } from 'vue-router';
  91. import Table from '@/baseComponents/Table.vue';
  92. import FormDialog from '@/baseComponents/FormDialog.vue';
  93. import {
  94. getReviewAccountListApi,
  95. } from '@/api/step4Component'
  96. import { ElMessage } from 'element-plus';
  97. const route = useRoute()
  98. const router = useRouter()
  99. // evaluationManageData.isGenerateAccountByGender // //按男女生成
  100. const evaluationManageData = inject('commonStepData')
  101. // 1. 评价账号数据 渲染 及 操作
  102. // 评价账号原始数据
  103. const originReviewAccount = ref({})
  104. // 渲染到表格中的评价账号数据
  105. const tableData = ref([]);
  106. const tableColumns = ref([])
  107. // 表头初始赋值 和 表行初始赋值 以及 批量编辑弹窗变量赋值
  108. const GetReviewAccountList = async ()=>{
  109. let params = {
  110. evaluationId: route.query.id,
  111. pageNum: 1,
  112. pageSize: 20
  113. }
  114. let res = await getReviewAccountListApi(params)
  115. if(res?.code == 200){
  116. ElMessage.success(res?.msg)
  117. let gradeMsg = res.data?.dataList || {}
  118. originReviewAccount.value = gradeMsg || {}
  119. // 批量编辑弹窗变量赋值
  120. batchEditGradeList.value = Object.values(gradeMsg).map(item=>{
  121. return {
  122. ...item,
  123. isSelectAll:false,
  124. selectedClassList:[],
  125. classList:item.classData.map(classItm=>{
  126. return {
  127. label: classItm.evaluationClassName,
  128. value: classItm.id
  129. }
  130. })
  131. }
  132. })
  133. //表头赋值
  134. tableColumns.value = Object.values(gradeMsg)?.map(grade=>{
  135. let gradeId = grade.evaluationGradeId
  136. return [
  137. {
  138. name: `grade_${gradeId}`,
  139. label: '年级',
  140. width: '80',
  141. align: 'center',
  142. custom: false,
  143. hidden: false,
  144. },
  145. {
  146. name: `class_${gradeId}`,
  147. label: '班级',
  148. width: '80',
  149. align: 'center',
  150. custom: true,
  151. hidden: false,
  152. },
  153. {
  154. name: `num_${gradeId}`,
  155. label: '数量',
  156. width: '80',
  157. align: 'center',
  158. custom: true,
  159. hidden: false,
  160. },
  161. {
  162. name: `male_${gradeId}`,
  163. label: '男生',
  164. width: '80',
  165. align: 'center',
  166. custom: true,
  167. hidden: true,
  168. },
  169. {
  170. name: `female_${gradeId}`,
  171. label: '女生',
  172. width: '80',
  173. align: 'center',
  174. custom: true,
  175. hidden: true,
  176. },
  177. ]
  178. }).flat()
  179. //初次赋值,要检查 上一次生成账号是否按男女生成
  180. ChangeHeaderShowItem(evaluationManageData.isGenerateAccountByGender)
  181. // 表行赋值
  182. Object.values(gradeMsg)?.map(grade=>{
  183. let gradeId = grade.evaluationGradeId
  184. let gradeName = grade.evaluationGradeName
  185. let classDataList = grade.classData
  186. classDataList.map((classItm,index)=>{
  187. if(typeof tableData.value[index] !== 'object'){
  188. tableData.value[index] = {}
  189. }
  190. // 当前年级下的行赋值
  191. tableData.value[index][`grade_${gradeId}`] = gradeName
  192. tableData.value[index][`class_${gradeId}`] = {
  193. className:classItm.evaluationClassName,
  194. classId:classItm.id,
  195. }
  196. tableData.value[index][`num_${gradeId}`] = classItm.evaluationCount
  197. tableData.value[index][`male_${gradeId}`] = classItm.boyCount
  198. tableData.value[index][`female_${gradeId}`] = classItm.girlCount
  199. })
  200. })
  201. }
  202. }
  203. // 切换评价账号的表头展示项 _ 根据 是否按男女生成 来判断
  204. const ChangeHeaderShowItem = (isGenerateByGender:Boolean)=>{
  205. if(isGenerateByGender){
  206. // 打开
  207. tableColumns.value = tableColumns.value.map(item=>{
  208. if(item?.name.startsWith('num_')){
  209. item.hidden = true
  210. }else if(item?.name.startsWith('male_') || item?.name.startsWith('female_')){
  211. item.hidden = false
  212. }
  213. return item
  214. })
  215. }else{
  216. // 关闭
  217. tableColumns.value = tableColumns.value.map(item=>{
  218. if(item?.name.startsWith('num_')){
  219. item.hidden = false
  220. }else if(item?.name.startsWith('male_') || item?.name.startsWith('female_')){
  221. item.hidden = true
  222. }
  223. return item
  224. })
  225. }
  226. }
  227. watch(()=>evaluationManageData.isGenerateAccountByGender,(val)=>{
  228. ChangeHeaderShowItem(val)
  229. })
  230. // 2. 批量编辑弹窗操作
  231. const batchEditFormVisible = ref(false)
  232. const batchEditFormLoading = ref(false)
  233. const batchAccountNum = ref() //批量的所有数据
  234. const batchFemaleNum = ref() //批量的女性数据
  235. const batchMaleNum = ref() //批量的男性数据
  236. interface batchEditGradeItm {
  237. evaluationGradeName: string,
  238. evaluationGradeId: string,
  239. classList: {label: string, value: string }[],
  240. selectedClassList:string[],
  241. isSelectAll:boolean,
  242. }
  243. // 批量编辑 弹窗数据
  244. const batchEditGradeList = ref<batchEditGradeItm[]>([]);
  245. // 关闭批量编辑弹窗
  246. const CloseBatchEditForm = ()=>{
  247. batchEditFormVisible.value = false
  248. batchAccountNum.value = null
  249. batchMaleNum.value = null
  250. batchFemaleNum.value = null
  251. // 清除 批量弹窗编辑 的批量选中数据
  252. batchEditGradeList.value = batchEditGradeList.value.map(item=>{
  253. return {
  254. ...item,
  255. selectedClassList:[],
  256. isSelectAll:false
  257. }
  258. })
  259. }
  260. // 打开批量编辑弹窗
  261. const OpenBatchEditForm = ()=>{
  262. batchEditFormVisible.value = true
  263. }
  264. // 保存批量编辑配置 ——
  265. const SaveBatchEditForm = (params:any)=>{
  266. const batchData = batchEditGradeList.value.map(item=>{
  267. return {
  268. gradeName: item.evaluationGradeName,
  269. gradeId: item.evaluationGradeId,
  270. selectedClassList:item.selectedClassList
  271. }
  272. })?.filter(item=>{return item.selectedClassList?.length > 0})
  273. // 选中的值赋值
  274. batchEditGradeList.value.map(grade=>{
  275. let gradeId = grade.evaluationGradeId
  276. let classDataList = grade.classData
  277. let changeAim = batchData.find(itm=>itm.gradeId == gradeId)
  278. // 有需要批量修改的 年级
  279. if(changeAim){
  280. classDataList.map((classItm,index)=>{
  281. // 有需要批量修改的 班级
  282. if(changeAim.selectedClassList.find(classId=>classId == classItm.id )){
  283. if(typeof tableData.value[index] !== 'object'){
  284. tableData.value[index] = {}
  285. }
  286. // 当前年级下 某个班级 的行赋值
  287. if(evaluationManageData.isGenerateAccountByGender){
  288. // 按男女生成
  289. tableData.value[index][`num_${gradeId}`] = Number(batchMaleNum.value) + Number(batchFemaleNum.value)
  290. tableData.value[index][`male_${gradeId}`] = batchMaleNum.value
  291. tableData.value[index][`female_${gradeId}`] = batchFemaleNum.value
  292. }else{
  293. // 按总人数生成
  294. tableData.value[index][`num_${gradeId}`] = batchAccountNum.value
  295. tableData.value[index][`male_${gradeId}`] = Math.floor(batchAccountNum.value / 2)
  296. tableData.value[index][`female_${gradeId}`] = Math.ceil(batchAccountNum.value / 2)
  297. }
  298. }
  299. })
  300. }
  301. })
  302. CloseBatchEditForm()
  303. }
  304. // 年级全选/全不选
  305. const HandleGradeSelectAllOrNot = (grade,val)=>{
  306. if(val){
  307. // 全选
  308. batchEditGradeList.value = batchEditGradeList.value.map(item=>{
  309. if(item.evaluationGradeId == grade.evaluationGradeId){
  310. item.selectedClassList = item.classList.map(classItm=>{
  311. return classItm.value
  312. })
  313. }
  314. return item
  315. })
  316. }else{{
  317. // 全不选
  318. batchEditGradeList.value = batchEditGradeList.value.map(item=>{
  319. if(item.evaluationGradeId == grade.evaluationGradeId){
  320. item.selectedClassList = []
  321. }
  322. return item
  323. })
  324. }}
  325. }
  326. // 年级下 班级选择的变更
  327. const HandleGradeClassSelectChange = (grade,val)=>{
  328. batchEditGradeList.value = batchEditGradeList.value.map(item=>{
  329. if(item.evaluationGradeId == grade.evaluationGradeId){
  330. item.isSelectAll = grade.selectedClassList?.length === grade.classList?.length && grade.selectedClassList?.length !==0 ? true : false
  331. }
  332. return item
  333. })
  334. }
  335. // 3. 清空配置的评价账号数据
  336. const ClearReviewAccount = ()=>{
  337. batchEditGradeList.value?.map(grade=>{
  338. let gradeId = grade.evaluationGradeId
  339. let classDataList = grade.classData
  340. classDataList.map((classItm,index)=>{
  341. if(typeof tableData.value[index] !== 'object'){
  342. tableData.value[index] = {}
  343. }
  344. // 当前年级下的行赋值
  345. tableData.value[index][`num_${gradeId}`] = null
  346. tableData.value[index][`male_${gradeId}`] = null
  347. tableData.value[index][`female_${gradeId}`] = null
  348. })
  349. })
  350. }
  351. // 4. 生成评价码页面
  352. const GoToGenerateCodePage = ()=>{
  353. // 跳转到生成评价码页面前要临时存储 当前页面的所有数据
  354. let reviewAccountMsg = {
  355. originReviewAccount:originReviewAccount.value,
  356. batchEditGradeList:batchEditGradeList.value,
  357. tableColumns:tableColumns.value,
  358. tableData:tableData.value
  359. }
  360. let accounts = batchEditGradeList.value?.map(grade=>{
  361. let gradeId = grade.evaluationGradeId
  362. let classDataList = grade.classData
  363. return classDataList.map((classItm,index)=>{
  364. if(typeof tableData.value[index] !== 'object'){
  365. tableData.value[index] = {}
  366. }
  367. return {
  368. id:tableData.value[index][`class_${gradeId}`].classId,
  369. evaluationGradeName: tableData.value[index][`grade_${gradeId}`],
  370. evaluationDataClassName: tableData.value[index][`class_${gradeId}`]?.className,
  371. evaluationCount: tableData.value[index][`num_${gradeId}`],
  372. boyCount: tableData.value[index][`male_${gradeId}`],
  373. girlCount: tableData.value[index][`female_${gradeId}`]
  374. }
  375. })
  376. })?.flat() || []
  377. let params = {
  378. evaluationId: route.query.id,
  379. genderStatus: evaluationManageData.isGenerateAccountByGender ? 1 : 0,
  380. accounts
  381. }
  382. // 存储当前整个页面的内容——防止生成评价码失败后,不能继续延用 配置状态的旧数据
  383. sessionStorage.setItem('reviewAccountMsg',JSON.stringify(reviewAccountMsg))
  384. // 存储生成评价码需要的参数
  385. sessionStorage.setItem('reviewAccountOptionData',JSON.stringify(params))
  386. router.push(`generateReviewCode?id=${route.query.id}`)
  387. }
  388. onMounted(async ()=>{
  389. let reviewAccountMsg = sessionStorage.getItem('reviewAccountMsg')
  390. // 如果有缓存,说明是从生成评价码失败页面跳过来的
  391. if(reviewAccountMsg){
  392. let objMsg = JSON.parse(reviewAccountMsg || '{}')
  393. originReviewAccount.value = objMsg.originReviewAccount
  394. batchEditGradeList.value = objMsg.batchEditGradeList
  395. tableColumns.value = objMsg.tableColumns
  396. tableData.value = objMsg.tableData
  397. sessionStorage.removeItem('reviewAccountMsg') //获取完后清空数据
  398. }else{
  399. await GetReviewAccountList()
  400. }
  401. })
  402. </script>
  403. <style lang="scss" scoped>
  404. .grade_form_item{
  405. display: flex;
  406. flex-direction: column;
  407. gap:26px;
  408. .grade_name{
  409. font-weight: 600;
  410. font-size: 16px;
  411. color: #333333;
  412. margin-bottom: 10px;
  413. }
  414. .class_list .el-checkbox{
  415. font-weight: 400;
  416. font-size: 14px;
  417. color: #666666;
  418. }
  419. }
  420. .group_batch_num,
  421. .batch_num{
  422. display: flex;
  423. align-items: center;
  424. gap:20px;
  425. word-break: keep-all;
  426. > span{
  427. display: flex;
  428. align-items: center;
  429. word-break: keep-all;
  430. }
  431. }
  432. </style>