WorkTable.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <template>
  2. <div class="casually-name">
  3. <div class="star-title">
  4. <i></i>
  5. <span>工作经历</span>
  6. </div>
  7. <el-tag
  8. class="add-tag"
  9. type="primary"
  10. effect="plain"
  11. v-if="!tableData.length && !readOnly"
  12. @click="onAddItem(-1)"
  13. >+ 新增</el-tag
  14. >
  15. <el-table
  16. class="detail-table"
  17. :header-cell-style="{
  18. background: '#F2F4F8',
  19. color: '#000000'
  20. }"
  21. :data="tableData"
  22. >
  23. <el-table-column prop="workLocation" label="工作单位">
  24. <template #default="scope">
  25. <el-input v-model="scope.row.workLocation" v-if="scope.row.isEdit" />
  26. <span v-else>{{ scope.row.workLocation }}</span>
  27. </template>
  28. </el-table-column>
  29. <el-table-column prop="post" label="职位">
  30. <template #default="scope">
  31. <el-input v-model="scope.row.post" v-if="scope.row.isEdit" />
  32. <span v-else>{{ scope.row.post }}</span>
  33. </template>
  34. </el-table-column>
  35. <el-table-column prop="startTime" label="开始时间">
  36. <template #default="scope">
  37. <el-date-picker
  38. v-model="scope.row.startTime"
  39. type="date"
  40. format="YYYY-MM-DD"
  41. value-format="x"
  42. v-if="scope.row.isEdit"
  43. />
  44. <span v-else>{{ moment(scope.row.startTime).format('YYYY-MM-DD') }}</span>
  45. </template>
  46. </el-table-column>
  47. <el-table-column prop="endTime" label="结束时间">
  48. <template #default="scope">
  49. <el-date-picker
  50. v-model="scope.row.endTime"
  51. type="date"
  52. format="YYYY-MM-DD"
  53. value-format="x"
  54. v-if="scope.row.isEdit"
  55. />
  56. <span v-else>{{ moment(scope.row.endTime).format('YYYY-MM-DD') }}</span>
  57. </template>
  58. </el-table-column>
  59. <el-table-column prop="resignReason" label="离职原因">
  60. <template #default="scope">
  61. <el-input v-model="scope.row.resignReason" v-if="scope.row.isEdit" />
  62. <span v-else>{{ scope.row.resignReason }}</span>
  63. </template>
  64. </el-table-column>
  65. <el-table-column prop="jyxy" label="是否有竞业限制/未尽法律事宜">
  66. <template #default="scope">
  67. <el-input v-model="scope.row.jyxy" v-if="scope.row.isEdit" />
  68. <span v-else>{{ scope.row.jyxy }}</span>
  69. </template>
  70. </el-table-column>
  71. <el-table-column prop="competitionDetail" label="具体条款">
  72. <template #default="scope">
  73. <el-input v-model="scope.row.competitionDetail" v-if="scope.row.isEdit" />
  74. <span v-else>{{ scope.row.competitionDetail }}</span>
  75. </template>
  76. </el-table-column>
  77. <el-table-column fixed="right" label="操作" width="140" v-if="!readOnly">
  78. <template #default="scope">
  79. <el-button
  80. link
  81. type="primary"
  82. size="small"
  83. @click="onSaveItem(scope.$index)"
  84. v-if="scope.row.isEdit"
  85. >
  86. 保存
  87. </el-button>
  88. <el-button link type="primary" size="small" @click="onEditItem(scope.$index)" v-else>
  89. 编辑
  90. </el-button>
  91. <el-button link type="primary" size="small" @click="deleteRow(scope.$index)">
  92. 删除
  93. </el-button>
  94. <el-button link type="primary" size="small" @click="onAddItem(scope.$index)">
  95. 新增
  96. </el-button>
  97. </template>
  98. </el-table-column>
  99. </el-table>
  100. </div>
  101. </template>
  102. <script lang="ts" setup>
  103. /**
  104. * @description 工作经历
  105. */
  106. import { cloneDeep } from 'lodash-es'
  107. import moment from 'moment'
  108. interface ITable {
  109. id?: string
  110. userId?: string
  111. workLocation?: string // 工作单位
  112. post?: string // 职位
  113. startTime?: string // 开始时间
  114. endTime?: string // 结束时间
  115. resignReason?: string // 离职原因
  116. jyxy?: string // 是否有竞业限制/未尽法律事宜
  117. competitionDetail?: string // 具体条款
  118. isEdit?: boolean // 是否可编辑
  119. }
  120. const tableData = ref<ITable[]>([])
  121. const $emit = defineEmits<{
  122. (e: 'onSave', v: any): void
  123. }>()
  124. interface IProps {
  125. defaultData: any[]
  126. onlyRead?: boolean
  127. }
  128. const props = defineProps<IProps>()
  129. const { defaultData } = props
  130. const readOnly = ref(props.onlyRead)
  131. watch(
  132. () => props.onlyRead,
  133. (newVal) => {
  134. readOnly.value = newVal
  135. }
  136. )
  137. watch(
  138. () => props.defaultData,
  139. (newVal) => {
  140. tableData.value = newVal.map((item: any) => {
  141. return {
  142. ...item,
  143. isEdit: false
  144. }
  145. })
  146. }
  147. )
  148. onMounted(() => {
  149. if (defaultData && defaultData.length) {
  150. tableData.value = defaultData.map((item: any) => {
  151. return {
  152. ...item,
  153. isEdit: false
  154. }
  155. })
  156. }
  157. })
  158. // 新增行
  159. const onAddItem = (index: number) => {
  160. tableData.value.splice(index + 1, 0, {
  161. workLocation: '',
  162. post: '',
  163. startTime: '',
  164. endTime: '',
  165. resignReason: '',
  166. jyxy: '',
  167. competitionDetail: '',
  168. isEdit: true
  169. })
  170. }
  171. // 保存行
  172. const onSaveItem = (index: number) => {
  173. tableData.value.forEach((item: any, num: number) => {
  174. if (num == index) {
  175. item.isEdit = false
  176. }
  177. })
  178. const changeData = cloneDeep(tableData.value).map((item: any) => {
  179. delete item.isEdit
  180. return item
  181. })
  182. $emit('onSave', changeData)
  183. }
  184. // 编辑行
  185. const onEditItem = (index: number) => {
  186. tableData.value[index].isEdit = true
  187. }
  188. // 删除
  189. const deleteRow = (index: number) => {
  190. tableData.value.splice(index, 1)
  191. }
  192. </script>
  193. <style scoped lang="scss">
  194. .casually-name {
  195. position: relative;
  196. }
  197. .star-title {
  198. display: flex;
  199. align-items: center;
  200. margin-bottom: 8px;
  201. i {
  202. display: block;
  203. width: 16px;
  204. height: 16px;
  205. margin-right: 9px;
  206. background: url('../../../../assets/imgs/OA/mine/star.png') center no-repeat;
  207. background-size: 100%;
  208. }
  209. span {
  210. font-size: 18px;
  211. font-weight: bold;
  212. color: #000000;
  213. }
  214. }
  215. .add-tag {
  216. position: absolute;
  217. top: 2px;
  218. right: 0;
  219. cursor: pointer;
  220. }
  221. .detail-table {
  222. width: 100%;
  223. min-height: 100px;
  224. }
  225. </style>