<!-- 新增签名弹窗 -->
<script lang="ts" setup name="addNotice">
import type { FormInstance, FormRules } from 'element-plus'
import { ElLoading, ElMessage } from 'element-plus'
import dayjs from 'dayjs'
import type { signType } from '../../file/file-interface'
import showPhoto from '@/components/showPhoto/index.vue'
import { getUserList } from '@/api/system/user'
import { uploadApi } from '@/api/system/notice'
import { addApi, listPageDetailApi, updateApi } from '@/api/system/tool'
import type { userType } from '@/views/system/user/user-interface'
import canvasDialog from '@/components/canvas/canvasDialog.vue'
const emits = defineEmits(['resetData'])
const ruleFormRef = ref<FormInstance>() // from组件
const ruleForm = reactive<signType>({
userIdList: [], // 可使用人列表
signType: '', // 类型
signName: '', // 名称
signDirector: '', // 负责人
minioFileName: '', // 上传文件名
signDesc: '', // 描述
signNo: '',
createTime: '',
id: '',
signUserId: '', // 可使用人id
}) // 表单
const title = ref('')
const rules = ref<FormRules>({
userIdList: [{ required: true, message: '可使用人列表必填', trigger: 'blur' }],
signName: [{ required: true, message: '签名名称必填', trigger: 'blur' }],
signDirector: [{ required: true, message: '签名负责人必填', trigger: 'blur' }],
minioFileName: [{ required: true, message: '上传附件必填', trigger: 'blur' }],
signUserId: [{ required: true, message: '签名人员必填', trigger: 'blur' }],
}) // 表单验证规则
const dialogVisible = ref<boolean>(false) // 弹窗显示
const userList = ref<userType[]>([]) // 可使用人列表
const getuser = () => {
getUserList({ offset: 1, limit: 99999 }).then((res) => {
userList.value = res.data.rows
})
} // 获取可使用人列表
// 弹窗初始化
const initDialog = (row: signType) => {
title.value = row.title as string
ruleForm.signNo = ''
ruleForm.signName = ''
ruleForm.createTime = ''
ruleForm.signDesc = ''
ruleForm.minioFileName = ''
ruleForm.userIdList = []
ruleForm.signDirector = ''
ruleForm.id = ''
dialogVisible.value = true
if (row.title === '新增') {
// 新增
ruleFormRef.value?.resetFields()
ruleForm.createTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
}
// 修改
else if (row.title === '编辑') {
ruleForm.signNo = row.signNo
ruleForm.signName = row.signName
ruleForm.signDesc = row.signDesc
ruleForm.minioFileName = row.minioFileName
ruleForm.userIdList = row.userIdList
ruleForm.signDirector = row.signDirector
ruleForm.id = row.id
ruleForm.createTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
ruleForm.signUserId = row.signUserId
// 获取详情列表
// listPageDetailApi({ ...row }).then((res) => {
// ruleForm.id = res.data.id
// res.data.userList.forEach((element: userType) => {
// ruleForm.userIdList?.push(element.id)
// })
// })
}
else {
// 详情
ruleForm.signNo = row.signNo
ruleForm.signName = row.signName
ruleForm.createTime = row.createTime
ruleForm.signDesc = row.signDesc
ruleForm.minioFileName = row.minioFileName
ruleForm.userIdList = row.userIdList
ruleForm.signDirector = row.signDirector
ruleForm.signUserId = row.signUserId
// 获取详情列表
// listPageDetailApi({ ...row }).then((res) => {
// res.data.userList.forEach((element: userType) => {
// ruleForm.userIdList?.push(element.id)
// })
// })
}
ruleForm.signType = row.signType
getuser()
}
defineExpose({ initDialog })
// 关闭弹窗
const close = () => {
dialogVisible.value = false
emits('resetData')
}
const userListRef = ref()
// 多选可使用人列表
const multipleUser = () => {
userListRef.value.initDialog()
}
// 选择多选可使用人列表
const confirmUser = (data: userType) => {
ruleForm.signUserId = data.id
}
// 提交
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) { return }
await formEl.validate((valid, fields) => {
if (valid) {
if (title.value === '新增') {
userList.value.map((item) => {
if (item.id === ruleForm.signUserId) {
// 后台去掉校验去除赋值操作
ruleForm.signDirector = item.name
ruleForm.signName = item.name
ruleForm.userIdList = [ruleForm.signUserId]
}
})
addApi(ruleForm).then((res) => {
if (res.code === 200) {
ElMessage.success('新增成功')
close()
}
})
}
else {
userList.value.map((item) => {
if (item.id === ruleForm.signUserId) {
// 后台去掉校验去除赋值操作
ruleForm.signDirector = item.name
ruleForm.signName = item.name
ruleForm.userIdList = [ruleForm.signUserId]
}
})
updateApi(ruleForm).then((res) => {
if (res.code === 200) {
ElMessage.success('更新成功')
close()
}
})
}
}
})
}
// 取消
const resetForm = (formEl: FormInstance | undefined) => {
formEl?.resetFields()
dialogVisible.value = false
emits('resetData')
}
const fileRef = ref() // 文件上传input
const onFileChange = (event: any) => {
// 原生上传
// console.log(event.target.files)
if (event.target.files?.length !== 0) {
// 创建formdata对象
const fd = new FormData()
fd.append('multipartFile', event.target.files[0])
const loading = ElLoading.service({
lock: true,
background: 'rgba(255, 255, 255, 0.8)',
})
uploadApi(fd).then((res) => {
if (res.code === 200) {
ruleFormRef.value?.clearValidate('minioFileName')
ruleForm.minioFileName = res.data[0]
ElMessage.success('上传成功')
loading.close()
}
else {
ElMessage.error(res.message)
loading.close()
}
})
}
}
const upload = () => {
fileRef.value.click()
}
const canvasDialogRef = ref() // 画布组件ref
const $router = useRouter()
// 点击手写签名
const handWritten = () => {
canvasDialogRef.value.initDialog()
}
// 第一个参数dataUrl是一个base64的字符串。第二个参数是文件名可以随意命名
function base64toFile(dataurl: string, filename = 'file') {
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)![1]
// suffix是该文件的后缀
const suffix = mime.split('/')[1]
// atob 对经过 base-64 编码的字符串进行解码
const bstr = atob(arr[1])
// n 是解码后的长度
let n = bstr.length
// Uint8Array 数组类型表示一个 8 位无符号整型数组 初始值都是 数子0
const u8arr = new Uint8Array(n)
// charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
// new File返回File对象 第一个参数是 ArraryBuffer 或 Bolb 或Arrary 第二个参数是文件名
// 第三个参数是 要放到文件中的内容的 MIME 类型
return new File([u8arr], `${filename}.${suffix}`, {
type: mime,
})
}
// 签字后点击确定
const signPicture = (picture: any) => {
// 创建formdata对象
const fd = new FormData()
fd.append('multipartFile', base64toFile(picture))
const loading = ElLoading.service({
lock: true,
background: 'rgba(255, 255, 255, 0.8)',
})
uploadApi(fd).then((res) => {
if (res.code === 200) {
ruleFormRef.value?.clearValidate('minioFileName')
ruleForm.minioFileName = res.data[0]
ElMessage.success('上传成功')
canvasDialogRef.value.close() // 关闭对话框
loading.close()
}
else {
ElMessage.error(res.message)
loading.close()
}
})
}
</script>
<template>
<el-dialog v-if="dialogVisible" v-model="dialogVisible" :title="title" width="65%" append-to-body class="container" @close="resetForm">
<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-position="right" label-width="110px" :class="[title === '详情' ? 'isDetail' : '']">
<el-form-item label="签名人员" prop="signUserId" style="flex-wrap: nowrap;">
<div style="display: flex;width: 100%;">
<el-select v-model="ruleForm.signUserId" filterable clearable :placeholder="title === '详情' ? '暂无签名人员' : '请选择签名人员'" :disabled="title === '详情'" style="width: 100%;">
<el-option v-for="(item) in userList" :key="item.id" :label="item.name" :value="item.id">
<span style="float: left;">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px;">{{ item.deptName }}</span>
</el-option>
</el-select>
<!-- <el-button v-if="title !== '详情'" @click="multipleUser">
选择
</el-button> -->
</div>
</el-form-item>
<el-form-item label="签名图片" prop="minioFileName">
<show-photo :minio-file-name="ruleForm.minioFileName" width="400px" height="300px" fit="contain" />
<el-button v-if="title !== '详情'" type="primary" :disabled="title === '详情'" :style="{ 'margin-left': ruleForm.minioFileName === '' ? '0px' : '20px', 'margin-top': ruleForm.minioFileName === '' ? '0px' : '56px' }" @click="upload">
{{ ruleForm.minioFileName === '' ? '上传' : '更换图片' }}
</el-button>
<el-button v-if="title !== '详情'" type="primary" :disabled="title === '详情'" :style="{ 'margin-left': ruleForm.minioFileName === '' ? '10px' : '20px', 'margin-top': ruleForm.minioFileName === '' ? '0px' : '56px' }" @click="handWritten">
{{ ruleForm.minioFileName === '' ? '手写签名' : '重新签名' }}
</el-button>
<input v-show="title === '123'" ref="fileRef" type="file" accept="image/*" @change="onFileChange">
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer footer">
<el-button v-if="title !== '详情'" type="primary" @click="submitForm(ruleFormRef)">
发布
</el-button>
<el-button @click="resetForm(ruleFormRef)">
关闭
</el-button>
</div>
</template>
<!-- 多选用户弹窗 -->
<user-list-comp ref="userListRef" @add="confirmUser" />
<!-- 画布组件 -->
<canvas-dialog ref="canvasDialogRef" @signPicture="signPicture" />
</el-dialog>
</template>
<style lang="scss" scoped>
.container {
.isDetail {
::v-deep {
.el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap > .el-form-item__label::before,
.el-form-item.is-required:not(.is-no-asterisk) > .el-form-item__label::before {
content: "";
display: none;
}
}
}
.center {
display: flex;
align-items: flex-end;
}
}
</style>