综合办公系统
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

staffDetail.vue 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. <template>
  2. <view class="container">
  3. <!-- 头部信息 -->
  4. <view class="header-section">
  5. <view class="avatar-section">
  6. <uv-avatar :src="staffInfo.avatar || '/static/images/user.png'" size="120" />
  7. </view>
  8. <view class="basic-info">
  9. <view class="name">{{ staffInfo.nickName }}</view>
  10. <view class="dept">{{ staffInfo.dept ? staffInfo.dept.deptName : '未分配部门' }}</view>
  11. <view class="status">
  12. <u-tag :text="getStatusText(staffInfo.status)" :type="getStatusType(staffInfo.status)" />
  13. </view>
  14. </view>
  15. </view>
  16. <!-- 基本信息 -->
  17. <view class="info-section">
  18. <view class="section-title">基本信息</view>
  19. <view class="info-grid">
  20. <view class="info-item">
  21. <text class="label">姓名</text>
  22. <text class="value">{{ staffInfo.nickName }}</text>
  23. </view>
  24. <view class="info-item">
  25. <text class="label">年龄</text>
  26. <text class="value">{{ String(getAgeByIdCard(staffInfo.idCard)).slice(0, 2) }}岁</text>
  27. </view>
  28. <view class="info-item">
  29. <text class="label">性别</text>
  30. <text class="value">{{ staffInfo.sex == 0 ? '男' : '女' }}</text>
  31. </view>
  32. <view class="info-item">
  33. <text class="label">手机号码</text>
  34. <text class="value">{{ staffInfo.phonenumber || '' }}</text>
  35. </view>
  36. <view class="info-item">
  37. <text class="label">身份证</text>
  38. <text class="value">{{ staffInfo.idCard || '' }}</text>
  39. </view>
  40. <view class="info-item">
  41. <text class="label">籍贯</text>
  42. <text class="value">{{ staffInfo.nativePlace || '' }}</text>
  43. </view>
  44. <view class="info-item">
  45. <text class="label">民族</text>
  46. <text class="value">{{ staffInfo.ethnic || '' }}</text>
  47. </view>
  48. <view class="info-item">
  49. <text class="label">政治面貌</text>
  50. <text class="value">{{ getPoliticalText(staffInfo.politicalAffiliation) || '' }}</text>
  51. </view>
  52. </view>
  53. </view>
  54. <!-- 工作信息 -->
  55. <view class="info-section">
  56. <view class="section-title">工作信息</view>
  57. <view class="info-grid">
  58. <view class="info-item">
  59. <text class="label">部门</text>
  60. <text class="value">{{ staffInfo.dept ? staffInfo.dept.deptName : '未分配部门' }}</text>
  61. </view>
  62. <view class="info-item">
  63. <text class="label">职务</text>
  64. <text class="value">{{ postData || '' }}</text>
  65. </view>
  66. <view class="info-item">
  67. <text class="label">职称</text>
  68. <text class="value">{{ titlesMap[staffInfo.titles] || '' }}</text>
  69. </view>
  70. <view class="info-item">
  71. <text class="label">职业资格</text>
  72. <text class="value">{{ getCertificateText(staffInfo.certificates) || '' }}</text>
  73. </view>
  74. <view class="info-item">
  75. <text class="label">岗级</text>
  76. <text class="value">{{ getPostLevelText(staffInfo.postLevel, staffInfo.salaryLevel) || '' }}</text>
  77. </view>
  78. <view class="info-item">
  79. <text class="label">工程师岗级</text>
  80. <text class="value">{{ engineerLevelData[staffInfo.engineerLevel] || '' }}</text>
  81. </view>
  82. <view class="info-item">
  83. <text class="label">技工等级</text>
  84. <text class="value">{{ operatorLevelData[staffInfo.operatorLevel] || '' }}</text>
  85. </view>
  86. <view class="info-item">
  87. <text class="label">项目经理等级</text>
  88. <text class="value">{{ pmLevelData[staffInfo.pmLevel] || '' }}</text>
  89. </view>
  90. <view class="info-item">
  91. <text class="label">入职时间</text>
  92. <text class="value">{{ parseTime(staffInfo.entryDate, "{y}-{m}-{d}") || '' }}</text>
  93. </view>
  94. <view class="info-item">
  95. <text class="label">合同签订</text>
  96. <text class="value">{{ parseTime(staffInfo.contractSign, "{y}-{m}-{d}") || '' }}</text>
  97. </view>
  98. <view class="info-item">
  99. <text class="label">合同期满</text>
  100. <text class="value">{{ parseTime(staffInfo.contractExpire, "{y}-{m}-{d}") || '' }}</text>
  101. </view>
  102. </view>
  103. </view>
  104. <!-- 教育背景 -->
  105. <view class="info-section">
  106. <view class="section-title">教育背景</view>
  107. <view class="info-grid">
  108. <view class="info-item">
  109. <text class="label">最高学历</text>
  110. <text class="value">{{ getDegreeText(staffInfo.degree) || '' }}</text>
  111. </view>
  112. <view class="info-item">
  113. <text class="label">最高学历专业</text>
  114. <text class="value">{{ staffInfo.major || '' }}</text>
  115. </view>
  116. <view class="info-item">
  117. <text class="label">最高学历毕业院校</text>
  118. <text class="value">{{ staffInfo.graduateSchool || '' }}</text>
  119. </view>
  120. <view class="info-item">
  121. <text class="label">初始学历</text>
  122. <text class="value">{{ getDegreeText(staffInfo.initialDegree) || '' }}</text>
  123. </view>
  124. <view class="info-item">
  125. <text class="label">初始学历专业</text>
  126. <text class="value">{{ staffInfo.initialMajor || '' }}</text>
  127. </view>
  128. <view class="info-item">
  129. <text class="label">初始学历毕业院校</text>
  130. <text class="value">{{ staffInfo.initialSchool || '' }}</text>
  131. </view>
  132. </view>
  133. </view>
  134. <!-- 其他信息 -->
  135. <view class="info-section">
  136. <view class="section-title">其他信息</view>
  137. <view class="info-grid">
  138. <view class="info-item">
  139. <text class="label">家庭住址</text>
  140. <text class="value">{{ staffInfo.homePlace || '' }}</text>
  141. </view>
  142. <view class="info-item">
  143. <text class="label">紧急联系人</text>
  144. <text class="value">{{ staffInfo.contact || '' }}</text>
  145. </view>
  146. <view class="info-item">
  147. <text class="label">紧急联系电话</text>
  148. <text class="value">{{ staffInfo.telephone || '' }}</text>
  149. </view>
  150. <view class="info-item">
  151. <text class="label">备注</text>
  152. <text class="value">{{ staffInfo.remark || '无' }}</text>
  153. </view>
  154. </view>
  155. </view>
  156. </view>
  157. </template>
  158. <script>
  159. import { parseTime } from "@/utils/common.js"
  160. import { getUser } from "@/api/system/user"
  161. import { listType, getType } from "@/api/system/dict/type"
  162. import { listData } from "@/api/system/dict/data"
  163. export default {
  164. data() {
  165. return {
  166. staffInfo: {},
  167. userId: '',
  168. nickName: '',
  169. postData: '',
  170. engineerLevelData: {},
  171. operatorLevelData: {},
  172. pmLevelData: {},
  173. politicalMap: {},
  174. titlesMap: {},
  175. certificateMap: {},
  176. postLevelMap: {},
  177. salaryLevelMap: {}
  178. }
  179. },
  180. onLoad(options) {
  181. this.userId = options.userId
  182. this.nickName = options.nickName
  183. this.getDictLabelValue();
  184. this.getStaffInfo();
  185. },
  186. methods: {
  187. parseTime,
  188. // 获取员工信息
  189. async getStaffInfo() {
  190. try {
  191. const res = await getUser(this.userId);
  192. this.staffInfo = res.data;
  193. let postArr = [];
  194. for (let post of res.posts) {
  195. for (let postid of res.postIds) {
  196. if (postid == post.postId) {
  197. postArr.push(post.postName)
  198. }
  199. }
  200. }
  201. this.postData = postArr.join('/')
  202. } catch (error) {
  203. console.error('获取员工信息失败:', error);
  204. uni.showToast({
  205. title: '获取员工信息失败',
  206. icon: 'none'
  207. });
  208. }
  209. },
  210. getDictLabelValue() {
  211. listData({ pageSize: 100, dictType: 'sys_user_engineerlevel' }).then(res => {
  212. res.rows.map(item => {
  213. this.engineerLevelData[item.dictValue] = item.dictLabel
  214. })
  215. })
  216. listData({ pageSize: 100, dictType: 'sys_user_operatorlevel' }).then(res => {
  217. res.rows.map(item => {
  218. this.operatorLevelData[item.dictValue] = item.dictLabel
  219. })
  220. })
  221. listData({ pageSize: 100, dictType: 'sys_user_pmlevel' }).then(res => {
  222. res.rows.map(item => {
  223. this.pmLevelData[item.dictValue] = item.dictLabel
  224. })
  225. })
  226. listData({ pageSize: 100, dictType: 'sys_user_political' }).then(res => {
  227. res.rows.map(item => {
  228. this.politicalMap[item.dictValue] = item.dictLabel
  229. })
  230. })
  231. listData({ pageSize: 100, dictType: 'sys_user_titles' }).then(res => {
  232. res.rows.map(item => {
  233. this.titlesMap[item.dictValue] = item.dictLabel
  234. })
  235. })
  236. listData({ pageSize: 100, dictType: 'sys_user_certificates' }).then(res => {
  237. res.rows.map(item => {
  238. this.certificateMap[item.dictValue] = item.dictLabel
  239. })
  240. })
  241. listData({ pageSize: 100, dictType: 'sys_user_postlevel' }).then(res => {
  242. res.rows.map(item => {
  243. this.postLevelMap[item.dictValue] = item.dictLabel
  244. })
  245. })
  246. listData({ pageSize: 100, dictType: 'sys_user_salarylevel' }).then(res => {
  247. res.rows.map(item => {
  248. this.salaryLevelMap[item.dictValue] = item.dictLabel
  249. })
  250. })
  251. },
  252. // 获取状态文本
  253. getStatusText(status) {
  254. const statusMap = {
  255. '0': '在职',
  256. '1': '离职',
  257. '2': '退休',
  258. '3': '试用',
  259. '4': '返聘'
  260. };
  261. return statusMap[status] || '未知';
  262. },
  263. // 获取状态类型
  264. getStatusType(status) {
  265. const typeMap = {
  266. '0': 'success',
  267. '1': 'error',
  268. '2': 'warning',
  269. '3': 'primary',
  270. '4': 'info'
  271. };
  272. return typeMap[status] || 'default';
  273. },
  274. // 根据身份证计算年龄
  275. getAgeByIdCard(idCard) {
  276. if (!idCard) return 0;
  277. const birthStr = idCard.substring(6, 14);
  278. const birthYear = parseInt(birthStr.substring(0, 4), 10);
  279. const birthMonth = parseInt(birthStr.substring(4, 6), 10) - 1;
  280. const birthDay = parseInt(birthStr.substring(6, 8), 10);
  281. const birthDate = new Date(birthYear, birthMonth, birthDay);
  282. const now = new Date();
  283. let age = now.getFullYear() - birthDate.getFullYear();
  284. const monthDiff = now.getMonth() - birthDate.getMonth();
  285. if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < birthDate.getDate())) {
  286. age--;
  287. }
  288. return age;
  289. },
  290. // 获取政治面貌文本
  291. getPoliticalText(politicalAffiliation) {
  292. if (!politicalAffiliation) return '';
  293. const politicalArray = politicalAffiliation.split(',');
  294. let politicalText = politicalArray.map(political => this.politicalMap[political] || political).join('、');
  295. return politicalText;
  296. },
  297. // 获取职业资格文本
  298. getCertificateText(certificates) {
  299. if (!certificates) return '';
  300. const certArray = certificates.split(',');
  301. return certArray.map(cert => this.certificateMap[cert] || cert).join('、');
  302. },
  303. // 获取岗级文本
  304. getPostLevelText(postLevel, salaryLevel) {
  305. const postText = this.postLevelMap[postLevel] || '';
  306. const salaryText = this.salaryLevelMap[salaryLevel] || '';
  307. return postText && salaryText ? `${postText}${salaryText}` : '';
  308. },
  309. // 获取学历文本
  310. getDegreeText(degree) {
  311. const degreeMap = {
  312. '0': '博士',
  313. '1': '硕士',
  314. '2': '本科',
  315. '3': '专科',
  316. '4': '高中',
  317. '5': '中专',
  318. '6': '初中'
  319. };
  320. return degreeMap[degree] || '';
  321. },
  322. },
  323. }
  324. </script>
  325. <style lang="scss" scoped>
  326. .container {
  327. background-color: #f5f5f5;
  328. min-height: 100vh;
  329. padding: 30rpx;
  330. padding-bottom: 120rpx;
  331. }
  332. .header-section {
  333. background-color: #fff;
  334. padding: 40rpx 30rpx;
  335. display: flex;
  336. align-items: center;
  337. margin-bottom: 20rpx;
  338. .avatar-section {
  339. margin-right: 30rpx;
  340. }
  341. .basic-info {
  342. flex: 1;
  343. .name {
  344. font-size: 36rpx;
  345. font-weight: bold;
  346. color: #333;
  347. margin-bottom: 10rpx;
  348. }
  349. .dept {
  350. font-size: 28rpx;
  351. color: #666;
  352. margin-bottom: 15rpx;
  353. }
  354. .status {
  355. display: inline-block;
  356. }
  357. }
  358. }
  359. .info-section {
  360. background-color: #fff;
  361. margin-bottom: 20rpx;
  362. padding: 30rpx;
  363. .section-title {
  364. font-size: 32rpx;
  365. font-weight: bold;
  366. color: #333;
  367. margin-bottom: 30rpx;
  368. border-left: 6rpx solid #007aff;
  369. padding-left: 20rpx;
  370. }
  371. .info-grid {
  372. .info-item {
  373. display: flex;
  374. margin-bottom: 25rpx;
  375. .label {
  376. width: 200rpx;
  377. font-size: 28rpx;
  378. color: #666;
  379. }
  380. .value {
  381. flex: 1;
  382. font-size: 28rpx;
  383. color: #333;
  384. word-break: break-all;
  385. }
  386. }
  387. }
  388. }
  389. .action-section {
  390. position: fixed;
  391. bottom: 0;
  392. left: 0;
  393. right: 0;
  394. background-color: #fff;
  395. padding: 20rpx 30rpx;
  396. border-top: 1rpx solid #eee;
  397. .uv-button {
  398. width: 100%;
  399. }
  400. }
  401. </style>