|
@@ -1,40 +1,259 @@
|
|
-<script setup lang="ts">
|
|
|
|
-const tableData = [
|
|
|
|
- // {
|
|
|
|
- // date: '2016-05-03',
|
|
|
|
- // name: '测绘质量检测技术',
|
|
|
|
- // level: '高级',
|
|
|
|
- // organization: '浙江省测绘与地理信息行业协会'
|
|
|
|
- // },
|
|
|
|
- // {
|
|
|
|
- // date: '2016-05-02',
|
|
|
|
- // name: '职称证书',
|
|
|
|
- // level: '中级',
|
|
|
|
- // organization: '浙江省测绘与地理信息行业协会'
|
|
|
|
- // }
|
|
|
|
-]
|
|
|
|
-</script>
|
|
|
|
-
|
|
|
|
<template>
|
|
<template>
|
|
- <el-table
|
|
|
|
- :header-cell-style="{
|
|
|
|
- background: '#F2F4F8',
|
|
|
|
- color: '#000000',
|
|
|
|
- height: '46px'
|
|
|
|
- }"
|
|
|
|
- style="width: 100%; height: 100%"
|
|
|
|
- :data="tableData"
|
|
|
|
- height="150px"
|
|
|
|
- >
|
|
|
|
- <el-table-column type="index" width="50" />
|
|
|
|
- <el-table-column prop="name" label="证书名称" />
|
|
|
|
- <el-table-column prop="level" label="证书等级" />
|
|
|
|
- <el-table-column prop="date" label="获得时间" />
|
|
|
|
- <el-table-column prop="organization" label="发证机构" />
|
|
|
|
- <el-table-column fixed="right" label="操作" width="120">
|
|
|
|
- <template #default>
|
|
|
|
- <el-button link type="primary" size="small">查看</el-button>
|
|
|
|
- </template>
|
|
|
|
- </el-table-column>
|
|
|
|
- </el-table>
|
|
|
|
|
|
+ <div class="casually-name">
|
|
|
|
+ <div class="star-title">
|
|
|
|
+ <i></i>
|
|
|
|
+ <span>技能证书</span>
|
|
|
|
+ </div>
|
|
|
|
+ <el-tag
|
|
|
|
+ class="add-tag"
|
|
|
|
+ type="primary"
|
|
|
|
+ effect="plain"
|
|
|
|
+ v-if="!tableData.length && !readOnly"
|
|
|
|
+ @click="onAddItem(-1)"
|
|
|
|
+ >+ 新增</el-tag
|
|
|
|
+ >
|
|
|
|
+ <el-table
|
|
|
|
+ class="detail-table"
|
|
|
|
+ :header-cell-style="{
|
|
|
|
+ background: '#F2F4F8',
|
|
|
|
+ color: '#000000'
|
|
|
|
+ }"
|
|
|
|
+ :data="tableData"
|
|
|
|
+ >
|
|
|
|
+ <el-table-column prop="certName" label="证书名称">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <el-input v-model="scope.row.certName" v-if="scope.row.isEdit" />
|
|
|
|
+ <span v-else>{{ scope.row.certName }}</span>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column prop="zcjb" label="证书等级">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <el-input v-model="scope.row.zcjb" v-if="scope.row.isEdit" />
|
|
|
|
+ <span v-else>{{ scope.row.zcjb }}</span>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column prop="acTime" label="获得时间">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-model="scope.row.acTime"
|
|
|
|
+ type="date"
|
|
|
|
+ format="YYYY-MM-DD"
|
|
|
|
+ value-format="x"
|
|
|
|
+ v-if="scope.row.isEdit"
|
|
|
|
+ />
|
|
|
|
+ <span v-else>{{ moment(scope.row.acTime).format('YYYY-MM-DD') }}</span>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column prop="certDetail" label="证书情况">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <el-input v-model="scope.row.certDetail" v-if="scope.row.isEdit" />
|
|
|
|
+ <span v-else>{{ scope.row.certDetail }}</span>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column prop="filePath" label="附件" width="400px">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <UploadImgs
|
|
|
|
+ :modelValue="imageUrl(scope.row.filePath)"
|
|
|
|
+ :updateUrl="updateUrl"
|
|
|
|
+ height="55px"
|
|
|
|
+ :limit="1"
|
|
|
|
+ v-if="scope.row.isEdit"
|
|
|
|
+ :callback="(file) => onUploadSuccess(file, scope.$index)"
|
|
|
|
+ />
|
|
|
|
+ <div v-else>
|
|
|
|
+ <span
|
|
|
|
+ style="margin-left: 3px"
|
|
|
|
+ v-for="(item, index) in getImgUrlList(scope.row.filePath)"
|
|
|
|
+ :key="index"
|
|
|
|
+ >
|
|
|
|
+ <el-image
|
|
|
|
+ style="width: 100px; height: 100px"
|
|
|
|
+ :src="item"
|
|
|
|
+ fit="scale-down"
|
|
|
|
+ :preview-src-list="[item]"
|
|
|
|
+ />
|
|
|
|
+ </span>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column fixed="right" label="操作" width="140" v-if="!readOnly">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <el-button
|
|
|
|
+ link
|
|
|
|
+ type="primary"
|
|
|
|
+ size="small"
|
|
|
|
+ @click="onSaveItem(scope.$index)"
|
|
|
|
+ v-if="scope.row.isEdit"
|
|
|
|
+ >
|
|
|
|
+ 保存
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button link type="primary" size="small" @click="onEditItem(scope.$index)" v-else>
|
|
|
|
+ 编辑
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button link type="primary" size="small" @click="deleteRow(scope.$index)">
|
|
|
|
+ 删除
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button link type="primary" size="small" @click="onAddItem(scope.$index)">
|
|
|
|
+ 新增
|
|
|
|
+ </el-button>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
+/**
|
|
|
|
+ * @description 技能证书
|
|
|
|
+ */
|
|
|
|
+import { cloneDeep } from 'lodash-es'
|
|
|
|
+import moment from 'moment'
|
|
|
|
+import { UploadImgs } from '@/components/UploadFile'
|
|
|
|
+
|
|
|
|
+// 上传路径
|
|
|
|
+const updateUrl =
|
|
|
|
+ import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + import.meta.env.VITE_UPLOAD_URL
|
|
|
|
+
|
|
|
|
+interface ITable {
|
|
|
|
+ id?: string
|
|
|
|
+ userId?: string
|
|
|
|
+ nickname?: string // 姓名
|
|
|
|
+ deptId?: string // 部门id
|
|
|
|
+ deptName?: string // 部门名称
|
|
|
|
+ zcjb?: string // 职称级别
|
|
|
|
+ certName?: string // 专业/资格名称
|
|
|
|
+ acTime?: string // 取得时间
|
|
|
|
+ exTime?: string // 注册到期时间
|
|
|
|
+ certDetail?: string // 证书情况
|
|
|
|
+ filePath?: string // 原件地址
|
|
|
|
+ isEdit?: boolean
|
|
|
|
+}
|
|
|
|
+const tableData = ref<ITable[]>([])
|
|
|
|
+
|
|
|
|
+const $emit = defineEmits<{
|
|
|
|
+ (e: 'onSave', v: any): void
|
|
|
|
+}>()
|
|
|
|
+
|
|
|
|
+interface IProps {
|
|
|
|
+ defaultData: any[]
|
|
|
|
+ onlyRead?: boolean
|
|
|
|
+}
|
|
|
|
+const props = defineProps<IProps>()
|
|
|
|
+const { defaultData } = props
|
|
|
|
+const readOnly = ref(props.onlyRead)
|
|
|
|
+watch(
|
|
|
|
+ () => props.onlyRead,
|
|
|
|
+ (newVal) => {
|
|
|
|
+ readOnly.value = newVal
|
|
|
|
+ }
|
|
|
|
+)
|
|
|
|
+watch(
|
|
|
|
+ () => props.defaultData,
|
|
|
|
+ (newVal) => {
|
|
|
|
+ tableData.value = newVal.map((item: any) => {
|
|
|
|
+ return {
|
|
|
|
+ ...item,
|
|
|
|
+ isEdit: false
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+)
|
|
|
|
+onMounted(() => {
|
|
|
|
+ if (defaultData && defaultData.length) {
|
|
|
|
+ tableData.value = defaultData.map((item: any) => {
|
|
|
|
+ return {
|
|
|
|
+ ...item,
|
|
|
|
+ isEdit: false
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+// 新增行
|
|
|
|
+const onAddItem = (index: number) => {
|
|
|
|
+ tableData.value.splice(index + 1, 0, {
|
|
|
|
+ zcjb: '',
|
|
|
|
+ certName: '',
|
|
|
|
+ acTime: '',
|
|
|
|
+ exTime: '',
|
|
|
|
+ certDetail: '',
|
|
|
|
+ filePath: '',
|
|
|
|
+ isEdit: true
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 保存行
|
|
|
|
+const onSaveItem = (index: number) => {
|
|
|
|
+ tableData.value.forEach((item: any, num: number) => {
|
|
|
|
+ if (num == index) {
|
|
|
|
+ item.isEdit = false
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ const changeData = cloneDeep(tableData.value).map((item: any) => {
|
|
|
|
+ delete item.isEdit
|
|
|
|
+ return item
|
|
|
|
+ })
|
|
|
|
+ $emit('onSave', changeData)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 编辑行
|
|
|
|
+const onEditItem = (index: number) => {
|
|
|
|
+ tableData.value[index].isEdit = true
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 删除
|
|
|
|
+const deleteRow = (index: number) => {
|
|
|
|
+ tableData.value.splice(index, 1)
|
|
|
|
+}
|
|
|
|
+// 回填正确路径
|
|
|
|
+const imageUrl = (url) => {
|
|
|
|
+ if (!url) return []
|
|
|
|
+ return url.split(',').map((item, index) => ({
|
|
|
|
+ url: item,
|
|
|
|
+ uid: index
|
|
|
|
+ }))
|
|
|
|
+}
|
|
|
|
+const getImgUrlList = (url) => {
|
|
|
|
+ if (!url) return []
|
|
|
|
+ return url.split(',')
|
|
|
|
+}
|
|
|
|
+// 附件上传成功
|
|
|
|
+const onUploadSuccess = (file: any, index) => {
|
|
|
|
+ const fileList = file.map((item) => item.url)
|
|
|
|
+ tableData.value[index].filePath = fileList.join(',')
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
+.casually-name {
|
|
|
|
+ position: relative;
|
|
|
|
+}
|
|
|
|
+.star-title {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
+
|
|
|
|
+ i {
|
|
|
|
+ display: block;
|
|
|
|
+ width: 16px;
|
|
|
|
+ height: 16px;
|
|
|
|
+ margin-right: 9px;
|
|
|
|
+ background: url('../../../../assets/imgs/OA/mine/star.png') center no-repeat;
|
|
|
|
+ background-size: 100%;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ span {
|
|
|
|
+ font-size: 18px;
|
|
|
|
+ font-weight: bold;
|
|
|
|
+ color: #000000;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.add-tag {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 2px;
|
|
|
|
+ right: 0;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+}
|
|
|
|
+.detail-table {
|
|
|
|
+ width: 100%;
|
|
|
|
+ min-height: 100px;
|
|
|
|
+}
|
|
|
|
+</style>
|