Showing
3 changed files
with
108 additions
and
35 deletions
| ... | @@ -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,35 +89,43 @@ const handleReset = () => { | ... | @@ -80,35 +89,43 @@ 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 | ||
| 87 | -const handleGenerate = () => { | 100 | +/********** 上传七牛云获取图片地址 ***********/ |
| 88 | - esign.value | 101 | +const loading = ref(false); |
| 89 | - .generate() | 102 | +const formCode = $route.query.code; // 表单code |
| 90 | - .then(async (res) => { | 103 | +const uuid = () => { |
| 91 | - // let fileName = "img1.png"; | 104 | + let s = []; |
| 92 | - // let file = this.dataURLtoFile(res, fileName); | 105 | + let hexDigits = "0123456789abcdef"; |
| 93 | - // console.log("file", file); | 106 | + for (var i = 0; i < 36; i++) { |
| 94 | - let affix = uuidv4(); | 107 | + s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); |
| 95 | - let base64url = res.slice(res.indexOf(",") + 1); // 截取前缀的base64 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnoAAAJeCAYAA....... | 108 | + } |
| 96 | - // 获取七牛token | 109 | + s[14] = "4"; |
| 97 | - const { token, key, code } = await qiniuTokenAPI({ | 110 | + s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); |
| 98 | - filename: `${affix}_sign`, | 111 | + s[8] = s[13] = s[18] = s[23] = "-"; |
| 99 | - file: base64url, | 112 | + |
| 100 | - }); | 113 | + var uuid = s.join(""); |
| 101 | - if (code) { | 114 | + return uuid; |
| 102 | - const config = { | 115 | +}; |
| 103 | - headers: { | 116 | + |
| 104 | - "Content-Type": "application/octet-stream", | 117 | +const uploadQiniu = async (file, token, filename) => { |
| 105 | - Authorization: "UpToken " + token, // UpToken后必须有一个 ' '(空格) | 118 | + let formData = new FormData(); |
| 106 | - }, | 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" }, | ||
| 107 | }; | 124 | }; |
| 108 | - // 上传七牛服务器 | 125 | + // 自拍图片上传七牛服务器 |
| 109 | const { filekey, hash, image_info } = await qiniuUploadAPI( | 126 | const { filekey, hash, image_info } = await qiniuUploadAPI( |
| 110 | - "http://upload.qiniup.com/putb64/-1/key/" + key, | 127 | + "http://upload.qiniu.com/", |
| 111 | - base64url, | 128 | + formData, |
| 112 | config | 129 | config |
| 113 | ); | 130 | ); |
| 114 | if (filekey) { | 131 | if (filekey) { |
| ... | @@ -120,15 +137,47 @@ const handleGenerate = () => { | ... | @@ -120,15 +137,47 @@ const handleGenerate = () => { |
| 120 | height: image_info.height, | 137 | height: image_info.height, |
| 121 | width: image_info.width, | 138 | width: image_info.width, |
| 122 | }); | 139 | }); |
| 123 | - props.item.value = { key: "sign", value: data.src }; | 140 | + return data; |
| 124 | - image_url.value = data.src; | 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 | + | ||
| 160 | +const handleGenerate = () => { | ||
| 161 | + esign.value | ||
| 162 | + .generate() | ||
| 163 | + .then(async (res) => { | ||
| 164 | + let affix = uuidv4(); | ||
| 165 | + let fileName = `uploadForm/${formCode}/${affix}_sign.png`; | ||
| 166 | + let file = dataURLtoFile(res, fileName); // 生成文件 | ||
| 167 | + const imgUrl = await handleUpload(file, fileName); | ||
| 168 | + loading.value = false; | ||
| 169 | + props.item.value = { | ||
| 170 | + key: "sign", | ||
| 171 | + filed_name: props.item.key, | ||
| 172 | + value: imgUrl.src, | ||
| 173 | + }; | ||
| 174 | + image_url.value = imgUrl.src; | ||
| 125 | show_control.value = false; | 175 | show_control.value = false; |
| 126 | show_empty.value = false; | 176 | show_empty.value = false; |
| 127 | emit("active", props.item.value); | 177 | 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 | // 通过验证 | ... | ... |
-
Please register or login to post a comment