946 lines
23 KiB
Vue
946 lines
23 KiB
Vue
<template>
|
||
<view class="asset-page asset-theme bmt-info-page">
|
||
<asset-page-shell title="补充签约信息" />
|
||
|
||
<view class="asset-scroll bmt-info-scroll">
|
||
<view class="glass-panel bmt-info-notice">
|
||
<text class="bmt-info-notice__title">温馨提示</text>
|
||
<text class="bmt-info-notice__text">如核对后仍然审核失败,可联系客服处理。</text>
|
||
<text v-if="noticeText" class="bmt-info-notice__error">审核失败:{{ noticeText }}</text>
|
||
</view>
|
||
|
||
<view class="glass-panel bmt-info-section">
|
||
<text class="bmt-info-section__title">身份证认证</text>
|
||
<text class="bmt-info-section__desc">请上传本人身份证正反面照片,并核对识别后的身份信息。</text>
|
||
|
||
<view class="bmt-upload-row">
|
||
<view v-for="item in uploadList" :key="item.key" class="bmt-upload-col">
|
||
<view class="bmt-upload-box" @click="handleUpload(item.key)">
|
||
<image class="bmt-upload-image" :src="item.image || item.placeholder" mode="aspectFit" />
|
||
<view v-if="item.uploading" class="bmt-upload-mask">{{ item.loadingText || "上传中..." }}</view>
|
||
</view>
|
||
<text class="bmt-upload-label">{{ item.label }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="glass-panel bmt-info-section">
|
||
<text class="bmt-info-section__title">身份信息</text>
|
||
|
||
<view class="bmt-form">
|
||
<view class="bmt-form-item">
|
||
<text class="bmt-form-label">姓名</text>
|
||
<input class="bmt-form-input" type="text" v-model="form.sign_name" placeholder="识别后自动回填"
|
||
placeholder-class="bmt-form-placeholder" />
|
||
</view>
|
||
<view class="bmt-form-item">
|
||
<text class="bmt-form-label">身份证号</text>
|
||
<input class="bmt-form-input" type="text" v-model="form.id_card" maxlength="18" placeholder="识别后自动回填"
|
||
placeholder-class="bmt-form-placeholder" />
|
||
</view>
|
||
<view class="bmt-form-item">
|
||
<text class="bmt-form-label">手机号</text>
|
||
<input class="bmt-form-input" type="number" v-model="form.sign_mobile" maxlength="11" placeholder="请输入手机号"
|
||
placeholder-class="bmt-form-placeholder" />
|
||
</view>
|
||
<view class="bmt-form-item bmt-form-item--textarea">
|
||
<text class="bmt-form-label">身份证地址</text>
|
||
<textarea class="bmt-form-textarea" v-model="form.sign_address" auto-height maxlength="120"
|
||
placeholder="识别后自动回填" placeholder-class="bmt-form-placeholder" />
|
||
</view>
|
||
|
||
<view class="bmt-shoot">
|
||
<text class="bmt-shoot__title">拍摄身份证要求:</text>
|
||
<text class="bmt-shoot__item">1、持有的本人有效二代身份证;</text>
|
||
<text class="bmt-shoot__item">2、拍摄时确保身份证边框完整、字体清晰、亮度均匀。</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="bmt-info-bottom">
|
||
<view class="bmt-info-bottom__row">
|
||
<view class="bmt-info-button bmt-info-button--ghost" @click="handleCancel">取消</view>
|
||
<view class="bmt-info-button bmt-info-button--primary" :class="{ 'is-disabled': isBusy }"
|
||
@click="handleSubmit">提交</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import AssetPageShell from "../../components/asset-page-shell.vue";
|
||
import {
|
||
uploadBmtImage,
|
||
fetchBmtOcrResult,
|
||
submitBmtSignInfo,
|
||
fetchBmtContractStatus,
|
||
checkBmtSignCondition,
|
||
startBmtSigning,
|
||
} from "../../api/bmt";
|
||
|
||
const ID_CARD_REG = /^(\d{15}|\d{17}[\dXx])$/;
|
||
const OCR_TYPE_ID_CARD = "idcard_ocr";
|
||
|
||
export default {
|
||
components: {
|
||
AssetPageShell,
|
||
},
|
||
data() {
|
||
return {
|
||
info: {},
|
||
form: {
|
||
back_img: "",
|
||
id_card: "",
|
||
positive_img: "",
|
||
sign_address: "",
|
||
sign_mobile: "",
|
||
sign_name: "",
|
||
},
|
||
uploadList: [
|
||
{
|
||
key: "positive_img",
|
||
label: "人像面",
|
||
placeholder: "https://imgs.agrimedia.cn/shop/sfz-2.png",
|
||
image: "",
|
||
uploading: false,
|
||
loadingText: "",
|
||
ocrValid: false,
|
||
},
|
||
{
|
||
key: "back_img",
|
||
label: "国徽面",
|
||
placeholder: "https://imgs.agrimedia.cn/shop/sfz-1.png",
|
||
image: "",
|
||
uploading: false,
|
||
loadingText: "",
|
||
ocrValid: false,
|
||
},
|
||
],
|
||
isSubmitting: false,
|
||
isIdCardExpired: false,
|
||
};
|
||
},
|
||
computed: {
|
||
noticeText() {
|
||
return String(this.info.jzq_audit_msg || "");
|
||
},
|
||
isBusy() {
|
||
return (
|
||
this.isSubmitting ||
|
||
this.uploadList.some((item) => item.uploading)
|
||
);
|
||
},
|
||
},
|
||
onLoad(options) {
|
||
if (options && options.data) {
|
||
try {
|
||
this.info = JSON.parse(decodeURIComponent(options.data)) || {};
|
||
} catch (error) {
|
||
this.info = {};
|
||
}
|
||
}
|
||
|
||
this.initForm();
|
||
},
|
||
methods: {
|
||
initForm() {
|
||
const data = this.info || {};
|
||
|
||
this.form = {
|
||
back_img: data.back_img || data.reverse_img || "",
|
||
id_card: data.id_card || data.card_id || data.number || "",
|
||
positive_img: data.positive_img || data.front_img || "",
|
||
sign_address:
|
||
data.sign_address ||
|
||
data.card_address ||
|
||
data.id_card_address ||
|
||
data.address ||
|
||
"",
|
||
sign_mobile:
|
||
data.sign_mobile || data.mobile || data.realname_mobile || "",
|
||
sign_name:
|
||
data.sign_name ||
|
||
data.legal_representative_name ||
|
||
data.legal_person ||
|
||
data.name ||
|
||
"",
|
||
};
|
||
|
||
this.syncUploadList();
|
||
},
|
||
syncUploadList() {
|
||
this.uploadList.forEach((item) => {
|
||
item.image = this.form[item.key] || "";
|
||
item.loadingText = "";
|
||
item.ocrValid = !!item.image;
|
||
});
|
||
},
|
||
getUploadItem(key) {
|
||
return this.uploadList.find((item) => item.key === key);
|
||
},
|
||
getRequiredUploads() {
|
||
return ["positive_img", "back_img"];
|
||
},
|
||
showTip(title) {
|
||
uni.showToast({
|
||
title: title,
|
||
icon: "none",
|
||
});
|
||
},
|
||
formatError(error, fallback) {
|
||
if (!error) {
|
||
return fallback;
|
||
}
|
||
|
||
if (typeof error === "string") {
|
||
return error;
|
||
}
|
||
|
||
if (error.message) {
|
||
return error.message;
|
||
}
|
||
|
||
if (error.msg) {
|
||
return error.msg;
|
||
}
|
||
|
||
if (error.errMsg) {
|
||
return error.errMsg;
|
||
}
|
||
|
||
if (error.data && error.data.msg) {
|
||
return error.data.msg;
|
||
}
|
||
|
||
return fallback;
|
||
},
|
||
handleUpload(key) {
|
||
if (this.isBusy) {
|
||
return;
|
||
}
|
||
|
||
const target = this.getUploadItem(key);
|
||
|
||
if (!target || target.uploading) {
|
||
return;
|
||
}
|
||
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sizeType: ["original", "compressed"],
|
||
sourceType: ["album", "camera"],
|
||
success: (result) => {
|
||
const filePath =
|
||
result && result.tempFilePaths && result.tempFilePaths[0];
|
||
const fileSize =
|
||
result && result.tempFiles && result.tempFiles[0]
|
||
? Number(result.tempFiles[0].size || 0)
|
||
: 0;
|
||
|
||
if (!filePath) {
|
||
return;
|
||
}
|
||
|
||
this.uploadAndRecognize(key, filePath, fileSize);
|
||
},
|
||
});
|
||
},
|
||
async uploadAndRecognize(key, filePath, fileSize) {
|
||
const target = this.getUploadItem(key);
|
||
|
||
if (!target) {
|
||
return;
|
||
}
|
||
|
||
const previous = {
|
||
image: target.image || "",
|
||
value: this.form[key] || "",
|
||
ocrValid: target.ocrValid,
|
||
};
|
||
|
||
target.uploading = true;
|
||
target.loadingText = "上传中...";
|
||
|
||
try {
|
||
// 超出 2MB 时会先压缩再上传
|
||
const uploadResult = await uploadBmtImage(filePath, {
|
||
size: fileSize,
|
||
});
|
||
const url = uploadResult && uploadResult.url ? uploadResult.url : "";
|
||
|
||
if (!url) {
|
||
throw new Error("上传失败,请重试");
|
||
}
|
||
|
||
target.image = url;
|
||
target.ocrValid = false;
|
||
this.form[key] = url;
|
||
target.loadingText = "识别中...";
|
||
|
||
console.log("[BMT签约] 图片上传成功,开始 OCR:", url);
|
||
|
||
// OCR:/api/merchant/ocr_img,type 固定 idcard_ocr
|
||
const ocrResult = await fetchBmtOcrResult({
|
||
type: OCR_TYPE_ID_CARD,
|
||
url: url,
|
||
});
|
||
|
||
console.log("[BMT签约] OCR 返回:", ocrResult);
|
||
|
||
if (!this.handleOcrResult(key, ocrResult)) {
|
||
this.restoreUpload(key, previous);
|
||
}
|
||
} catch (error) {
|
||
console.error("[BMT签约] 上传/识别失败", error);
|
||
this.restoreUpload(key, previous);
|
||
this.showTip(this.formatError(error, "识别失败,请重新上传清晰照片"));
|
||
} finally {
|
||
target.uploading = false;
|
||
target.loadingText = "";
|
||
}
|
||
},
|
||
restoreUpload(key, previous) {
|
||
const target = this.getUploadItem(key);
|
||
|
||
if (!target) {
|
||
return;
|
||
}
|
||
|
||
target.image = previous.image || "";
|
||
target.ocrValid = !!previous.ocrValid;
|
||
this.form[key] = previous.value || "";
|
||
},
|
||
getOcrData(result) {
|
||
if (!result || typeof result !== "object") {
|
||
return {};
|
||
}
|
||
|
||
if (result.data && result.data.data && result.data.data.info) {
|
||
return result.data.data.info;
|
||
}
|
||
|
||
if (result.data && result.data.info) {
|
||
return result.data.info;
|
||
}
|
||
|
||
if (result.data && result.data.data) {
|
||
return result.data.data;
|
||
}
|
||
|
||
if (result.data) {
|
||
return result.data;
|
||
}
|
||
|
||
return result;
|
||
},
|
||
handleOcrResult(key, result) {
|
||
if (key === "positive_img") {
|
||
return this.handleIdCardFrontOcr(result);
|
||
}
|
||
|
||
if (key === "back_img") {
|
||
return this.handleIdCardBackOcr(result);
|
||
}
|
||
|
||
return true;
|
||
},
|
||
handleIdCardFrontOcr(result) {
|
||
const info = this.getOcrData(result);
|
||
const name = String(info.name || info.sign_name || "").trim();
|
||
const number = String(
|
||
info.number || info.id_card || info.card_id || "",
|
||
).trim();
|
||
const address = String(
|
||
info.address || info.sign_address || info.card_address || "",
|
||
).trim();
|
||
const target = this.getUploadItem("positive_img");
|
||
|
||
if (!name && !number) {
|
||
if (target) {
|
||
target.ocrValid = false;
|
||
}
|
||
this.showTip("身份证人像面识别失败,请重新上传清晰照片");
|
||
return false;
|
||
}
|
||
|
||
if (!name) {
|
||
if (target) {
|
||
target.ocrValid = false;
|
||
}
|
||
this.showTip("未识别到姓名,请重新上传清晰照片");
|
||
return false;
|
||
}
|
||
|
||
if (!number) {
|
||
if (target) {
|
||
target.ocrValid = false;
|
||
}
|
||
this.showTip("未识别到身份证号,请重新上传清晰照片");
|
||
return false;
|
||
}
|
||
|
||
if (!ID_CARD_REG.test(number)) {
|
||
if (target) {
|
||
target.ocrValid = false;
|
||
}
|
||
this.showTip("身份证号识别异常,请重新上传清晰照片");
|
||
return false;
|
||
}
|
||
|
||
this.form.sign_name = name;
|
||
this.form.id_card = number;
|
||
|
||
if (address) {
|
||
this.form.sign_address = address;
|
||
}
|
||
|
||
if (target) {
|
||
target.ocrValid = true;
|
||
}
|
||
|
||
this.showTip("身份证识别成功,请核对信息");
|
||
return true;
|
||
},
|
||
handleIdCardBackOcr(result) {
|
||
const info = this.getOcrData(result);
|
||
const timelimit = String(
|
||
info.timelimit || info.valid_date || info.validity || "",
|
||
).trim();
|
||
const validity = this.checkIdCardTimelimit(timelimit);
|
||
const target = this.getUploadItem("back_img");
|
||
|
||
this.isIdCardExpired = false;
|
||
|
||
if (!validity.valid) {
|
||
if (target) {
|
||
target.ocrValid = false;
|
||
}
|
||
this.showTip("身份证国徽面识别失败,请重新上传清晰照片");
|
||
return false;
|
||
}
|
||
|
||
if (validity.expired) {
|
||
this.isIdCardExpired = true;
|
||
|
||
if (target) {
|
||
target.ocrValid = false;
|
||
}
|
||
|
||
this.showTip("身份证已过期,请上传最新身份证");
|
||
return false;
|
||
}
|
||
|
||
if (target) {
|
||
target.ocrValid = true;
|
||
}
|
||
|
||
this.showTip("身份证国徽面识别成功");
|
||
return true;
|
||
},
|
||
checkIdCardTimelimit(timelimit) {
|
||
const text = String(timelimit || "").trim();
|
||
|
||
if (!text) {
|
||
return { valid: false, expired: true, text: "" };
|
||
}
|
||
|
||
if (text.indexOf("长期") > -1) {
|
||
return { valid: true, expired: false, text: text };
|
||
}
|
||
|
||
const digits = text.replace(/\D/g, "");
|
||
|
||
if (digits.length < 16) {
|
||
return { valid: false, expired: true, text: text };
|
||
}
|
||
|
||
const parseDate = (value) => {
|
||
if (!value || value.length < 8) {
|
||
return null;
|
||
}
|
||
|
||
const year = parseInt(value.slice(0, 4), 10);
|
||
const month = parseInt(value.slice(4, 6), 10) - 1;
|
||
const day = parseInt(value.slice(6, 8), 10);
|
||
const dateObj = new Date(year, month, day);
|
||
|
||
return isNaN(dateObj.getTime()) ? null : dateObj;
|
||
};
|
||
|
||
const startDate = parseDate(digits.slice(0, 8));
|
||
const endDate = parseDate(digits.slice(digits.length - 8));
|
||
|
||
if (!startDate || !endDate) {
|
||
return { valid: false, expired: true, text: text };
|
||
}
|
||
|
||
const currentDate = new Date();
|
||
|
||
return {
|
||
valid: true,
|
||
expired: currentDate > endDate || currentDate < startDate,
|
||
text: text,
|
||
};
|
||
},
|
||
validateUploads() {
|
||
const labels = {
|
||
positive_img: "身份证人像面",
|
||
back_img: "身份证国徽面",
|
||
};
|
||
const required = this.getRequiredUploads();
|
||
|
||
for (let i = 0; i < required.length; i += 1) {
|
||
const key = required[i];
|
||
const target = this.getUploadItem(key);
|
||
|
||
if (!this.form[key]) {
|
||
this.showTip(`请上传${labels[key]}`);
|
||
return false;
|
||
}
|
||
|
||
if (!target || !target.ocrValid) {
|
||
this.showTip(`请重新上传${labels[key]}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
},
|
||
validateForm() {
|
||
if (!this.validateUploads()) {
|
||
return false;
|
||
}
|
||
|
||
const validations = [
|
||
{ field: "sign_name", message: "请输入姓名" },
|
||
{ field: "id_card", message: "请输入身份证号" },
|
||
{ field: "sign_mobile", message: "请输入手机号" },
|
||
{ field: "sign_address", message: "请输入身份证地址" },
|
||
];
|
||
|
||
for (let i = 0; i < validations.length; i += 1) {
|
||
const item = validations[i];
|
||
|
||
if (!String(this.form[item.field] || "").trim()) {
|
||
this.showTip(item.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (!ID_CARD_REG.test(String(this.form.id_card || "").trim())) {
|
||
this.showTip("请输入正确的身份证号");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
},
|
||
buildPayload() {
|
||
const address = String(this.form.sign_address || "").trim();
|
||
|
||
return {
|
||
sign_name: String(this.form.sign_name || "").trim(),
|
||
id_card: String(this.form.id_card || "").trim(),
|
||
sign_mobile: String(this.form.sign_mobile || "").trim(),
|
||
sign_address: address,
|
||
contact_address: address,
|
||
positive_img: this.form.positive_img || "",
|
||
back_img: this.form.back_img || "",
|
||
};
|
||
},
|
||
handleCancel() {
|
||
if (getCurrentPages().length > 1) {
|
||
uni.navigateBack();
|
||
return;
|
||
}
|
||
|
||
uni.reLaunch({
|
||
url: "/pages/index/index",
|
||
});
|
||
},
|
||
navigateToExternalUrl(targetUrl) {
|
||
if (!targetUrl) {
|
||
return;
|
||
}
|
||
|
||
if (typeof window !== "undefined" && window.location) {
|
||
window.location.href = targetUrl;
|
||
return;
|
||
}
|
||
|
||
if (
|
||
typeof plus !== "undefined" &&
|
||
plus.webview &&
|
||
plus.webview.currentWebview
|
||
) {
|
||
const currentWebview = plus.webview.currentWebview();
|
||
|
||
if (currentWebview && typeof currentWebview.loadURL === "function") {
|
||
currentWebview.loadURL(targetUrl);
|
||
return;
|
||
}
|
||
}
|
||
|
||
uni.navigateTo({
|
||
url: targetUrl,
|
||
});
|
||
},
|
||
backAfterSubmit() {
|
||
setTimeout(() => {
|
||
this.handleCancel();
|
||
}, 800);
|
||
},
|
||
async handleSubmit() {
|
||
if (this.isBusy) {
|
||
return;
|
||
}
|
||
|
||
if (!this.validateForm()) {
|
||
return;
|
||
}
|
||
|
||
this.isSubmitting = true;
|
||
|
||
try {
|
||
await submitBmtSignInfo(this.buildPayload(), {
|
||
showLoading: true,
|
||
loadingText: "提交中",
|
||
});
|
||
|
||
uni.showToast({
|
||
title: "提交成功",
|
||
icon: "none",
|
||
});
|
||
|
||
await this.handleAfterSignInfoSubmit();
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: this.formatError(error, "提交失败"),
|
||
icon: "none",
|
||
});
|
||
} finally {
|
||
this.isSubmitting = false;
|
||
}
|
||
},
|
||
/**
|
||
* 提交成功后复查签约状态:仍未签约则自动发起签约,
|
||
* 拿到 saasShortLink 后跳转去认证;否则回到上一页。
|
||
*/
|
||
async handleAfterSignInfoSubmit() {
|
||
let saasShortLink = "";
|
||
|
||
try {
|
||
const status = (await fetchBmtContractStatus()) || {};
|
||
const contractStatus = Number(status.contract_status || 0);
|
||
|
||
if (contractStatus !== 0) {
|
||
this.backAfterSubmit();
|
||
return;
|
||
}
|
||
|
||
let contractType = Number(status.contract_type || 0);
|
||
let contractId = "";
|
||
let recordId = String(status.id || "");
|
||
|
||
try {
|
||
const checkData =
|
||
(await checkBmtSignCondition(
|
||
{},
|
||
{
|
||
showLoading: true,
|
||
loadingText: "校验中",
|
||
},
|
||
)) || {};
|
||
|
||
contractId = String(checkData.c_id || "");
|
||
recordId = String(checkData.id || recordId || "");
|
||
|
||
const checkType = checkData.contract_type;
|
||
|
||
if (
|
||
checkType !== undefined &&
|
||
checkType !== null &&
|
||
checkType !== ""
|
||
) {
|
||
contractType = Number(checkType) === 1 ? 1 : 0;
|
||
}
|
||
} catch (error) {
|
||
// 前置校验失败不阻断,继续尝试发起签约
|
||
}
|
||
|
||
const result =
|
||
(await startBmtSigning(
|
||
{
|
||
contract_type: contractType,
|
||
c_id: contractId,
|
||
id: recordId,
|
||
},
|
||
{
|
||
showLoading: true,
|
||
loadingText: "发起签约",
|
||
},
|
||
)) || {};
|
||
|
||
console.log("[BMT签约] start_signing_bmt_v2 返回:", result.raw);
|
||
|
||
if (Number(result.status) === 0 && result.saasShortLink) {
|
||
saasShortLink = String(result.saasShortLink);
|
||
} else {
|
||
uni.showToast({
|
||
title: result.message || "发起签约失败,请稍后重试",
|
||
icon: "none",
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error("[BMT签约] 提交后自动签约失败", error);
|
||
}
|
||
|
||
if (saasShortLink) {
|
||
this.navigateToExternalUrl(saasShortLink);
|
||
return;
|
||
}
|
||
|
||
this.backAfterSubmit();
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import "../../styles/tokens.scss";
|
||
@import "../../styles/common.scss";
|
||
|
||
.bmt-info-page {
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.bmt-info-scroll {
|
||
padding: 12rpx 24rpx calc(env(safe-area-inset-bottom) + 180rpx);
|
||
}
|
||
|
||
.bmt-info-notice {
|
||
padding: 24rpx 26rpx;
|
||
}
|
||
|
||
.bmt-info-notice__title {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
color: $asset-warning;
|
||
}
|
||
|
||
.bmt-info-notice__text {
|
||
display: block;
|
||
margin-top: 10rpx;
|
||
font-size: 24rpx;
|
||
line-height: 1.7;
|
||
color: $asset-text-muted;
|
||
}
|
||
|
||
.bmt-info-notice__error {
|
||
display: block;
|
||
margin-top: 10rpx;
|
||
font-size: 24rpx;
|
||
line-height: 1.7;
|
||
color: $asset-danger;
|
||
}
|
||
|
||
.bmt-info-section {
|
||
margin-top: 24rpx;
|
||
padding: 28rpx 26rpx;
|
||
}
|
||
|
||
.bmt-info-section__title {
|
||
display: block;
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: $asset-text-main;
|
||
}
|
||
|
||
.bmt-info-section__desc {
|
||
display: block;
|
||
margin-top: 12rpx;
|
||
font-size: 24rpx;
|
||
line-height: 1.7;
|
||
color: $asset-text-subtle;
|
||
}
|
||
|
||
.bmt-upload-row {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
margin-top: 24rpx;
|
||
}
|
||
|
||
.bmt-upload-col {
|
||
flex: 1;
|
||
min-width: 0;
|
||
text-align: center;
|
||
}
|
||
|
||
.bmt-upload-col+.bmt-upload-col {
|
||
margin-left: 16rpx;
|
||
}
|
||
|
||
.bmt-upload-box {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 176rpx;
|
||
border-radius: 14rpx;
|
||
overflow: hidden;
|
||
background: rgba(18, 25, 48, 0.72);
|
||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.bmt-upload-image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.bmt-upload-mask {
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: rgba(5, 10, 22, 0.62);
|
||
font-size: 24rpx;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.bmt-upload-label {
|
||
display: block;
|
||
margin-top: 12rpx;
|
||
min-height: 44rpx;
|
||
font-size: 22rpx;
|
||
line-height: 32rpx;
|
||
color: $asset-text-muted;
|
||
}
|
||
|
||
.bmt-form {
|
||
margin-top: 16rpx;
|
||
}
|
||
|
||
.bmt-form-item {
|
||
display: flex;
|
||
align-items: center;
|
||
min-height: 96rpx;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||
}
|
||
|
||
.bmt-form-item:last-child {
|
||
border-bottom: 0;
|
||
}
|
||
|
||
.bmt-form-item--textarea {
|
||
align-items: flex-start;
|
||
padding: 26rpx 0;
|
||
}
|
||
|
||
.bmt-form-label {
|
||
width: 200rpx;
|
||
flex-shrink: 0;
|
||
font-size: 28rpx;
|
||
color: $asset-text-muted;
|
||
}
|
||
|
||
.bmt-form-input {
|
||
flex: 1;
|
||
height: 72rpx;
|
||
padding: 0;
|
||
border: 0;
|
||
text-align: right;
|
||
font-size: 30rpx;
|
||
color: $asset-text-main;
|
||
background: transparent;
|
||
}
|
||
|
||
.bmt-form-textarea {
|
||
flex: 1;
|
||
width: auto;
|
||
min-height: 84rpx;
|
||
padding: 0;
|
||
border: 0;
|
||
text-align: right;
|
||
font-size: 28rpx;
|
||
line-height: 42rpx;
|
||
color: $asset-text-main;
|
||
background: transparent;
|
||
}
|
||
|
||
.bmt-form-placeholder {
|
||
font-size: 26rpx;
|
||
color: rgba(143, 167, 207, 0.72);
|
||
}
|
||
|
||
.bmt-shoot {
|
||
margin-top: 26rpx;
|
||
}
|
||
|
||
.bmt-shoot__title {
|
||
display: block;
|
||
font-size: 26rpx;
|
||
color: $asset-text-muted;
|
||
}
|
||
|
||
.bmt-shoot__item {
|
||
display: block;
|
||
margin-top: 8rpx;
|
||
font-size: 24rpx;
|
||
line-height: 1.7;
|
||
color: $asset-text-subtle;
|
||
}
|
||
|
||
.bmt-info-bottom {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
padding: 20rpx 24rpx calc(20rpx + env(safe-area-inset-bottom));
|
||
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
||
background: #191e32;
|
||
z-index: 30;
|
||
}
|
||
|
||
.bmt-info-bottom__row {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.bmt-info-button {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex: 1;
|
||
height: 84rpx;
|
||
border-radius: 999rpx;
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.bmt-info-button+.bmt-info-button {
|
||
margin-left: 20rpx;
|
||
}
|
||
|
||
.bmt-info-button--ghost {
|
||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||
background: rgba(255, 255, 255, 0.06);
|
||
color: $asset-text-main;
|
||
}
|
||
|
||
.bmt-info-button--primary {
|
||
background: linear-gradient(135deg, #7e6cff 0%, #6b56f6 100%);
|
||
box-shadow: 0 14rpx 24rpx rgba(93, 79, 225, 0.22);
|
||
color: #ffffff;
|
||
}
|
||
|
||
.bmt-info-button.is-disabled {
|
||
opacity: 0.6;
|
||
}
|
||
</style>
|