user.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. <template>
  2. <div class="hc-page-box">
  3. <HcNewCard>
  4. <template #header>
  5. <div class="w-72">
  6. <el-input v-model="searchForm.queryValue" clearable placeholder="请输入人员名称查询" @keyup="keyUpEvent" />
  7. </div>
  8. <div class="ml-2">
  9. <el-button :disabled="tableData.length < 1" type="primary" @click="searchClick">
  10. <HcIcon name="search-2" />
  11. <span>搜索</span>
  12. </el-button>
  13. </div>
  14. </template>
  15. <template #extra>
  16. <HcTooltip keys="tentative_laboratory_user_add">
  17. <el-button hc-btn type="primary" @click="addFormModalClick">
  18. <HcIcon name="add-circle" />
  19. <span>新增</span>
  20. </el-button>
  21. </HcTooltip>
  22. <HcTooltip keys="tentative_parameter_density_edit">
  23. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn type="primary" color="#12C060" style="color: white;" @click="editFormModalClick">
  24. <HcIcon name="edit" />
  25. <span>编辑</span>
  26. </el-button>
  27. </HcTooltip>
  28. <HcTooltip keys="tentative_laboratory_user_del">
  29. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn color="#e03997" @click="delModalClick">
  30. <HcIcon name="delete-bin-2" />
  31. <span>删除</span>
  32. </el-button>
  33. </HcTooltip>
  34. </template>
  35. <HcTable
  36. ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
  37. is-new :index-style="{ width: 60 }" is-check :check-style="{ width: 29 }"
  38. @selection-change="tableSelection"
  39. >
  40. <template #sex="{ row }">
  41. <span>{{ row.sex === 1 ? '男' : '女' }}</span>
  42. </template>
  43. <template #status="{ row }">
  44. <span>{{ row.status === 1 ? '在职' : '离职' }}</span>
  45. </template>
  46. <template #education="{ row }">
  47. <span>{{ arrKeyValue(educationData, 'dictKey', 'dictValue', row.education) }}</span>
  48. </template>
  49. </HcTable>
  50. <template #action>
  51. <HcPages :pages="searchForm" @change="pageChange" />
  52. </template>
  53. </HcNewCard>
  54. <!-- 新增/编辑 -->
  55. <hc-new-dialog
  56. v-model="addEditFormModal" :is-close="false" :loading="addEditFormLoading"
  57. :title="`${addEditFormModel.id ? '编辑' : '新增'}人员档案`" widths="70rem" @close="addEditFormModalClose"
  58. @save="addEditFormClick"
  59. >
  60. <template #extra>
  61. <HcNewSwitch :datas="tabTypeTab" :keys="tabTypeKey" size="default" @change="tabTypeChange" />
  62. </template>
  63. <el-form
  64. ref="addEditFormRef" :model="addEditFormModel" :rules="addEditFormRules" label-width="auto"
  65. size="large"
  66. >
  67. <template v-if="tabTypeKey === 'tab1'">
  68. <div class="hc-form-item">
  69. <el-form-item label="姓名" prop="name">
  70. <el-input v-model="addEditFormModel.name" />
  71. </el-form-item>
  72. <el-form-item label="身份证" prop="idCard">
  73. <el-input v-model="addEditFormModel.idCard" />
  74. </el-form-item>
  75. <el-form-item label="出生日期" prop="birthday">
  76. <el-date-picker
  77. v-model="addEditFormModel.birthday" :clearable="false" class="block"
  78. type="date" value-format="YYYY-MM-DD"
  79. />
  80. </el-form-item>
  81. </div>
  82. <div class="hc-form-item">
  83. <el-form-item label="性别">
  84. <el-select v-model="addEditFormModel.sex" block>
  85. <el-option :value="1" label="男" />
  86. <el-option :value="2" label="女" />
  87. </el-select>
  88. </el-form-item>
  89. <el-form-item label="毕业院校">
  90. <el-input v-model="addEditFormModel.graduationSchool" />
  91. </el-form-item>
  92. <el-form-item label="专业">
  93. <el-input v-model="addEditFormModel.major" />
  94. </el-form-item>
  95. </div>
  96. <div class="hc-form-item">
  97. <el-form-item label="学历">
  98. <el-select v-model="addEditFormModel.education" block>
  99. <el-option
  100. v-for="item in educationData" :label="item.dictValue"
  101. :value="item.dictKey"
  102. />
  103. </el-select>
  104. </el-form-item>
  105. <el-form-item label="毕业日期">
  106. <el-date-picker
  107. v-model="addEditFormModel.graduationDate" :clearable="false" class="block"
  108. type="date" value-format="YYYY-MM-DD"
  109. />
  110. </el-form-item>
  111. <el-form-item label="入职时间">
  112. <el-date-picker
  113. v-model="addEditFormModel.entryTime" :clearable="false" class="block"
  114. type="date" value-format="YYYY-MM-DD"
  115. />
  116. </el-form-item>
  117. </div>
  118. <div class="hc-form-item">
  119. <el-form-item label="就职状态">
  120. <el-select v-model="addEditFormModel.status" block>
  121. <el-option :value="1" label="在职" />
  122. <el-option :value="0" label="离职" />
  123. </el-select>
  124. </el-form-item>
  125. <el-form-item label="职称">
  126. <el-input v-model="addEditFormModel.jobTitleName" />
  127. </el-form-item>
  128. <el-form-item label="工作职务">
  129. <el-input v-model="addEditFormModel.jobTitlePost" />
  130. </el-form-item>
  131. </div>
  132. <div class="hc-form-item">
  133. <el-form-item label="进场时间">
  134. <el-date-picker
  135. v-model="addEditFormModel.mobilizationTime" :clearable="false" class="block"
  136. type="date" value-format="YYYY-MM-DD"
  137. />
  138. </el-form-item>
  139. <el-form-item label="部门">
  140. <el-input v-model="addEditFormModel.department" />
  141. </el-form-item>
  142. <el-form-item label="从事检测工作时间(月)">
  143. <el-input v-model="addEditFormModel.workingTime" />
  144. </el-form-item>
  145. </div>
  146. <div class="hc-form-item">
  147. <el-form-item label="退场时间">
  148. <el-date-picker
  149. v-model="addEditFormModel.exitTime" :clearable="false" class="block"
  150. type="date" value-format="YYYY-MM-DD"
  151. />
  152. </el-form-item>
  153. <el-form-item label="劳动合同开始日期">
  154. <el-date-picker
  155. v-model="addEditFormModel.laborContractStartDate" :clearable="false" class="block"
  156. type="date" value-format="YYYY-MM-DD"
  157. />
  158. </el-form-item>
  159. <el-form-item label="劳动合同终止日期">
  160. <el-date-picker
  161. v-model="addEditFormModel.laborContractEndDate" :clearable="false" class="block"
  162. type="date" value-format="YYYY-MM-DD"
  163. />
  164. </el-form-item>
  165. </div>
  166. </template>
  167. <template v-if="tabTypeKey === 'tab2'">
  168. <el-form-item label="证书编号">
  169. <el-input v-model="addEditFormModel.certificateNo" />
  170. </el-form-item>
  171. <el-form-item label="持证类型">
  172. <el-select v-model="addEditFormModel.certificateType" block>
  173. <el-option label="检测员" value="1" />
  174. <el-option label="检测工程师" value="2" />
  175. </el-select>
  176. </el-form-item>
  177. <el-form-item label="持证专业">
  178. <el-select v-model="addEditFormModel.certificateMajor" block>
  179. <el-option label="水运结构与地基" value="1" />
  180. <el-option label="交通工具" value="2" />
  181. <el-option label="水运材料" value="3" />
  182. <el-option label="桥梁隧道工程" value="4" />
  183. <el-option label="道路工程" value="5" />
  184. </el-select>
  185. </el-form-item>
  186. <el-form-item label="证书文件">
  187. <FormItemUpload v-model="addEditFormModel.certificateUrl" />
  188. </el-form-item>
  189. </template>
  190. <template v-if="tabTypeKey === 'tab3'">
  191. <el-form-item label="记录日期">
  192. <el-date-picker
  193. v-model="addEditFormModel.workRecordDate" :clearable="false" class="block"
  194. type="date" value-format="YYYY-MM-DD"
  195. />
  196. </el-form-item>
  197. <el-form-item label="内容">
  198. <el-input v-model="addEditFormModel.workContent" :autosize="{ minRows: 8 }" type="textarea" />
  199. </el-form-item>
  200. </template>
  201. </el-form>
  202. </hc-new-dialog>
  203. </div>
  204. </template>
  205. <script setup>
  206. import { onMounted, ref } from 'vue'
  207. import { useAppStore } from '~src/store'
  208. import dataApi from '~api/tentative/laboratory/user'
  209. import FormItemUpload from './components/FormItemUpload.vue'
  210. import { arrKeyValue, arrToId, formValidate, getArrValue, isIdCard } from 'js-fast-way'
  211. import { getDictionary } from '~api/other'
  212. import { delMessageV2 } from '~com/message/index.js'
  213. //初始变量
  214. const useAppState = useAppStore()
  215. //全局变量
  216. const projectId = ref(useAppState.getProjectId)
  217. const contractId = ref(useAppState.getContractId)
  218. //渲染完成
  219. onMounted(() => {
  220. getTableData()
  221. getEducationType()
  222. })
  223. //获取学历类型
  224. const educationData = ref([])
  225. const getEducationType = async () => {
  226. const { data } = await getDictionary({
  227. code: 'trial_user_education',
  228. })
  229. const arrData = getArrValue(data)
  230. arrData.forEach(item => {
  231. item.dictKey = Number(item.dictKey)
  232. })
  233. educationData.value = arrData
  234. }
  235. //持证类型、持证专业
  236. //搜索表单
  237. const searchForm = ref({
  238. queryValue: null, current: 1, size: 20, total: 0,
  239. })
  240. //回车搜索
  241. const keyUpEvent = (e) => {
  242. if (e.key === 'Enter') {
  243. searchForm.value.current = 1
  244. getTableData()
  245. }
  246. }
  247. //搜索
  248. const searchClick = () => {
  249. searchForm.value.current = 1
  250. getTableData()
  251. }
  252. //分页被点击
  253. const pageChange = ({ current, size }) => {
  254. searchForm.value.current = current
  255. searchForm.value.size = size
  256. getTableData()
  257. }
  258. //表格数据
  259. const tableRef = ref(null)
  260. const tableColumn = ref([
  261. { key: 'name', name: '姓名', width: 100 },
  262. { key: 'department', name: '部门', width: 120 },
  263. { key: 'jobTitleName', name: '职称', width: 100 },
  264. { key: 'status', name: '就职状态', width: 80 },
  265. { key: 'entryTime', name: '入职时间', width: 140 },
  266. { key: 'workingTime', name: '从事检测工作(月)', width: 150 },
  267. { key: 'jobTitlePost', name: '工作职务', width: 120 },
  268. { key: 'idCard', name: '身份证号码', width: 180 },
  269. { key: 'birthday', name: '出生日期', width: 140 },
  270. { key: 'sex', name: '性别', width: 80 },
  271. { key: 'graduationSchool', name: '毕业院校' },
  272. { key: 'education', name: '学历', width: 120 },
  273. { key: 'major', name: '专业', width: 150 },
  274. { key: 'graduationDate', name: '毕业时间', width: 140 },
  275. { key: 'laborContractEndDate', name: '劳动合同终止日期', width: 140 },
  276. { key: 'mobilizationTime', name: '进场时间', width: 140 },
  277. { key: 'exitTime', name: '退场时间', width: 140 },
  278. ])
  279. //获取数据
  280. const tableLoading = ref(false)
  281. const tableData = ref([])
  282. const getTableData = async () => {
  283. tableLoading.value = true
  284. const { error, code, data } = await dataApi.queryPage({
  285. projectId: projectId.value,
  286. contractId: contractId.value,
  287. ...searchForm.value,
  288. })
  289. //处理数据
  290. tableLoading.value = false
  291. if (!error && code === 200) {
  292. tableData.value = getArrValue(data['records'])
  293. tableData.value.forEach((item) => {
  294. if (item?.workingTime == -1) {
  295. item.workingTime = ''
  296. }
  297. })
  298. searchForm.value.total = data.total || 0
  299. } else {
  300. tableData.value = []
  301. searchForm.value.total = 0
  302. }
  303. }
  304. //多选
  305. const tableCheckedKeys = ref([])
  306. const tableSelection = (rows) => {
  307. tableCheckedKeys.value = rows
  308. }
  309. //新增表单
  310. const addEditFormModal = ref(false)
  311. const addFormModalClick = () => {
  312. addEditFormModel.value = {
  313. status: 1, sex: 1, certificateType: '1', certificateMajor: '1', education: 1,
  314. }
  315. addEditFormModal.value = true
  316. }
  317. //编辑表单
  318. const editFormModalClick = () => {
  319. const keys = tableCheckedKeys.value
  320. if (keys.length === 1) {
  321. addEditFormModel.value = keys[0]
  322. addEditFormModel.value.certificateType = addEditFormModel.value.certificateType + ''
  323. addEditFormModel.value.certificateMajor = addEditFormModel.value.certificateMajor + ''
  324. addEditFormModal.value = true
  325. } else if (keys.length > 1) {
  326. window?.$message?.warning('只能选择一条数据编辑')
  327. }
  328. }
  329. //关闭表单
  330. const addEditFormModalClose = () => {
  331. addEditFormModal.value = false
  332. addEditFormModel.value = {}
  333. }
  334. //类型tab数据和相关处理
  335. const tabTypeKey = ref('tab1')
  336. const tabTypeTab = ref([
  337. { key: 'tab1', name: '基本信息' },
  338. { key: 'tab2', name: '证书信息' },
  339. { key: 'tab3', name: '工作记录' },
  340. ])
  341. const tabTypeChange = (item) => {
  342. tabTypeKey.value = item?.key
  343. }
  344. //新增/编辑 表单
  345. const addEditFormRef = ref(null)
  346. const addEditFormModel = ref({})
  347. const addEditFormRules = {
  348. name: {
  349. required: true,
  350. trigger: 'blur',
  351. validator: (rule, value, callback) => {
  352. if (!value) {
  353. callback(new Error('请输入姓名'))
  354. } else if (value.length > 5 || value.length < 2) {
  355. callback(new Error('姓名长度必须大于等于2并且小于等于5'))
  356. } else {
  357. callback()
  358. }
  359. },
  360. },
  361. idCard: {
  362. required: true,
  363. validator: (rule, value, callback) => {
  364. if (!value) {
  365. callback(new Error('请输入身份证号码'))
  366. } else if (!isIdCard(value)) {
  367. callback(new Error('身份证号码格式错误'))
  368. } else {
  369. callback()
  370. }
  371. },
  372. trigger: 'blur',
  373. },
  374. birthday: {
  375. required: true,
  376. trigger: 'blur',
  377. message: '请选择出生日期',
  378. },
  379. }
  380. //新增/编辑 保存
  381. const addEditFormLoading = ref(false)
  382. const addEditFormClick = async () => {
  383. const validate = await formValidate(addEditFormRef.value)
  384. if (validate) {
  385. addEditFormLoading.value = true
  386. addEditFormModel.value.workingTime = Number(addEditFormModel.value.workingTime)
  387. const { error, code } = await dataApi.submitForm({
  388. ...addEditFormModel.value,
  389. projectId: projectId.value,
  390. contractId: contractId.value,
  391. })
  392. //处理数据
  393. if (!error && code === 200) {
  394. window?.$message?.success('操作成功')
  395. addEditFormModal.value = false
  396. addEditFormLoading.value = false
  397. await getTableData()
  398. }
  399. addEditFormModal.value = false
  400. addEditFormLoading.value = false
  401. }
  402. }
  403. //删除
  404. const delModalClick = () => {
  405. delMessageV2(async (action, instance, done) => {
  406. if (action === 'confirm') {
  407. instance.confirmButtonLoading = true
  408. tableRemoveData()
  409. instance.confirmButtonLoading = false
  410. done()
  411. } else {
  412. done()
  413. }
  414. })
  415. }
  416. //批量删除
  417. const tableRemoveData = async () => {
  418. const rows = tableCheckedKeys.value
  419. if (rows.length > 0) {
  420. const ids = arrToId(rows)
  421. //删除请求
  422. const { error, code } = await dataApi.removeData({
  423. projectId: projectId.value,
  424. contractId: contractId.value,
  425. ids: ids,
  426. })
  427. //处理数据
  428. if (!error && code === 200) {
  429. window?.$message?.success('操作成功')
  430. searchClick()
  431. }
  432. }
  433. }
  434. </script>
  435. <style lang="scss" scoped>
  436. </style>