kmjksz.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. <script setup lang="ts">
  2. import { ref, getCurrentInstance, reactive } from "vue";
  3. import { useRouter } from "vue-router";
  4. import request, { download } from '~/utils/request';
  5. import { pick } from 'lodash-es';
  6. import { ElMessage } from 'element-plus'
  7. import type { FormInstance, FormRules } from 'element-plus'
  8. import type { AxiosRequestConfig } from 'axios'
  9. // #region (constant)
  10. const TABLE_KEY = 'xkkm_id'
  11. const URL_CUT = '/xdjx/kcpzgl_kmjksz'
  12. const URL_CUT_REF = ref(URL_CUT)
  13. const URL_SUBMIT_KEY = URL_CUT.split('/').join('_').slice(1)
  14. const instance = getCurrentInstance()
  15. const router = useRouter()
  16. // #endregion
  17. // #region (variable)
  18. const loading_table = ref(true)
  19. let whichDialogSubmit: 'add' | 'edit'
  20. // #endregion
  21. // #region (type)
  22. type TYPE_TABLE_FIELD = {
  23. [TABLE_KEY]: string;
  24. 'xkkm_kmmc': string; // 科目名称
  25. 'xkkm_jkjs': string; // 监考教师
  26. 'xkkm_jkjs_json': string; // 监考教师JSON
  27. 'xjj_zgbh': string // 职工编号
  28. }
  29. // #endregion
  30. // #region (props)
  31. // #endregion
  32. // #region (query row)
  33. const queryForm_Data = ref<Partial<TYPE_TABLE_FIELD> & { keyword?: string }>({})
  34. const handleQueryFormBtn_search = () => {
  35. queryApi()
  36. }
  37. const handleQueryFormBtn_clear = () => {
  38. queryForm_Data.value = {}
  39. }
  40. // #endregion
  41. // #region (table selection)
  42. const multipleSelection = ref<TYPE_TABLE_FIELD[]>([])
  43. const handleSelectionChange = (val: TYPE_TABLE_FIELD[]) => {
  44. multipleSelection.value = val
  45. }
  46. // #endregion
  47. // #region (table row)
  48. const handleTableRowBtn_import = async ({ file }: { file: File }) => {
  49. const res = await API_MAP['import']({ file })
  50. if (res.code === '1') {
  51. queryApi()
  52. ElMessage.success(res.msg)
  53. }
  54. }
  55. const handleTableRowBtn_export = () => {
  56. exportApi()
  57. }
  58. const handleTableRowBtn_add = () => {
  59. whichDialogSubmit = 'add'
  60. dialogForm_Data.value = {}
  61. dialogVisible_addOrEdit.value = true
  62. }
  63. const handleTableRowBtn_delete = async () => {
  64. await deleteApi(multipleSelection.value.map((item: TYPE_TABLE_FIELD) => item[TABLE_KEY]))
  65. queryApi()
  66. }
  67. // #endregion
  68. // #region (table body)
  69. const tableData = ref<TYPE_TABLE_FIELD[]>([])
  70. const DetailName = '-KCPZGL-KMJKSZ'
  71. const DetailParam = 'aid'
  72. const handleTableColBtn_edit = async (scope: { row: TYPE_TABLE_FIELD }) => {
  73. whichDialogSubmit = 'edit'
  74. const res = await detailApi(scope.row[TABLE_KEY])
  75. dialogForm_Data.value = (res.data.one_info)
  76. dialogVisible_addOrEdit.value = true
  77. }
  78. const handleTableColBtn_audit = (scope: { row: TYPE_TABLE_FIELD }) => {
  79. whichDialogSubmit = 'edit'
  80. dialogForm_Data.value = pick(scope.row, [`${TABLE_KEY}`, ...Object.keys(dialogForm_Rules_audit)])
  81. dialogVisible_audit.value = true
  82. }
  83. const handleTableColBtn_detail = (scope: { row: TYPE_TABLE_FIELD }) => {
  84. router.push({ name: DetailName, params: { [DetailParam]: scope.row[TABLE_KEY] } })
  85. }
  86. const handleTableColBtn_delete = async (scope: { row: TYPE_TABLE_FIELD }) => {
  87. await deleteApi(scope.row[TABLE_KEY])
  88. queryApi()
  89. }
  90. // #endregion
  91. // #region (pagination)
  92. const total = ref(0)
  93. const limit = ref(10)
  94. const currentPage = ref(1)
  95. function handleCurrentChange() {
  96. queryApi()
  97. }
  98. // #endregion
  99. // #region (dialog base)
  100. const dialogForm_Data = ref<Partial<TYPE_TABLE_FIELD> & { keyword?: string }>({})
  101. const handleDialogFormBtn_submit = async (formRefKey: string, extendData?: Partial<TYPE_TABLE_FIELD>) => {
  102. const isValid = await (instance?.refs[formRefKey] as FormInstance).validate((valid: boolean) => valid)
  103. if (isValid) {
  104. await API_MAP[whichDialogSubmit](<TYPE_TABLE_FIELD>({ ...dialogForm_Data.value, ...extendData }))
  105. handleDialogFormBtn_cancel()
  106. queryApi()
  107. }
  108. }
  109. const handleDialogFormBtn_cancel = (formRefKey?: string) => {
  110. dialogVisible_addOrEdit.value = false
  111. dialogVisible_audit.value = false
  112. }
  113. // #endregion
  114. // #region (dialog add/edit)
  115. const dialogVisible_addOrEdit = ref<boolean>(false)
  116. const dialogForm_Ref_addOrEdit = ref<FormInstance>()
  117. const dialogForm_Rules_addOrEdit = reactive({
  118. 'xkkm_kmmc': { required: true, message: '科目名称不能为空', trigger: 'submit' },
  119. 'xkkm_jkjs': { required: true, message: '监考教师不能为空', trigger: 'submit' },
  120. 'xkkm_jkjs_json': { required: true, message: '监考教师JSON不能为空', trigger: 'submit' },
  121. })
  122. // #endregion
  123. // #region (dialog audit)
  124. const dialogVisible_audit = ref<boolean>(false)
  125. const dialogForm_Field_audit = reactive<{
  126. FLAG: keyof TYPE_TABLE_FIELD,
  127. REASON?: keyof TYPE_TABLE_FIELD
  128. }>({
  129. FLAG: 'xkkm_id',
  130. REASON: 'xkkm_id'
  131. })
  132. const dialogForm_Ref_audit = ref<FormInstance>()
  133. const dialogForm_Rules_audit = reactive<FormRules>({
  134. 'xkkm_kmmc': { required: true, message: '科目名称不能为空', trigger: 'submit' },
  135. 'xkkm_jkjs': { required: true, message: '监考教师不能为空', trigger: 'submit' },
  136. 'xkkm_jkjs_json': { required: true, message: '监考教师JSON不能为空', trigger: 'submit' },
  137. })
  138. // #endregion
  139. // #region (request api):
  140. function queryApi() {
  141. loading_table.value = true
  142. return request({
  143. url: URL_CUT + '/index',
  144. data: {
  145. ...queryForm_Data.value,
  146. limit: limit.value,
  147. page: currentPage.value
  148. }
  149. }).then((response: { data: { total_rows: string, page_data: TYPE_TABLE_FIELD[] } }) => {
  150. const { data } = response
  151. total.value = parseInt(data.total_rows)
  152. tableData.value = data.page_data
  153. return response
  154. }).then(() => {
  155. loading_table.value = false
  156. })
  157. }
  158. function addApi(data: TYPE_TABLE_FIELD) {
  159. return request({
  160. url: URL_CUT + '/add',
  161. data: {
  162. [URL_SUBMIT_KEY]: data,
  163. }
  164. })
  165. }
  166. function editApi(data: Partial<TYPE_TABLE_FIELD>) {
  167. return request({
  168. url: URL_CUT + '/edit',
  169. data: {
  170. [TABLE_KEY]: data[TABLE_KEY],
  171. [URL_SUBMIT_KEY]: pick(data, ['xkkm_kmmc', 'xkkm_jkjs', 'xkkm_jkjs_json', 'xjj_zgbh']),
  172. }
  173. })
  174. }
  175. function deleteApi(id: string | string[]) {
  176. return request({
  177. url: URL_CUT + '/delete',
  178. data: {
  179. [TABLE_KEY]: id,
  180. }
  181. })
  182. }
  183. function detailApi(id: string) {
  184. return request({
  185. url: URL_CUT + '/detail',
  186. data: {
  187. [TABLE_KEY]: id,
  188. }
  189. })
  190. }
  191. function importApi(data: { file: File }) {
  192. return request({
  193. $type: 'import',
  194. url: URL_CUT + '/import',
  195. data
  196. } as AxiosRequestConfig)
  197. }
  198. function exportApi() {
  199. return download(URL_CUT + '/index', queryForm_Data.value)
  200. }
  201. const API_MAP = {
  202. query: queryApi,
  203. add: addApi,
  204. edit: editApi,
  205. delete: deleteApi,
  206. detail: detailApi,
  207. import: importApi,
  208. export: exportApi,
  209. }
  210. // #endregion
  211. // #region (page init)
  212. function init() {
  213. queryApi()
  214. }
  215. init()
  216. // #endregion
  217. </script>
  218. <template>
  219. <div class="card flex-grow flex flex-col">
  220. <el-form inline :model="queryForm_Data">
  221. <el-form-item label="科目名称">
  222. <el-input v-model="queryForm_Data.xkkm_kmmc" clearable />
  223. </el-form-item>
  224. <el-form-item label="监考教师">
  225. <el-input v-model="queryForm_Data.xkkm_jkjs" clearable />
  226. </el-form-item>
  227. <!-- <el-form-item label="监考教师JSON"><el-input v-model="queryForm_Data.xkkm_jkjs_json" type="textarea" /></el-form-item> -->
  228. <el-form-item>
  229. <el-button @click="handleQueryFormBtn_search" type="primary">搜索</el-button>
  230. <el-button @click="handleQueryFormBtn_clear" type="warning">清空</el-button>
  231. </el-form-item>
  232. </el-form>
  233. <div class="divider"></div>
  234. <div>
  235. <import-button :url="URL_CUT_REF"></import-button>
  236. <el-button @click="handleTableRowBtn_export" type="success">导出</el-button>
  237. <el-button @click="handleTableRowBtn_add" type="primary">新增</el-button>
  238. <el-button @click="handleTableRowBtn_delete" type="danger">删除</el-button>
  239. </div>
  240. <div class="divider"></div>
  241. <div class="flex-auto">
  242. <el-table :data="tableData" @selection-change="handleSelectionChange" v-loading="loading_table"
  243. element-loading-background="#ffffff70">
  244. <el-table-column type="selection"></el-table-column>
  245. <el-table-column type="index" label="序号" width="60" :index="(i: number) => (currentPage - 1) * limit + i + 1" />
  246. <el-table-column prop="xkkm_kmmc" label="科目名称" width="auto" show-overflow-tooltip></el-table-column>
  247. <!-- <el-table-column prop="xkkm_jkjs" label="监考教师" width="auto" show-overflow-tooltip></el-table-column> -->
  248. <el-table-column prop="xkkm_jkjs_json" label="监考教师" width="auto" show-overflow-tooltip></el-table-column>
  249. <el-table-column label="操作" fixed="right">
  250. <template #default="scope">
  251. <el-button link :auto-insert-space="false" @click="handleTableColBtn_edit(scope)" type="primary">编辑
  252. </el-button>
  253. <!-- <el-button link :auto-insert-space="false" @click="handleTableColBtn_audit(scope)" type="primary" >审核</el-button>
  254. <el-button link :auto-insert-space="false" @click="handleTableColBtn_detail(scope)" type="primary" >详情</el-button> -->
  255. <el-button link :auto-insert-space="false" @click="handleTableColBtn_delete(scope)" type="primary">删除
  256. </el-button>
  257. </template>
  258. </el-table-column>
  259. </el-table>
  260. </div>
  261. <div class="flex justify-end mt-10 py-4">
  262. <el-pagination :page-size="limit" v-model:current-page="currentPage" @current-change="handleCurrentChange"
  263. background layout="total, prev, pager, next" :total="total" />
  264. </div>
  265. </div>
  266. <el-dialog v-model="dialogVisible_addOrEdit" append-to-body destroy-on-close>
  267. <el-form :model="dialogForm_Data" ref="dialogForm_Ref_addOrEdit" :rules="dialogForm_Rules_addOrEdit"
  268. label-width="120px">
  269. <el-form-item label="科目名称" prop="xkkm_kmmc">
  270. <el-input v-model="dialogForm_Data.xkkm_kmmc" clearable />
  271. </el-form-item>
  272. <el-form-item label="监考教师" prop="xkkm_jkjs">
  273. <!-- <el-input v-model="dialogForm_Data.xkkm_jkjs" clearable /> -->
  274. <remote-multi-select url="/xdbg/jzggl_jsgl/index" :fields="['xjj_zgbh','xjj_xm']" v-model="dialogForm_Data.xkkm_jkjs" v-model:model-name="dialogForm_Data.xkkm_jkjs_json" ></remote-multi-select>
  275. </el-form-item>
  276. <!-- <el-form-item label="监考教师JSON" prop="xkkm_jkjs_json">
  277. <el-input v-model="dialogForm_Data.xkkm_jkjs_json" type="textarea" />
  278. </el-form-item> -->
  279. <div class="flex justify-center">
  280. <el-button @click="handleDialogFormBtn_submit('dialogForm_Ref_addOrEdit')" type="primary">提交</el-button>
  281. <el-button @click="handleDialogFormBtn_cancel('dialogForm_Ref_addOrEdit')" type="default">取消</el-button>
  282. </div>
  283. </el-form>
  284. </el-dialog>
  285. <el-dialog v-model="dialogVisible_audit" append-to-body destroy-on-close>
  286. <el-form :model="dialogForm_Data" ref="dialogForm_Ref_audit" :rules="dialogForm_Rules_audit" label-width="120px">
  287. <el-form-item label="状态">
  288. <el-radio-group v-model="dialogForm_Data[dialogForm_Field_audit.FLAG]">
  289. <el-radio label="1">通过</el-radio>
  290. <el-radio label="2">未通过</el-radio>
  291. </el-radio-group>
  292. </el-form-item>
  293. <!-- <el-form-item label="原因" v-show="dialogForm_Data[dialogForm_Field_audit.FLAG] === '1'">
  294. <el-input type="textarea" v-model="dialogForm_Data[dialogForm_Field_audit.REASON]" :rows="5" />
  295. </el-form-item> -->
  296. <div class="flex justify-center">
  297. <el-button @click="handleDialogFormBtn_submit('dialogForm_Ref_audit')" type="primary">提交</el-button>
  298. <el-button @click="handleDialogFormBtn_cancel('dialogForm_Ref_audit')" type="default">取消</el-button>
  299. </div>
  300. </el-form>
  301. </el-dialog>
  302. </template>