hookehuyr

fix 电子签名图片保存功能实现

...@@ -18,10 +18,17 @@ ...@@ -18,10 +18,17 @@
18 :after-read="afterRead" 18 :after-read="afterRead"
19 :before-delete="beforeDelete" 19 :before-delete="beforeDelete"
20 v-model="fileList" 20 v-model="fileList"
21 - :multiple="true" 21 + :multiple="item.component_props.multiple"
22 /> 22 />
23 </div> 23 </div>
24 <div class="type-text">上传格式:{{ type_text }}</div> 24 <div class="type-text">上传格式:{{ type_text }}</div>
25 + <div
26 + v-if="show_empty"
27 + class="van-field__error-message"
28 + style="padding: 0 1rem 1rem 1rem"
29 + >
30 + 图片上传不能为空
31 + </div>
25 </div> 32 </div>
26 33
27 <van-overlay :show="loading"> 34 <van-overlay :show="loading">
...@@ -202,6 +209,7 @@ const afterRead = async (files) => { ...@@ -202,6 +209,7 @@ const afterRead = async (files) => {
202 files.status = ""; 209 files.status = "";
203 files.message = ""; 210 files.message = "";
204 fileList.value.push({ 211 fileList.value.push({
212 + meta_id: imgUrl.meta_id,
205 url: imgUrl.src, 213 url: imgUrl.src,
206 isImage: true, 214 isImage: true,
207 }); 215 });
...@@ -215,8 +223,10 @@ const afterRead = async (files) => { ...@@ -215,8 +223,10 @@ const afterRead = async (files) => {
215 props.item.value = { 223 props.item.value = {
216 key: "image_uploader", 224 key: "image_uploader",
217 filed_name: props.item.key, 225 filed_name: props.item.key,
226 + // value: fileList.value.map((item) => item.url),
218 value: fileList.value, 227 value: fileList.value,
219 }; 228 };
229 + show_empty.value = false;
220 emit("active", props.item.value); 230 emit("active", props.item.value);
221 console.warn(fileList.value); 231 console.warn(fileList.value);
222 }; 232 };
...@@ -228,6 +238,7 @@ const beforeDelete = (files) => { ...@@ -228,6 +238,7 @@ const beforeDelete = (files) => {
228 props.item.value = { 238 props.item.value = {
229 key: "image_uploader", 239 key: "image_uploader",
230 filed_name: props.item.key, 240 filed_name: props.item.key,
241 + // value: fileList.value.map((item) => item.url),
231 value: fileList.value, 242 value: fileList.value,
232 }; 243 };
233 emit("active", props.item.value); 244 emit("active", props.item.value);
......
...@@ -51,17 +51,26 @@ ...@@ -51,17 +51,26 @@
51 电子签名不能为空 51 电子签名不能为空
52 </div> 52 </div>
53 </div> 53 </div>
54 +
55 + <van-overlay :show="loading">
56 + <div class="wrapper" @click.stop>
57 + <van-loading vertical color="#FFFFFF">生成中...</van-loading>
58 + </div>
59 + </van-overlay>
54 </template> 60 </template>
55 61
56 <script setup> 62 <script setup>
57 import { v4 as uuidv4 } from "uuid"; 63 import { v4 as uuidv4 } from "uuid";
58 import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from "@/api/common"; 64 import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from "@/api/common";
59 import { showSuccessToast, showFailToast } from "vant"; 65 import { showSuccessToast, showFailToast } from "vant";
66 +import { useRoute } from "vue-router";
67 +import BMF from "browser-md5-file";
68 +import { getEtag } from "@/utils/qetag.js"; // 生成hash值
60 69
61 const props = defineProps({ 70 const props = defineProps({
62 item: Object, 71 item: Object,
63 }); 72 });
64 - 73 +const $route = useRoute();
65 const emit = defineEmits(["active"]); 74 const emit = defineEmits(["active"]);
66 75
67 const esign = ref(null); 76 const esign = ref(null);
...@@ -80,55 +89,95 @@ const handleReset = () => { ...@@ -80,55 +89,95 @@ const handleReset = () => {
80 show_control.value = true; 89 show_control.value = true;
81 // 删除可能存在的签名 90 // 删除可能存在的签名
82 image_url.value = ""; 91 image_url.value = "";
83 - props.item.value = { key: "sign", value: "" }; 92 + props.item.value = {
93 + key: "sign",
94 + filed_name: props.item.key,
95 + value: "",
96 + };
84 emit("active", props.item.value); 97 emit("active", props.item.value);
85 }; 98 };
86 99
100 +/********** 上传七牛云获取图片地址 ***********/
101 +const loading = ref(false);
102 +const formCode = $route.query.code; // 表单code
103 +const uuid = () => {
104 + let s = [];
105 + let hexDigits = "0123456789abcdef";
106 + for (var i = 0; i < 36; i++) {
107 + s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
108 + }
109 + s[14] = "4";
110 + s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
111 + s[8] = s[13] = s[18] = s[23] = "-";
112 +
113 + var uuid = s.join("");
114 + return uuid;
115 +};
116 +
117 +const uploadQiniu = async (file, token, filename) => {
118 + let formData = new FormData();
119 + formData.append("file", file); // 通过append向form对象添加数据
120 + formData.append("token", token);
121 + formData.append("key", filename);
122 + let config = {
123 + headers: { "Content-Type": "multipart/form-data" },
124 + };
125 + // 自拍图片上传七牛服务器
126 + const { filekey, hash, image_info } = await qiniuUploadAPI(
127 + "http://upload.qiniu.com/",
128 + formData,
129 + config
130 + );
131 + if (filekey) {
132 + // 保存图片
133 + const { data } = await saveFileAPI({
134 + filekey,
135 + hash,
136 + format: image_info.format,
137 + height: image_info.height,
138 + width: image_info.width,
139 + });
140 + return data;
141 + }
142 +};
143 +/****************** END *******************/
144 +
145 +const handleUpload = async (files, filename) => {
146 + // 上传图片流程
147 + loading.value = true;
148 + // 获取HASH值
149 + const hash = getEtag(files);
150 + // 获取七牛token
151 + const { token, key, code } = await qiniuTokenAPI({
152 + name: filename,
153 + hash,
154 + });
155 + // 文件上传七牛云
156 + const imgUrl = await uploadQiniu(files, token, filename);
157 + return imgUrl;
158 +};
159 +
87 const handleGenerate = () => { 160 const handleGenerate = () => {
88 esign.value 161 esign.value
89 .generate() 162 .generate()
90 .then(async (res) => { 163 .then(async (res) => {
91 - // let fileName = "img1.png";
92 - // let file = this.dataURLtoFile(res, fileName);
93 - // console.log("file", file);
94 let affix = uuidv4(); 164 let affix = uuidv4();
95 - let base64url = res.slice(res.indexOf(",") + 1); // 截取前缀的base64 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnoAAAJeCAYAA....... 165 + let fileName = `uploadForm/${formCode}/${affix}_sign.png`;
96 - // 获取七牛token 166 + let file = dataURLtoFile(res, fileName); // 生成文件
97 - const { token, key, code } = await qiniuTokenAPI({ 167 + const imgUrl = await handleUpload(file, fileName);
98 - filename: `${affix}_sign`, 168 + loading.value = false;
99 - file: base64url, 169 + props.item.value = {
100 - }); 170 + key: "sign",
101 - if (code) { 171 + filed_name: props.item.key,
102 - const config = { 172 + value: imgUrl.src,
103 - headers: { 173 + };
104 - "Content-Type": "application/octet-stream", 174 + image_url.value = imgUrl.src;
105 - Authorization: "UpToken " + token, // UpToken后必须有一个 ' '(空格) 175 + show_control.value = false;
106 - }, 176 + show_empty.value = false;
107 - }; 177 + emit("active", props.item.value);
108 - // 上传七牛服务器
109 - const { filekey, hash, image_info } = await qiniuUploadAPI(
110 - "http://upload.qiniup.com/putb64/-1/key/" + key,
111 - base64url,
112 - config
113 - );
114 - if (filekey) {
115 - // 保存图片
116 - const { data } = await saveFileAPI({
117 - filekey,
118 - hash,
119 - format: image_info.format,
120 - height: image_info.height,
121 - width: image_info.width,
122 - });
123 - props.item.value = { key: "sign", value: data.src };
124 - image_url.value = data.src;
125 - show_control.value = false;
126 - show_empty.value = false;
127 - emit("active", props.item.value);
128 - }
129 - }
130 }) 178 })
131 .catch((err) => { 179 .catch((err) => {
180 + loading.value = false;
132 // 签名生成失败 181 // 签名生成失败
133 console.warn(err); 182 console.warn(err);
134 if (err) { 183 if (err) {
...@@ -221,4 +270,17 @@ export default { ...@@ -221,4 +270,17 @@ export default {
221 padding-bottom: 1rem; 270 padding-bottom: 1rem;
222 } 271 }
223 } 272 }
273 +
274 +.wrapper {
275 + display: flex;
276 + align-items: center;
277 + justify-content: center;
278 + height: 100%;
279 +}
280 +
281 +.block {
282 + width: 120px;
283 + height: 120px;
284 + background-color: #fff;
285 +}
224 </style> 286 </style>
......
...@@ -180,7 +180,7 @@ const onActive = (item) => { ...@@ -180,7 +180,7 @@ const onActive = (item) => {
180 postData.value[item.filed_name] = item.value; 180 postData.value[item.filed_name] = item.value;
181 } 181 }
182 if (item.key === "sign") { 182 if (item.key === "sign") {
183 - postData.value["sign"] = item.value; 183 + postData.value[item.filed_name] = item.value;
184 } 184 }
185 if (item.type === "rate") { 185 if (item.type === "rate") {
186 postData.value = _.assign(postData.value, { [item.key]: item.value }); 186 postData.value = _.assign(postData.value, { [item.key]: item.value });
...@@ -221,10 +221,10 @@ const onSubmit = async (values) => { ...@@ -221,10 +221,10 @@ const onSubmit = async (values) => {
221 // 合并自定义字段到提交表单字段 221 // 合并自定义字段到提交表单字段
222 postData.value = _.assign(postData.value, values); 222 postData.value = _.assign(postData.value, values);
223 // 格式化value值为json格式, 提交格式有问题 223 // 格式化value值为json格式, 提交格式有问题
224 - for (let key in postData.value) { 224 + // for (let key in postData.value) {
225 - key = JSON.stringify(key); 225 + // key = JSON.stringify(key);
226 - // postData.value[key] = postData.value[key]; 226 + // // postData.value[key] = postData.value[key];
227 - } 227 + // }
228 // 检查非表单输入项 228 // 检查非表单输入项
229 if (validOther().status) { 229 if (validOther().status) {
230 // 通过验证 230 // 通过验证
......