2024-02-05 09:15:37 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<a-modal
|
|
|
|
|
|
v-model:visible="data.visible"
|
|
|
|
|
|
:maskClosable="false"
|
|
|
|
|
|
:width="600"
|
|
|
|
|
|
:title="title"
|
|
|
|
|
|
@ok="submit"
|
|
|
|
|
|
@cancel="close"
|
|
|
|
|
|
:okText="t('确认')"
|
|
|
|
|
|
:cancelText="t('取消')"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="box" v-if="data.visible">
|
|
|
|
|
|
<a-form
|
|
|
|
|
|
:model="data.info"
|
|
|
|
|
|
ref="formRef"
|
|
|
|
|
|
name="basic"
|
|
|
|
|
|
:label-col="{ span: 4 }"
|
|
|
|
|
|
:wrapper-col="{ span: 20 }"
|
|
|
|
|
|
autocomplete="off"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-form-item
|
|
|
|
|
|
:label="t('签章名称')"
|
|
|
|
|
|
name="name"
|
|
|
|
|
|
:rules="[{ required: true, message: t('请填写签章名称!') }]"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-input
|
|
|
|
|
|
:placeholder="t('请填写签章名称')"
|
|
|
|
|
|
v-model:value="data.info.name"
|
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item
|
|
|
|
|
|
:label="t('印章分类')"
|
|
|
|
|
|
name="stampCategory"
|
|
|
|
|
|
:rules="[{ required: true, message: t('请填写印章分类!') }]"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-select
|
|
|
|
|
|
v-model:value="data.info.stampCategory"
|
|
|
|
|
|
:placeholder="t('请选择印章分类')"
|
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-select-option v-for="item in data.categoryOptions" :key="item.id" :value="item.id">
|
|
|
|
|
|
{{ item.name }}
|
|
|
|
|
|
</a-select-option>
|
|
|
|
|
|
</a-select>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item
|
|
|
|
|
|
:label="t('签章密码')"
|
|
|
|
|
|
name="password"
|
|
|
|
|
|
:rules="[{ required: true, message: t('请填写签章密码!') }]"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-input-password
|
|
|
|
|
|
:placeholder="t('请填写签章密码')"
|
|
|
|
|
|
v-model:value="data.info.password"
|
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item
|
|
|
|
|
|
:label="t('签章排序')"
|
|
|
|
|
|
name="sortCode"
|
|
|
|
|
|
:rules="[{ required: true, message: t('请填写签章排序!') }]"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-input-number
|
|
|
|
|
|
:placeholder="t('请填写签章排序')"
|
|
|
|
|
|
v-model:value="data.info.sortCode"
|
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item
|
|
|
|
|
|
:label="t('签章类型')"
|
|
|
|
|
|
name="fileType"
|
|
|
|
|
|
:rules="[{ required: true, message: t('请填写签章类型!') }]"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-radio-group v-model:value="data.info.fileType" name="radioGroup">
|
|
|
|
|
|
<a-radio :value="StampFileTypeAttributes.UPLOAD_PICTURES">{{ t('上传照片') }}</a-radio>
|
|
|
|
|
|
<a-radio :value="StampFileTypeAttributes.HANDWRITTEN_SIGNATURE">{{
|
|
|
|
|
|
t('手写签名')
|
|
|
|
|
|
}}</a-radio>
|
|
|
|
|
|
</a-radio-group>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item
|
|
|
|
|
|
:label="t('上传照片')"
|
|
|
|
|
|
name="fileUrl"
|
|
|
|
|
|
v-if="data.info.fileType === StampFileTypeAttributes.UPLOAD_PICTURES"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-upload
|
|
|
|
|
|
v-if="data.info.fileType === StampFileTypeAttributes.UPLOAD_PICTURES"
|
|
|
|
|
|
name="file"
|
|
|
|
|
|
accept="image/*"
|
|
|
|
|
|
:headers="data.headers"
|
|
|
|
|
|
:max-count="1"
|
|
|
|
|
|
:showUploadList="false"
|
|
|
|
|
|
:action="data.action"
|
|
|
|
|
|
list-type="picture-card"
|
|
|
|
|
|
@change="photoChange"
|
|
|
|
|
|
>
|
|
|
|
|
|
<img v-if="data.photoUrl" :src="data.photoUrl" />
|
|
|
|
|
|
<div v-else>{{ t('点击上传照片') }}</div>
|
2025-07-17 14:56:20 +08:00
|
|
|
|
<div v-if="VITE_GLOB_UPLOAD_ALERT_TIP?.trim()" style="color: red; margin-top: 8px;">
|
|
|
|
|
|
{{VITE_GLOB_UPLOAD_ALERT_TIP}}
|
|
|
|
|
|
</div>
|
2024-02-05 09:15:37 +08:00
|
|
|
|
</a-upload>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item
|
|
|
|
|
|
:label="t('手写签名')"
|
|
|
|
|
|
name="fileUrl"
|
|
|
|
|
|
v-if="data.info.fileType === StampFileTypeAttributes.HANDWRITTEN_SIGNATURE"
|
|
|
|
|
|
>
|
|
|
|
|
|
<Sign
|
|
|
|
|
|
v-if="data.info.fileType === StampFileTypeAttributes.HANDWRITTEN_SIGNATURE"
|
|
|
|
|
|
:src="data.signUrl"
|
|
|
|
|
|
@submit="uploadSign"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item :label="t('签章备注')" name="remark">
|
|
|
|
|
|
<a-textarea
|
|
|
|
|
|
v-model:value="data.info.remark"
|
|
|
|
|
|
:placeholder="t('请填写签章备注')"
|
|
|
|
|
|
:auto-size="{ minRows: 2, maxRows: 5 }"
|
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
</a-form>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</a-modal>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
import { computed, onMounted, reactive, ref } from 'vue';
|
|
|
|
|
|
import { notification } from 'ant-design-vue';
|
|
|
|
|
|
import { StampInfo } from '/@/api/workflow/model';
|
|
|
|
|
|
import { TreeItem } from '/@/components/Tree';
|
|
|
|
|
|
import Sign from './Sign.vue';
|
|
|
|
|
|
import { getDicDetailList } from '/@/api/system/dic';
|
|
|
|
|
|
import { uploadSrc, uploadBlobApi } from '/@/api/sys/upload';
|
|
|
|
|
|
import { postStamp, putStamp } from '/@/api/workflow/stamp';
|
|
|
|
|
|
import { StampCategory } from '/@/enums/workflowEnum';
|
|
|
|
|
|
|
|
|
|
|
|
import { getAppEnvConfig } from '/@/utils/env';
|
|
|
|
|
|
import { getToken } from '/@/utils/auth';
|
|
|
|
|
|
import type { UploadChangeParam } from 'ant-design-vue';
|
|
|
|
|
|
import { message } from 'ant-design-vue';
|
|
|
|
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
|
|
|
import { StampType, StampFileTypeAttributes } from '/@/enums/workflowEnum';
|
|
|
|
|
|
import { dataURLtoBlob } from '/@/utils/file/base64Conver';
|
|
|
|
|
|
import { useI18n } from '/@/hooks/web/useI18n';
|
2025-07-17 14:56:20 +08:00
|
|
|
|
const { VITE_GLOB_UPLOAD_ALERT_TIP } = getAppEnvConfig();
|
2024-02-05 09:15:37 +08:00
|
|
|
|
const { t } = useI18n();
|
|
|
|
|
|
let props = defineProps(['id', 'type', 'info']);
|
|
|
|
|
|
const formRef = ref();
|
|
|
|
|
|
let emits = defineEmits(['close']);
|
|
|
|
|
|
const title = computed(() => {
|
|
|
|
|
|
return props.id == '' ? t('新增签章') : t('编辑签章');
|
|
|
|
|
|
});
|
|
|
|
|
|
const defaultInfo: StampInfo = {
|
|
|
|
|
|
enabledMark: 0,
|
|
|
|
|
|
fileType: StampFileTypeAttributes.UPLOAD_PICTURES,
|
|
|
|
|
|
fileUrl: '',
|
|
|
|
|
|
password: '',
|
|
|
|
|
|
stampCategory: undefined,
|
|
|
|
|
|
stampType: StampType.PUBLIC_SIGNATURE,
|
|
|
|
|
|
name: '',
|
|
|
|
|
|
sortCode: 0,
|
|
|
|
|
|
remark: '',
|
|
|
|
|
|
id: '',
|
|
|
|
|
|
maintain: '',
|
|
|
|
|
|
};
|
|
|
|
|
|
const data: {
|
|
|
|
|
|
visible: boolean;
|
|
|
|
|
|
categoryOptions: TreeItem[];
|
|
|
|
|
|
info: StampInfo;
|
|
|
|
|
|
action: string;
|
|
|
|
|
|
headers: { Authorization: string };
|
|
|
|
|
|
photoUrl: string;
|
|
|
|
|
|
signUrl: string;
|
|
|
|
|
|
} = reactive({
|
|
|
|
|
|
visible: false,
|
|
|
|
|
|
categoryOptions: [],
|
|
|
|
|
|
info: defaultInfo,
|
|
|
|
|
|
action: '',
|
|
|
|
|
|
headers: { Authorization: '' },
|
|
|
|
|
|
photoUrl: '',
|
|
|
|
|
|
signUrl: '',
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const onCheck = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await formRef.value.validateFields();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
} catch (errorInfo) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
|
if (props.id) {
|
2025-07-09 18:58:37 +08:00
|
|
|
|
data.info = { ...defaultInfo, ...cloneDeep(props.info) };
|
|
|
|
|
|
// 回显时使用fileUrlFixed(如果有),否则使用fileUrl(改了)
|
|
|
|
|
|
const displayUrl = props.info.fileUrlFixed || props.info.fileUrl;
|
|
|
|
|
|
|
|
|
|
|
|
if (data.info.fileType === StampFileTypeAttributes.UPLOAD_PICTURES) {
|
|
|
|
|
|
data.photoUrl = displayUrl; // 显示用
|
|
|
|
|
|
} else {
|
|
|
|
|
|
data.signUrl = displayUrl; // 显示用
|
|
|
|
|
|
}
|
2024-02-05 09:15:37 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
data.info = defaultInfo;
|
|
|
|
|
|
}
|
|
|
|
|
|
data.action = getAppEnvConfig().VITE_GLOB_API_URL + uploadSrc;
|
|
|
|
|
|
data.headers.Authorization = `Bearer ${getToken()}`;
|
|
|
|
|
|
open();
|
|
|
|
|
|
});
|
|
|
|
|
|
async function open() {
|
|
|
|
|
|
data.categoryOptions = (await getDicDetailList({
|
|
|
|
|
|
itemId: StampCategory.ID,
|
|
|
|
|
|
})) as unknown as TreeItem[];
|
|
|
|
|
|
if (props.id) {
|
|
|
|
|
|
}
|
|
|
|
|
|
data.info.stampType = props.type;
|
|
|
|
|
|
data.visible = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function close() {
|
|
|
|
|
|
data.visible = false;
|
|
|
|
|
|
emits('close');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function uploadSign(base64) {
|
|
|
|
|
|
data.info.fileUrl = base64;
|
|
|
|
|
|
const blob = dataURLtoBlob(base64);
|
|
|
|
|
|
|
2025-07-09 18:58:37 +08:00
|
|
|
|
const response = await uploadBlobApi(blob, t('手写签名.png'));
|
|
|
|
|
|
if (response) {
|
|
|
|
|
|
// 存储原始URL到info.fileUrl(用于提交)(改了)
|
|
|
|
|
|
data.info.fileUrl = response.fileUrl;
|
|
|
|
|
|
|
|
|
|
|
|
// 显示使用fileUrlFixed(如果有),否则使用fileUrl(改了)
|
|
|
|
|
|
data.signUrl = response.fileUrlFixed || response.fileUrl;
|
2024-02-05 09:15:37 +08:00
|
|
|
|
message.success(t('手写签章上传成功'));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
message.error(t('手写签章上传失败'));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
async function submit() {
|
2025-07-21 19:23:41 +08:00
|
|
|
|
let valid = await onCheck();
|
|
|
|
|
|
let res = false;
|
|
|
|
|
|
if (valid) {
|
|
|
|
|
|
if (data.info.fileType === StampFileTypeAttributes.UPLOAD_PICTURES) {
|
|
|
|
|
|
if (!data.photoUrl) {
|
|
|
|
|
|
message.error(t('照片未上传'));
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if (!data.signUrl) {
|
|
|
|
|
|
message.error(t('签名未上传'));
|
|
|
|
|
|
return false;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
data.info.fileUrl = data.signUrl;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-02-05 09:15:37 +08:00
|
|
|
|
try {
|
|
|
|
|
|
if (props.id) {
|
|
|
|
|
|
res = await putStamp(props.id, props.type, data.info);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
res = await postStamp(props.type, data.info);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (res) {
|
|
|
|
|
|
notification.open({
|
|
|
|
|
|
type: 'success',
|
|
|
|
|
|
message: t('签章'),
|
|
|
|
|
|
description: title.value + t('成功'),
|
|
|
|
|
|
});
|
|
|
|
|
|
close();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
notification.open({
|
|
|
|
|
|
type: 'error',
|
|
|
|
|
|
message: t('签章'),
|
|
|
|
|
|
description: title.value + t('失败'),
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
function photoChange(info: UploadChangeParam) {
|
|
|
|
|
|
if (info.file.status !== 'uploading') {
|
|
|
|
|
|
}
|
|
|
|
|
|
if (info.file.status === 'done') {
|
|
|
|
|
|
if (info.file && info.file.response && info.file.response.code == 0) {
|
|
|
|
|
|
message.success(t(`{name}上传成功!`, { name: info.file.name }));
|
|
|
|
|
|
console.log(info, t('上传成功'));
|
2025-07-09 18:58:37 +08:00
|
|
|
|
// 存储原始URL到info.fileUrl(用于提交)(改了)
|
|
|
|
|
|
data.info.fileUrl = info.file.response.data.fileUrl;
|
|
|
|
|
|
|
|
|
|
|
|
// 显示使用fileUrlFixed(如果有),否则使用fileUrl (改了)
|
|
|
|
|
|
data.photoUrl = info.file.response.data.fileUrlFixed || info.file.response.data.fileUrl;
|
2024-02-05 09:15:37 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
message.error(t('上传照片失败'));
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (info.file.status === 'error') {
|
|
|
|
|
|
message.error(t(`{name}上传失败.`, { name: info.file.name }));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
|
|
|
.box {
|
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|