2026-07-29 11:25:29 +08:00
|
|
|
<template>
|
2026-08-13 19:01:37 +08:00
|
|
|
<view>
|
|
|
|
|
<full-page>
|
|
|
|
|
<view class="claim-page">
|
|
|
|
|
<view v-if="tip" class="tip">{{ tip }}</view>
|
|
|
|
|
<view v-else class="tip">加载中...</view>
|
|
|
|
|
</view>
|
2026-08-17 16:13:10 +08:00
|
|
|
</full-page>
|
2026-08-13 19:01:37 +08:00
|
|
|
|
2026-08-17 16:13:10 +08:00
|
|
|
<!-- Keep the fixed overlay outside full-page's scroll-view for iOS compatibility. -->
|
|
|
|
|
<view v-if="posterVisible" class="poster-mask">
|
|
|
|
|
<view class="poster-dialog">
|
|
|
|
|
<image
|
|
|
|
|
v-if="issue?.posterUrl"
|
|
|
|
|
class="poster-image"
|
|
|
|
|
:src="issue.posterUrl"
|
|
|
|
|
mode="aspectFit"
|
|
|
|
|
/>
|
|
|
|
|
<view v-else class="poster-image poster-image--placeholder">体验券</view>
|
|
|
|
|
<view class="poster-content">{{ buildClaimContent() }}</view>
|
|
|
|
|
<view class="poster-btn" :class="{ disabled: claiming }" @click="acceptCoupon">
|
|
|
|
|
{{ claiming ? "领取中..." : "接受" }}
|
2026-07-29 11:25:29 +08:00
|
|
|
</view>
|
|
|
|
|
</view>
|
2026-08-17 16:13:10 +08:00
|
|
|
</view>
|
2026-08-13 19:01:37 +08:00
|
|
|
</view>
|
2026-07-29 11:25:29 +08:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { computed, ref } from "vue";
|
|
|
|
|
import { storeToRefs } from "pinia";
|
|
|
|
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
|
|
|
|
import useAccount from "@/store/account";
|
|
|
|
|
import api from "@/utils/api";
|
2026-08-13 19:01:37 +08:00
|
|
|
import { set } from "@/utils/cache";
|
|
|
|
|
import { hideLoading, loading, toast } from "@/utils/widget";
|
2026-07-29 11:25:29 +08:00
|
|
|
import { normalizeCorpId } from "@/utils/api-base-config";
|
|
|
|
|
import FullPage from "@/components/full-page.vue";
|
|
|
|
|
|
2026-08-12 18:09:41 +08:00
|
|
|
const env = __VITE_ENV__;
|
|
|
|
|
const appid = env.MP_WX_APP_ID;
|
2026-07-29 11:25:29 +08:00
|
|
|
const { account } = storeToRefs(useAccount());
|
2026-08-12 18:09:41 +08:00
|
|
|
const { getTeams, login } = useAccount();
|
2026-07-29 11:25:29 +08:00
|
|
|
|
|
|
|
|
const corpId = ref("");
|
|
|
|
|
const issueId = ref("");
|
|
|
|
|
const memberId = ref("");
|
|
|
|
|
const issue = ref(null);
|
2026-08-13 19:01:37 +08:00
|
|
|
const issueCustomer = ref(null);
|
2026-07-29 11:25:29 +08:00
|
|
|
const tip = ref("");
|
|
|
|
|
const claiming = ref(false);
|
|
|
|
|
const autoPrompted = ref(false);
|
|
|
|
|
const posterVisible = ref(false);
|
2026-08-13 19:01:37 +08:00
|
|
|
const archiveBindPending = ref(false);
|
2026-08-12 14:27:07 +08:00
|
|
|
const bindingTeamId = ref("");
|
2026-08-13 19:01:37 +08:00
|
|
|
const bindCorpName = ref("");
|
2026-08-17 17:12:26 +08:00
|
|
|
const bindingTeam = ref(null);
|
2026-07-29 11:25:29 +08:00
|
|
|
|
2026-08-05 15:43:23 +08:00
|
|
|
const projectNameText = computed(() => {
|
2026-07-29 11:25:29 +08:00
|
|
|
const projects = Array.isArray(issue.value?.projectSnapshot) ? issue.value.projectSnapshot : [];
|
|
|
|
|
if (!projects.length) return "未配置项目";
|
2026-08-05 15:43:23 +08:00
|
|
|
return projects.map((p) => p.projectName || "项目").join("、");
|
2026-07-29 11:25:29 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function buildClaimContent() {
|
|
|
|
|
const name = issue.value?.activityName || "体验券";
|
2026-08-05 15:43:23 +08:00
|
|
|
return `您收到一张【${name}】体验券,包含${projectNameText.value},是否存入您的权益卡包?`;
|
2026-07-29 11:25:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function ensureLogin() {
|
|
|
|
|
if (!account.value) await login();
|
|
|
|
|
if (!account.value) {
|
|
|
|
|
tip.value = "请先登录后再领取体验券";
|
2026-08-17 17:12:26 +08:00
|
|
|
await openTeamLogin();
|
2026-07-29 11:25:29 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function loadIssueDetail() {
|
|
|
|
|
const res = await api(
|
|
|
|
|
"getExperienceCouponIssueDetail",
|
|
|
|
|
{ corpId: corpId.value, issueId: issueId.value },
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
if (!res?.success || !res.data) {
|
|
|
|
|
tip.value = res?.message || "体验券不存在或已失效";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
issue.value = res.data;
|
|
|
|
|
if (!memberId.value && res.data.customerId) {
|
|
|
|
|
memberId.value = res.data.customerId;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-13 19:01:37 +08:00
|
|
|
async function getIssueCustomer({ force = false } = {}) {
|
2026-08-12 18:09:41 +08:00
|
|
|
if (!corpId.value || !memberId.value) return null;
|
2026-08-13 19:01:37 +08:00
|
|
|
if (issueCustomer.value && !force) return issueCustomer.value;
|
2026-07-29 11:25:29 +08:00
|
|
|
|
|
|
|
|
try {
|
2026-08-12 14:27:07 +08:00
|
|
|
const detail = await api(
|
|
|
|
|
"getCustomerByCustomerId",
|
|
|
|
|
{ corpId: corpId.value, customerId: memberId.value },
|
2026-07-29 11:25:29 +08:00
|
|
|
false
|
|
|
|
|
);
|
2026-08-12 14:27:07 +08:00
|
|
|
const customer = detail?.data || null;
|
2026-08-13 19:01:37 +08:00
|
|
|
issueCustomer.value = customer;
|
|
|
|
|
bindCorpName.value = detail?.corpName || issue.value?.corpName || "";
|
2026-08-12 14:27:07 +08:00
|
|
|
const teamIds = Array.isArray(customer?.teamId) ? customer.teamId : [customer?.teamId];
|
2026-08-17 17:12:26 +08:00
|
|
|
bindingTeamId.value = issue.value?.teamId || teamIds.find(Boolean) || "";
|
2026-08-12 18:09:41 +08:00
|
|
|
return customer;
|
2026-07-29 11:25:29 +08:00
|
|
|
} catch (e) {
|
2026-08-12 14:27:07 +08:00
|
|
|
console.warn("getCustomerByCustomerId failed", e);
|
2026-08-12 18:09:41 +08:00
|
|
|
return null;
|
2026-07-29 11:25:29 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-12 18:09:41 +08:00
|
|
|
async function hasBoundArchive() {
|
|
|
|
|
const openid = account.value?.openid || "";
|
|
|
|
|
if (!openid) return false;
|
|
|
|
|
|
2026-08-13 19:01:37 +08:00
|
|
|
const customer = await getIssueCustomer({ force: true });
|
2026-08-12 18:09:41 +08:00
|
|
|
return Boolean(customer && String(customer.miniAppId || "") === String(openid));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function buildClaimUrl() {
|
2026-08-12 14:27:07 +08:00
|
|
|
const params = [
|
|
|
|
|
`corpId=${encodeURIComponent(corpId.value || "")}`,
|
2026-08-12 18:09:41 +08:00
|
|
|
`issueId=${encodeURIComponent(issueId.value || "")}`,
|
|
|
|
|
memberId.value ? `memberId=${encodeURIComponent(memberId.value)}` : "",
|
|
|
|
|
].filter(Boolean).join("&");
|
|
|
|
|
return `/pages/experience-coupon/claim?${params}`;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-13 19:01:37 +08:00
|
|
|
function buildTeamLoginUrl() {
|
|
|
|
|
const query = [
|
|
|
|
|
"source=teamInvite",
|
|
|
|
|
`redirectUrl=${encodeURIComponent(buildClaimUrl())}`,
|
|
|
|
|
].join("&");
|
|
|
|
|
return `/pages/login/login?${query}`;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-17 17:12:26 +08:00
|
|
|
async function getBindingTeam() {
|
|
|
|
|
if (!corpId.value || !bindingTeamId.value) return null;
|
|
|
|
|
if (bindingTeam.value) return bindingTeam.value;
|
|
|
|
|
try {
|
|
|
|
|
const res = await api(
|
|
|
|
|
"getTeamData",
|
|
|
|
|
{ corpId: corpId.value, teamId: bindingTeamId.value, withCorpName: true },
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
const data = res?.data || null;
|
|
|
|
|
bindingTeam.value = data;
|
|
|
|
|
bindCorpName.value = data?.corpName || data?.corp_name || bindCorpName.value;
|
|
|
|
|
return data;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.warn("getTeamData failed", e);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-12 18:09:41 +08:00
|
|
|
|
2026-08-17 17:12:26 +08:00
|
|
|
async function openTeamLogin() {
|
2026-08-13 19:01:37 +08:00
|
|
|
const customer = await getIssueCustomer();
|
|
|
|
|
if (!customer || !bindingTeamId.value) {
|
|
|
|
|
tip.value = "体验券发放档案缺少所属团队,暂无法领取";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2026-08-17 17:12:26 +08:00
|
|
|
const team = await getBindingTeam();
|
2026-08-13 19:01:37 +08:00
|
|
|
set("invite-team-info", {
|
|
|
|
|
corpId: corpId.value,
|
|
|
|
|
teamId: bindingTeamId.value,
|
|
|
|
|
corpName: bindCorpName.value || issue.value?.corpName || "",
|
2026-08-17 17:12:26 +08:00
|
|
|
teamName: team?.name || team?.teamName || "",
|
|
|
|
|
avatars: Array.isArray(team?.memberList)
|
|
|
|
|
? team.memberList.map((member) => member?.avatar || "").filter(Boolean)
|
|
|
|
|
: [],
|
2026-07-29 11:25:29 +08:00
|
|
|
});
|
2026-08-13 19:01:37 +08:00
|
|
|
uni.navigateTo({ url: buildTeamLoginUrl() });
|
2026-08-12 18:09:41 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-17 17:12:26 +08:00
|
|
|
async function ensurePhoneAuthorized() {
|
|
|
|
|
if (account.value?.mobile) return true;
|
|
|
|
|
|
|
|
|
|
tip.value = "请先授权手机号后再领取体验券";
|
|
|
|
|
return openTeamLogin();
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-12 18:09:41 +08:00
|
|
|
async function ensureTeamAdded() {
|
|
|
|
|
const customer = await getIssueCustomer();
|
|
|
|
|
if (!customer || !bindingTeamId.value) {
|
|
|
|
|
tip.value = "体验券发放档案缺少所属团队,暂无法领取";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const teams = await getTeams();
|
|
|
|
|
const linked = (teams || []).some(
|
|
|
|
|
(team) =>
|
|
|
|
|
normalizeCorpId(team.corpId) === corpId.value &&
|
|
|
|
|
String(team.teamId) === String(bindingTeamId.value)
|
|
|
|
|
);
|
|
|
|
|
if (linked) return true;
|
|
|
|
|
|
2026-08-13 19:01:37 +08:00
|
|
|
loading("添加团队中...");
|
2026-08-12 18:09:41 +08:00
|
|
|
try {
|
|
|
|
|
const res = await api(
|
|
|
|
|
"bindWxappWithTeam",
|
|
|
|
|
{
|
|
|
|
|
appid,
|
|
|
|
|
corpId: corpId.value,
|
|
|
|
|
teamId: bindingTeamId.value,
|
|
|
|
|
openid: account.value?.openid || "",
|
|
|
|
|
},
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
if (!res?.success) {
|
2026-08-13 19:01:37 +08:00
|
|
|
tip.value = res?.message || "添加团队失败";
|
|
|
|
|
toast(tip.value);
|
2026-08-12 18:09:41 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
await getTeams();
|
|
|
|
|
return true;
|
2026-08-13 19:01:37 +08:00
|
|
|
} finally {
|
|
|
|
|
hideLoading();
|
2026-08-12 18:09:41 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-13 19:01:37 +08:00
|
|
|
function buildArchiveBindUrl() {
|
|
|
|
|
const params = [
|
|
|
|
|
`corpId=${encodeURIComponent(corpId.value || "")}`,
|
|
|
|
|
`teamId=${encodeURIComponent(bindingTeamId.value || "")}`,
|
|
|
|
|
`bindCustomerId=${encodeURIComponent(memberId.value || "")}`,
|
|
|
|
|
`source=experienceCoupon`,
|
|
|
|
|
].join("&");
|
|
|
|
|
return `/pages/archive/edit-archive?${params}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function openArchiveBindPage() {
|
|
|
|
|
if (!issueCustomer.value || !bindingTeamId.value) {
|
2026-08-12 18:09:41 +08:00
|
|
|
toast("体验券发放档案不存在");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-08-13 19:01:37 +08:00
|
|
|
archiveBindPending.value = true;
|
|
|
|
|
uni.navigateTo({ url: buildArchiveBindUrl() });
|
2026-07-29 11:25:29 +08:00
|
|
|
}
|
|
|
|
|
|
2026-08-14 14:16:15 +08:00
|
|
|
function toTimestamp(value) {
|
|
|
|
|
if (!value) return 0;
|
|
|
|
|
const numeric = Number(value);
|
|
|
|
|
if (Number.isFinite(numeric)) return numeric;
|
|
|
|
|
const parsed = new Date(value).getTime();
|
|
|
|
|
return Number.isNaN(parsed) ? 0 : parsed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getIssueExpireAt() {
|
|
|
|
|
return toTimestamp(issue.value?.activityEndTime || issue.value?.displayExpireTime);
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-29 11:25:29 +08:00
|
|
|
function isExpiredIssue() {
|
2026-08-14 14:16:15 +08:00
|
|
|
const expireAt = getIssueExpireAt();
|
|
|
|
|
return Boolean(expireAt && Date.now() > expireAt);
|
2026-07-29 11:25:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function acceptCoupon() {
|
|
|
|
|
if (claiming.value || !issue.value) return;
|
|
|
|
|
|
|
|
|
|
claiming.value = true;
|
|
|
|
|
loading("领取中...");
|
|
|
|
|
try {
|
|
|
|
|
const res = await api("claimExperienceCoupon", {
|
|
|
|
|
corpId: corpId.value,
|
|
|
|
|
issueId: issueId.value,
|
|
|
|
|
claimUserId: account.value?.openid || "",
|
|
|
|
|
});
|
|
|
|
|
hideLoading();
|
|
|
|
|
if (!res?.success) {
|
|
|
|
|
tip.value = res?.message || "领取失败";
|
|
|
|
|
toast(tip.value);
|
2026-08-13 19:01:37 +08:00
|
|
|
if (tip.value.includes("绑定本体验券发放的档案")) {
|
|
|
|
|
posterVisible.value = false;
|
|
|
|
|
openArchiveBindPage();
|
|
|
|
|
}
|
2026-07-29 11:25:29 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
toast("领取成功");
|
|
|
|
|
posterVisible.value = false;
|
|
|
|
|
uni.redirectTo({
|
|
|
|
|
url: `/pages/experience-coupon/my-rights?corpId=${encodeURIComponent(corpId.value)}&customerId=${encodeURIComponent(memberId.value || "")}&name=${encodeURIComponent(issue.value.customerName || "")}`,
|
|
|
|
|
});
|
|
|
|
|
} catch (e) {
|
|
|
|
|
hideLoading();
|
|
|
|
|
tip.value = e?.message || "领取失败";
|
|
|
|
|
toast(tip.value);
|
|
|
|
|
} finally {
|
|
|
|
|
claiming.value = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function promptClaim() {
|
|
|
|
|
if (autoPrompted.value) return;
|
|
|
|
|
autoPrompted.value = true;
|
|
|
|
|
|
|
|
|
|
if (!issue.value) return;
|
|
|
|
|
if (issue.value.status === "claimed") {
|
|
|
|
|
tip.value = "该体验券已领取";
|
|
|
|
|
uni.redirectTo({
|
|
|
|
|
url: `/pages/experience-coupon/my-rights?corpId=${encodeURIComponent(corpId.value)}&customerId=${encodeURIComponent(memberId.value || "")}`,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (issue.value.status === "void") {
|
|
|
|
|
tip.value = "该体验券已作废";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (issue.value.status && issue.value.status !== "issued") {
|
|
|
|
|
tip.value = "当前状态不可领取";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (isExpiredIssue()) {
|
|
|
|
|
tip.value = "体验券已过期,无法领取";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bound = await hasBoundArchive();
|
|
|
|
|
if (!bound) {
|
2026-08-13 19:01:37 +08:00
|
|
|
openArchiveBindPage();
|
2026-07-29 11:25:29 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tip.value = "";
|
|
|
|
|
posterVisible.value = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function bootstrap() {
|
|
|
|
|
loading("加载中...");
|
|
|
|
|
try {
|
|
|
|
|
const okDetail = await loadIssueDetail();
|
|
|
|
|
if (!okDetail) return;
|
2026-08-17 17:12:26 +08:00
|
|
|
const okLogin = await ensureLogin();
|
|
|
|
|
if (!okLogin) return;
|
2026-08-12 18:09:41 +08:00
|
|
|
const phoneAuthorized = await ensurePhoneAuthorized();
|
|
|
|
|
if (!phoneAuthorized) return;
|
|
|
|
|
const teamAdded = await ensureTeamAdded();
|
|
|
|
|
if (!teamAdded) return;
|
2026-07-29 11:25:29 +08:00
|
|
|
await promptClaim();
|
|
|
|
|
} finally {
|
|
|
|
|
hideLoading();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-12 10:11:51 +08:00
|
|
|
function parseOptions(options = {}) {
|
|
|
|
|
const href = typeof options.q === "string" ? decodeURIComponent(options.q) : "";
|
|
|
|
|
const [, url = ""] = href.split("?");
|
|
|
|
|
return url.split("&").reduce((acc, cur) => {
|
|
|
|
|
if (!cur) return acc;
|
|
|
|
|
const [key, val = ''] = cur.split("=");
|
|
|
|
|
if (!key) return acc;
|
|
|
|
|
acc[key] = val
|
|
|
|
|
return acc;
|
|
|
|
|
}, {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onLoad((opts = {}) => {
|
|
|
|
|
let options = {};
|
|
|
|
|
if (opts.q) {
|
|
|
|
|
options = { ...parseOptions(opts) }
|
|
|
|
|
} else {
|
|
|
|
|
options = { ...opts }
|
|
|
|
|
}
|
2026-07-29 11:25:29 +08:00
|
|
|
corpId.value = normalizeCorpId(options.corpId || "");
|
|
|
|
|
issueId.value = options.issueId || options.id || "";
|
|
|
|
|
memberId.value = options.memberId || options.customerId || "";
|
|
|
|
|
if (!corpId.value || !issueId.value) {
|
|
|
|
|
tip.value = "领取参数不完整";
|
|
|
|
|
toast(tip.value);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
bootstrap();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onShow(() => {
|
2026-08-13 19:01:37 +08:00
|
|
|
if (archiveBindPending.value && issue.value && issue.value.status === "issued") {
|
|
|
|
|
archiveBindPending.value = false;
|
2026-07-29 11:25:29 +08:00
|
|
|
autoPrompted.value = false;
|
2026-08-13 19:01:37 +08:00
|
|
|
tip.value = "";
|
|
|
|
|
posterVisible.value = true;
|
2026-07-29 11:25:29 +08:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.claim-page {
|
|
|
|
|
min-height: 100%;
|
|
|
|
|
padding: 30rpx;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
background: #f6fafa;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tip {
|
|
|
|
|
margin-top: 120rpx;
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: #999;
|
|
|
|
|
}
|
2026-08-12 10:11:51 +08:00
|
|
|
|
2026-07-29 11:25:29 +08:00
|
|
|
.poster-mask {
|
|
|
|
|
position: fixed;
|
2026-08-17 16:13:10 +08:00
|
|
|
top: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
left: 0;
|
2026-07-29 11:25:29 +08:00
|
|
|
z-index: 1000;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
padding: 40rpx;
|
|
|
|
|
box-sizing: border-box;
|
2026-08-05 15:43:23 +08:00
|
|
|
background: rgba(0, 0, 0, 0.65);
|
2026-07-29 11:25:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.poster-dialog {
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 620rpx;
|
2026-08-17 16:13:10 +08:00
|
|
|
max-height: calc(100vh - 80rpx);
|
2026-07-29 11:25:29 +08:00
|
|
|
overflow: hidden;
|
2026-08-05 15:43:23 +08:00
|
|
|
border-radius: 20rpx;
|
|
|
|
|
background: #fff;
|
2026-07-29 11:25:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.poster-image {
|
|
|
|
|
display: block;
|
2026-08-05 15:43:23 +08:00
|
|
|
width: 100%;
|
2026-08-17 16:13:10 +08:00
|
|
|
height: 58vh;
|
2026-08-05 15:43:23 +08:00
|
|
|
max-height: 700rpx;
|
2026-07-29 11:25:29 +08:00
|
|
|
background: #f5f7fa;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-17 16:13:10 +08:00
|
|
|
.poster-image--placeholder {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
color: #9aa5b1;
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-05 15:43:23 +08:00
|
|
|
.poster-content {
|
|
|
|
|
padding: 28rpx 30rpx 8rpx;
|
|
|
|
|
color: #333;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
line-height: 1.6;
|
2026-08-17 16:13:10 +08:00
|
|
|
max-height: 160rpx;
|
|
|
|
|
overflow: hidden;
|
2026-07-29 11:25:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.poster-btn {
|
2026-08-05 15:43:23 +08:00
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
2026-07-29 11:25:29 +08:00
|
|
|
height: 80rpx;
|
2026-08-05 15:43:23 +08:00
|
|
|
margin: 24rpx 30rpx 30rpx;
|
2026-07-29 11:25:29 +08:00
|
|
|
border-radius: 40rpx;
|
|
|
|
|
background: #065bd6;
|
|
|
|
|
color: #fff;
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.poster-btn.disabled {
|
|
|
|
|
opacity: 0.6;
|
|
|
|
|
}
|
2026-08-17 16:13:10 +08:00
|
|
|
</style>
|