CpdmLeave.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. <script lang="ts" setup>
  2. import { ref, reactive, defineExpose } from 'vue'
  3. import { ElMessage, formatter, type ComponentSize, type FormInstance, type FormRules } from 'element-plus'
  4. import { leaveRecordApi, subLeaveApi } from '@/api/login';
  5. //格式化时间格式
  6. import { format } from 'date-fns/format';
  7. import CpdmLeaveEdit from './CpdmLeaveEdit.vue';
  8. const editFlag = ref<any>()
  9. const leave_visible = ref<boolean>(false)
  10. const open = () => {
  11. leave_visible.value = true;
  12. }
  13. const type = ref<string>('1')
  14. //************表单数据******************/
  15. //设置表单大小
  16. const formSize = ref<ComponentSize>('default')
  17. const ruleFormRef = ref<any>()
  18. interface RuleForm {
  19. leaveType: string
  20. userPhone: string
  21. monitorName: string
  22. dormitory: string
  23. destination: string
  24. reason: string
  25. isKnow: string
  26. companionsPhone: string
  27. motherPhone: string
  28. fatherPhone: string
  29. travelMode: string
  30. startTime: string
  31. endTime: string
  32. }
  33. const ruleForm = reactive<RuleForm>({
  34. //是否离郑
  35. leaveType: '0',
  36. //本人手机号
  37. userPhone: '',
  38. //班长姓名
  39. monitorName: '',
  40. //宿舍:
  41. dormitory: '',
  42. //出行方式
  43. destination: '',
  44. //请假原因
  45. reason: '',
  46. //父母是否知情
  47. isKnow: '1',
  48. //同行人电话
  49. companionsPhone: '',
  50. //家长电话
  51. motherPhone: '',
  52. //紧急联系人电话
  53. fatherPhone: '',
  54. //出行方式
  55. travelMode: '',
  56. //请假时间
  57. startTime: '',
  58. //返校时间
  59. endTime: ''
  60. })
  61. const rules = reactive<FormRules<RuleForm>>({
  62. leaveType: [
  63. { required: true, message: '请填写是否离郑', trigger: 'blur' },
  64. ],
  65. userPhone: [
  66. { required: true, message: '请填写手机号', trigger: 'blur' },
  67. { pattern: /^1[3456789]\d{9}$/, message: '手机号码格式不正确', trigger: 'blur' }
  68. ],
  69. monitorName: [
  70. { required: false, message: '请填写班长姓名', trigger: 'blur' },
  71. ],
  72. dormitory: [
  73. { required: true, message: '请填写宿舍信息', trigger: 'blur' },
  74. { min: 1, max: 200, message: '宿舍信息不能超过200字', trigger: 'blur' },
  75. ],
  76. destination: [
  77. { required: true, message: '请填写出行目的', trigger: 'blur' },
  78. { min: 1, max: 200, message: '出行目的不能超过200字', trigger: 'blur' },
  79. ],
  80. reason: [
  81. { required: true, message: '请填写请假原因', trigger: 'blur' },
  82. { min: 1, max: 20, message: '请假原因不能超过200字', trigger: 'blur' },
  83. ],
  84. isKnow: [
  85. { required: true, message: '请填写父母是否知情', trigger: 'blur' },
  86. ],
  87. companionsPhone: [
  88. { pattern: /^1[3456789]\d{9}$/, message: '手机号码格式不正确', trigger: 'blur' }
  89. ],
  90. motherPhone: [
  91. { required: true, message: '请填写家长电话', trigger: 'blur' },
  92. { pattern: /^1[3456789]\d{9}$/, message: '手机号码格式不正确', trigger: 'blur' }
  93. ],
  94. fatherPhone: [
  95. { required: true, message: '请填写紧急联系人电话', trigger: 'blur' },
  96. { pattern: /^1[3456789]\d{9}$/, message: '手机号码格式不正确', trigger: 'blur' }
  97. ],
  98. travelMode: [
  99. { required: true, message: '请填写出行方式', trigger: 'blur' },
  100. ],
  101. startTime: [
  102. { required: true, message: '请填写请假时间', trigger: 'change' },
  103. {
  104. validator: function (rule, value, callback) {
  105. if (value !== '' && ruleForm.endTime !== '') {
  106. let startTime = new Date(value).getTime();
  107. let endTime = new Date(ruleForm.endTime).getTime()
  108. //先判断都不为空
  109. if (startTime >= endTime) {
  110. callback(new Error('请假时间应小于返校时间'))
  111. } else {
  112. callback()
  113. }
  114. } else {
  115. callback()
  116. }
  117. }, trigger: 'change'
  118. },
  119. ],
  120. endTime: [
  121. { required: true, message: '请填写返校时间', trigger: 'change' },
  122. {
  123. validator: function (rule, value, callback) {
  124. if (value !== '' && ruleForm.startTime !== '') {
  125. let startTime = new Date(ruleForm.startTime).getTime();
  126. let endTime = new Date(value).getTime()
  127. if (endTime <= startTime) {
  128. callback(new Error('返校时间应大于请假时间'))
  129. } else {
  130. callback()
  131. }
  132. } else {
  133. callback()
  134. }
  135. //
  136. }, trigger: 'change'
  137. },
  138. ],
  139. })
  140. //提交表单
  141. //按钮状态改变
  142. const buttonStatus = ref<boolean>(false)
  143. const submitForm = async (formEl: FormInstance | undefined) => {
  144. buttonStatus.value = true
  145. //设置单独校验的字段
  146. if (!formEl) {
  147. buttonStatus.value = false
  148. return
  149. }
  150. await formEl.validate(async (valid, fields) => {
  151. if (valid) {
  152. console.log('submit!')
  153. //调用用户提交信息的代码
  154. //判断返校时间是否大于请假时间
  155. let leaveTime = new Date()
  156. subLeaveInfo()
  157. } else {
  158. buttonStatus.value = false
  159. console.log('error submit!', fields)
  160. }
  161. })
  162. }
  163. //时间格式化
  164. //提交表单信息
  165. const subLeaveInfo = async () => {
  166. //提交表单信息
  167. //组装该用户需要提交的信息
  168. let params = {}
  169. //判断当前的状态是否离郑
  170. //1是不离郑
  171. if (ruleForm.leaveType == '0') {
  172. params = {
  173. userPhone: ruleForm.userPhone, //本人手机号
  174. destination: ruleForm.destination,//出行目的地
  175. dormitory: ruleForm.dormitory,//宿舍
  176. endTime: format(ruleForm.endTime, 'yyyy-MM-dd HH:mm:ss'),//返校时间
  177. fatherPhone: ruleForm.fatherPhone,//父亲手机号
  178. isKnow: ruleForm.isKnow,//父母是否知情
  179. leaveType: ruleForm.leaveType,//请假类型--离郑不离郑
  180. // monitorName: ruleForm.monitorName,//班长名字
  181. motherPhone: ruleForm.motherPhone,//家长电话
  182. reason: ruleForm.reason,//请假原因
  183. startTime: format(ruleForm.startTime, 'yyyy-MM-dd HH:mm:ss'),//请假开始时间
  184. travelMode: ruleForm.travelMode,//出行方式
  185. // companionsPhone: ruleForm.companionsPhone, //同行人电话
  186. }
  187. } else {
  188. params = {
  189. userPhone: ruleForm.userPhone, //本人手机号
  190. destination: ruleForm.destination,//出行目的地
  191. dormitory: ruleForm.dormitory,//宿舍
  192. endTime: format(ruleForm.endTime, 'yyyy-MM-dd HH:mm:ss'),//返校时间
  193. fatherPhone: ruleForm.fatherPhone,//父亲手机号
  194. isKnow: ruleForm.isKnow,//父母是否知情
  195. leaveType: ruleForm.leaveType,//请假类型--离郑不离郑
  196. monitorName: ruleForm.monitorName,//班长名字
  197. motherPhone: ruleForm.motherPhone,//家长电话
  198. reason: ruleForm.reason,//请假原因
  199. startTime: format(ruleForm.startTime, 'yyyy-MM-dd HH:mm:ss'),//请假开始时间
  200. travelMode: ruleForm.travelMode,//出行方式
  201. companionsPhone: ruleForm.companionsPhone, //同行人电话
  202. }
  203. }
  204. let res: any = await subLeaveApi(params)
  205. console.log(res)
  206. //跳转测试记录
  207. if (res.code == 200) {
  208. //结束了
  209. buttonStatus.value = false
  210. ElMessage({
  211. type: 'success',
  212. message: '提交成功'
  213. })
  214. //跳转到请假记录
  215. type.value = '2'
  216. leaveRecord()
  217. //开始查询请假记录的字段
  218. //
  219. } else {
  220. buttonStatus.value = false
  221. }
  222. }
  223. //清除表单的校验
  224. const resetData = (formEl: FormInstance | undefined) => {
  225. if (!formEl) return
  226. formEl.resetFields()
  227. }
  228. //是否离郑状态改变
  229. const leaveStatus = (val: string) => {
  230. // resetData(ruleFormRef)
  231. if (val == '1') {
  232. rules.monitorName = [
  233. { required: true, message: '请填写班长姓名', trigger: 'blur' },
  234. ]
  235. rules.companionsPhone = [
  236. { pattern: /^1[3456789]\d{9}$/, message: '手机号码格式不正确', trigger: 'blur' }
  237. ]
  238. //这样回触发校验
  239. // rules!.monitorName[0].required = true;
  240. // rules!.companionsPhone[0].required = true
  241. }
  242. ruleFormRef.value.clearValidate()
  243. }
  244. //类型方法
  245. const typeFun = (val: string) => {
  246. type.value = val;
  247. if (val == '1') {
  248. //清空表单
  249. ruleFormRef.value.clearValidate()
  250. ruleFormRef.value.resetFields()
  251. } else {
  252. //查询记录列表
  253. leaveRecord()
  254. }
  255. }
  256. //请假记录列表
  257. let tableData = ref<any>([])
  258. //第几页
  259. const pageNum = ref<number>(1)
  260. //每页多少条
  261. const pageSize = ref<number>(10)
  262. //总条数
  263. const total = ref<number>(0)
  264. const leaveRecord = async () => {
  265. //leaveRecordApi
  266. let params = {
  267. pageNum: pageNum.value,
  268. pageSize: pageSize.value
  269. }
  270. let res: any = await leaveRecordApi(params)
  271. tableData.value = res.data.content
  272. total.value = res.data.totalElements
  273. }
  274. //格式化是否离郑
  275. const leaveTypeFormatter = (val: any) => {
  276. if (val.leaveType == '0') {
  277. return '不离郑'
  278. } else {
  279. return '离郑'
  280. }
  281. }
  282. //格式化父母是否知情
  283. const isKnowFormatter = (val: any) => {
  284. if (val.isKnow == '1') {
  285. return '知情'
  286. } else {
  287. return '不知情'
  288. }
  289. }
  290. //格式审核状态状态
  291. const auditStatusFormatter = (val: any) => {
  292. if (val.auditStatus == '0') {
  293. return '待审批'
  294. } else {
  295. return '已审批'
  296. }
  297. }
  298. //审核结果
  299. const auditResultFormatter = (val: any) => {
  300. if (val.auditResult == null) {
  301. return ''
  302. } else {
  303. if (val.auditResult == '0') {
  304. return '驳回'
  305. } else {
  306. return '通过'
  307. }
  308. }
  309. }
  310. //分页显示
  311. const handleCurrentChange = (val: number) => {
  312. pageNum.value = val
  313. leaveRecord()
  314. }
  315. //需要重新编辑操作
  316. const editFun = (val: any, flag: boolean) => {
  317. editFlag.value.open(val, flag)
  318. }
  319. const listFun = () => {
  320. //刷新列表
  321. leaveRecord()
  322. }
  323. defineExpose({ open })
  324. </script>
  325. <template>
  326. <div class="outt"> <el-dialog v-model="leave_visible" :show-close="true" width="80%" top="5vh"
  327. style="border-radius: 40px; ">
  328. <template #header="{ close, titleId, titleClass }">
  329. <!-- <img src="../assets/zs/top_leave.png" alt="" > -->
  330. <div class="leave_title"></div>
  331. <div
  332. style="display: inline-flex;background-color: #EDEDED ;padding: 4px;border-radius: 40px;margin-left: 20px;">
  333. <span :class="{ button_leave_active: type == '1', button_leave_default: type == '2' }"
  334. @click="typeFun('1')">我要请假</span>
  335. <span :class="{ button_leave_active: type == '2', button_leave_default: type == '1' }"
  336. @click="typeFun('2')">请假记录</span>
  337. </div>
  338. <!-- <el-radio-group v-model="type" size="large" @change="typeFun" style="margin-left:20px">
  339. <el-radio-button label="我要请假" value="1" />
  340. <el-radio-button label="请假记录" value="2" />
  341. </el-radio-group> -->
  342. <div v-show="type == '1'" class="leave">
  343. <el-form ref="ruleFormRef" style="display: flex;flex-wrap: wrap;" :model="ruleForm" :rules="rules"
  344. :validate-on-rule-change=false label-width="auto" class="demo-ruleForm" :size="formSize"
  345. status-icon>
  346. <el-form-item label="是否离郑" prop="leaveType">
  347. <el-radio-group v-model="ruleForm.leaveType" @change="leaveStatus">
  348. <el-radio value="0">不离郑</el-radio>
  349. <el-radio value="1">离郑</el-radio>
  350. </el-radio-group>
  351. </el-form-item>
  352. <el-form-item label="本人手机号码" prop="userPhone">
  353. <el-input v-model="ruleForm.userPhone" placeholder="请输入本人手机号码" />
  354. </el-form-item>
  355. <el-form-item label="班长姓名" prop="monitorName" v-if="ruleForm.leaveType == '1'">
  356. <el-input v-model="ruleForm.monitorName" placeholder="请输入班长姓名" />
  357. </el-form-item>
  358. <el-form-item label="宿舍" prop="dormitory">
  359. <el-input v-model="ruleForm.dormitory" placeholder="例如松15-XXX" />
  360. </el-form-item>
  361. <el-form-item label="请假原因" prop="reason">
  362. <el-input v-model="ruleForm.reason" :rows="2" type="textarea" placeholder="一定要写清楚,例如拔牙" />
  363. </el-form-item>
  364. <el-form-item label="出行目的地" prop="destination">
  365. <el-input v-model="ruleForm.destination" :rows="2" type="textarea"
  366. placeholder="一定要写清楚,例如郑州市中原区高新区郑州中心医院" />
  367. </el-form-item>
  368. <el-form-item label="父母是否知情" prop="isKnow">
  369. <el-radio-group v-model="ruleForm.isKnow">
  370. <el-radio value="1">知情</el-radio>
  371. <el-radio value="0">不知情</el-radio>
  372. </el-radio-group>
  373. </el-form-item>
  374. <el-form-item label="同行人电话" prop="companionsPhone" v-if="ruleForm.leaveType == '1'">
  375. <el-input v-model="ruleForm.companionsPhone" placeholder="请输入同行人电话" />
  376. </el-form-item>
  377. <el-form-item label="家长电话" prop="motherPhone">
  378. <el-input v-model="ruleForm.motherPhone" placeholder="请输入家长电话" />
  379. </el-form-item>
  380. <el-form-item label="紧急联系人电话" prop="fatherPhone">
  381. <el-input v-model="ruleForm.fatherPhone" placeholder="请输入紧急联系人电话" />
  382. </el-form-item>
  383. <el-form-item label="出行方式" prop="travelMode">
  384. <el-input v-model="ruleForm.travelMode" placeholder="请输入出行方式" />
  385. </el-form-item>
  386. <el-form-item label="请假时间" prop="startTime">
  387. <el-date-picker v-model="ruleForm.startTime" type="datetime" placeholder="请输入请假时间"
  388. style="width: 100%;" />
  389. </el-form-item>
  390. <el-form-item label="返校时间" prop="endTime">
  391. <el-date-picker v-model="ruleForm.endTime" type="datetime" placeholder="请输入返校时间"
  392. style="width: 100%;" />
  393. </el-form-item>
  394. </el-form>
  395. <div class="reset_sub">
  396. <el-button @click="resetData(ruleFormRef)"
  397. style="border-radius: 40px;padding:10px 40px">重置</el-button>
  398. <el-button type="success" @click="submitForm(ruleFormRef)" :disabled="buttonStatus"
  399. style="border-radius: 40px;padding:10px 40px">提交</el-button>
  400. </div>
  401. <div class="leave_tip"> 温馨提示:(天气寒冷,晚上行人少,为保证大家安全,返校时间尽量在21:00之前。如需纸质假条,请到辅导员办公室办理。)
  402. </div>
  403. </div>
  404. <div v-show="type == '2'" style="padding:10px 20px">
  405. <el-table :data="tableData" style="width: 100%;height: 60vh;"
  406. :header-cell-style="{ background: '#F8F8F8', color: '#606266', 'font-family': 'Microsoft YaHei' }">
  407. <el-table-column fixed prop="leaveType" label="是否离郑" width="" :formatter="leaveTypeFormatter"
  408. align="center" />
  409. <el-table-column prop="userPhone" label="本人手机号" width="" show-overflow-tooltip align="center" />
  410. <!-- <el-table-column prop="monitorName" label="班长姓名" width="" /> -->
  411. <!-- <el-table-column prop="dormitory" label="宿舍" width="" /> -->
  412. <el-table-column prop="reason" label="请假原因" width="" align="center" />
  413. <el-table-column prop="destination" label="出行目的地" width="" show-overflow-tooltip
  414. align="center" />
  415. <!-- <el-table-column prop="isKnow" label="父母是否知情" width="" :formatter="isKnowFormatter" /> -->
  416. <!-- <el-table-column prop="companionsPhone" label="同行人电话" width="" /> -->
  417. <!-- <el-table-column prop="motherPhone" label="家长电话" width="" />
  418. <el-table-column prop="fatherPhone" label="紧急联系人电话" width="" /> -->
  419. <el-table-column prop="travelMode" label="出行方式" width="" show-overflow-tooltip align="center" />
  420. <el-table-column prop="startTime" label="请假时间" width="" show-overflow-tooltip align="center" />
  421. <el-table-column prop="endTime" label="返校时间" width="" show-overflow-tooltip align="center" />
  422. <el-table-column fixed="right" prop="auditSuggest" label="审核建议" width="" align="center"
  423. show-overflow-tooltip />
  424. <el-table-column fixed="right" prop="auditStatus" label="审核状态" width="" align="center"
  425. :formatter="auditStatusFormatter" />
  426. <!-- :formatter="auditStatusFormatter" -->
  427. <el-table-column fixed="right" prop="auditResult" label="审核结果" width="" align="center">
  428. <template #default="scoped">
  429. <div style="display: flex;justify-content: center;align-items: center;"
  430. v-show="scoped.row.auditResult == '1'">
  431. <img style="width: 14px;" src="../assets/footer/pass.png" alt="">&nbsp;
  432. <div>通过</div>
  433. </div>
  434. <div style="display: flex;justify-content: center;align-items: center;"
  435. v-show="scoped.row.auditResult == '0'">
  436. <img style="width: 14px;" src="../assets/footer/noPass.png" alt="">&nbsp;
  437. <div>驳回</div>
  438. </div>
  439. </template>
  440. </el-table-column>
  441. <!-- <el-table-column fixed="right" prop="auditResult" label="审核结果" width="" align="center"
  442. :formatter="auditResultFormatter" /> -->
  443. <el-table-column fixed="right" label="操作" min-width="" align="center">
  444. <template #default="scoped">
  445. <el-button v-show="scoped.row.auditResult == null" link type="primary" size="small"
  446. @click="editFun(scoped.row, false)">重新编辑</el-button>
  447. <el-button link type="primary" size="small" style="margin-left: 0px;"
  448. @click="editFun(scoped.row, true)">查看</el-button>
  449. </template>
  450. </el-table-column>
  451. </el-table>
  452. <div style="display: flex;justify-content: center;margin-top:10px">
  453. <el-pagination background v-model:current-page="pageNum" :page-size="pageSize"
  454. layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" />
  455. </div>
  456. </div>
  457. </template>
  458. <CpdmLeaveEdit ref="editFlag" @search='listFun' />
  459. </el-dialog></div>
  460. </template>
  461. <style lang="scss" scoped>
  462. .button_leave_active {
  463. background-color: #ffffff;
  464. padding: 6px 12px;
  465. border-radius: 40px;
  466. font-size: 16px;
  467. color: #222222;
  468. }
  469. .button_leave_default {
  470. padding: 6px 12px;
  471. border-radius: 40px;
  472. font-size: 16px;
  473. color: #999999;
  474. }
  475. .outt {
  476. :deep(.el-dialog) {
  477. padding: 0px !important;
  478. }
  479. :deep(.el-dialog__header.show-close) {
  480. padding-right: 0px !important;
  481. }
  482. :deep(.el-dialog__headerbtn .el-dialog__close) {
  483. color: #ffffff !important;
  484. }
  485. }
  486. .leave {
  487. padding: 10px 20px;
  488. :deep(.el-form) {
  489. justify-content: space-between;
  490. }
  491. :deep(.el-form-item) {
  492. width: 48% !important;
  493. margin-top: 10px;
  494. }
  495. :deep(.el-input__wrapper) {
  496. align-items: center;
  497. background-color: #F7F7F7 !important;
  498. border-radius: 40px !important;
  499. // border: none;
  500. // outline: none !important;
  501. box-shadow: none;
  502. }
  503. :deep(.el-form-item__content) {
  504. align-items: flex-start !important;
  505. // align-items: center !important;
  506. }
  507. }
  508. .reset_sub {
  509. display: flex;
  510. justify-content: space-around;
  511. }
  512. .leave_tip {
  513. margin-top: 20px;
  514. color: #5c5c5c;
  515. text-align: center;
  516. font-size: 12px;
  517. }
  518. .leave_title {
  519. background: url(../assets/zs/top_leave.png) no-repeat;
  520. background-size: 100% 100%;
  521. // border-radius: 40px;
  522. border-top-left-radius: 40px;
  523. border-top-right-radius: 40px;
  524. height: 40px;
  525. text-align: center;
  526. color: #333333;
  527. font-weight: 700;
  528. font-size: 16px;
  529. margin-bottom: 20px;
  530. }
  531. </style>