支持设置默认企业
This commit is contained in:
@@ -90,6 +90,24 @@
|
|||||||
class="form-input"
|
class="form-input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-item form-item-full">
|
||||||
|
<label class="form-label">小程序默认企业</label>
|
||||||
|
<el-select
|
||||||
|
v-model="systemConfig.defaultEnterpriseId"
|
||||||
|
class="form-input w-full"
|
||||||
|
placeholder="不设置则小程序无带参入口时不回落企业"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="ent in enterpriseOptions"
|
||||||
|
:key="ent.id"
|
||||||
|
:label="`${ent.name}(ID: ${ent.id})`"
|
||||||
|
:value="ent.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
<span class="form-hint">未带企业入口参数(如 scene / 链接中的 eid)时,小程序回落使用该企业的上下文;优先级:扫码或链接中的企业 > 用户已绑定企业 > 此处默认企业</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 小程序文案配置 -->
|
<!-- 小程序文案配置 -->
|
||||||
@@ -390,8 +408,12 @@ const systemConfig = reactive({
|
|||||||
maintenanceMode: false,
|
maintenanceMode: false,
|
||||||
maxTestsPerDay: 100,
|
maxTestsPerDay: 100,
|
||||||
trialTestCount: 10,
|
trialTestCount: 10,
|
||||||
|
defaultEnterpriseId: null as number | null,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/** 下拉:企业管理中的企业列表 */
|
||||||
|
const enterpriseOptions = ref<Array<{ id: number; name: string }>>([])
|
||||||
|
|
||||||
// 超管凭据
|
// 超管凭据
|
||||||
const credentials = reactive({
|
const credentials = reactive({
|
||||||
username: 'admin',
|
username: 'admin',
|
||||||
@@ -432,6 +454,9 @@ const loadSettings = async () => {
|
|||||||
// 加载系统配置
|
// 加载系统配置
|
||||||
if (response.data.system) {
|
if (response.data.system) {
|
||||||
Object.assign(systemConfig, response.data.system)
|
Object.assign(systemConfig, response.data.system)
|
||||||
|
const de = response.data.system.defaultEnterpriseId
|
||||||
|
systemConfig.defaultEnterpriseId =
|
||||||
|
de != null && de !== '' && Number(de) > 0 ? Number(de) : null
|
||||||
}
|
}
|
||||||
// 加载小程序文案配置
|
// 加载小程序文案配置
|
||||||
if (response.data.textConfig && typeof response.data.textConfig === 'object') {
|
if (response.data.textConfig && typeof response.data.textConfig === 'object') {
|
||||||
@@ -468,8 +493,21 @@ const loadSettings = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadEnterpriseOptions() {
|
||||||
|
try {
|
||||||
|
const res: any = await request.get('/enterprises', { params: { page: 1, pageSize: 500 } })
|
||||||
|
const list = (res?.code === 200 && res?.data?.list) ? res.data.list : []
|
||||||
|
enterpriseOptions.value = Array.isArray(list)
|
||||||
|
? list.map((r: any) => ({ id: Number(r.id), name: String(r.name || '') }))
|
||||||
|
: []
|
||||||
|
} catch {
|
||||||
|
enterpriseOptions.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadSettings()
|
loadSettings()
|
||||||
|
loadEnterpriseOptions()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 保存配置
|
// 保存配置
|
||||||
@@ -691,6 +729,14 @@ const handleSave = async (section: string) => {
|
|||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-item-full {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-full {
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-section {
|
.form-section {
|
||||||
|
|||||||
@@ -202,10 +202,15 @@ class Analyze extends BaseController
|
|||||||
'amountYuan' => $standardAmountFen > 0 ? round($standardAmountFen / 100, 2) : 0,
|
'amountYuan' => $standardAmountFen > 0 ? round($standardAmountFen / 100, 2) : 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
// 若该类型需付费才显示完整报告:返回给前端的也做脱敏,与详情/历史一致(只显示部分,付费后从详情接口拿完整)
|
// 未付费 / 资料未完善:与 /api/test/detail 一致做预览脱敏,防止直接抓包拿到完整报告
|
||||||
if ($requiresPayment) {
|
$gateResponse = false;
|
||||||
$responsePayload['faceAnalysis'] = null;
|
if ($requiresPayment > 0) {
|
||||||
$responsePayload['boneAnalysis'] = null;
|
$gateResponse = true;
|
||||||
|
} elseif ($earlyUserId > 0 && !TestController::isWechatProfileComplete($earlyUserId)) {
|
||||||
|
$gateResponse = true;
|
||||||
|
}
|
||||||
|
if (is_array($responsePayload) && $gateResponse) {
|
||||||
|
$responsePayload = TestController::filterFaceResultToPreview($responsePayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 把本次测试记录ID一起返回,便于解锁后通过 /api/test/detail 拉取完整数据
|
// 把本次测试记录ID一起返回,便于解锁后通过 /api/test/detail 拉取完整数据
|
||||||
|
|||||||
@@ -50,6 +50,30 @@ class AppConfig extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 系统配置:审核模式、默认企业(无带参入口时小程序回落)
|
||||||
|
$maintenanceMode = false;
|
||||||
|
$defaultEnterpriseId = null;
|
||||||
|
$systemRow = Db::name('system_config')->where('key', 'system')->find();
|
||||||
|
if ($systemRow && !empty($systemRow['value'])) {
|
||||||
|
$sysValEarly = is_string($systemRow['value']) ? json_decode($systemRow['value'], true) : $systemRow['value'];
|
||||||
|
if (is_array($sysValEarly)) {
|
||||||
|
if (!empty($sysValEarly['maintenanceMode'])) {
|
||||||
|
$maintenanceMode = true;
|
||||||
|
}
|
||||||
|
if (!empty($sysValEarly['defaultEnterpriseId'])) {
|
||||||
|
$de = (int) $sysValEarly['defaultEnterpriseId'];
|
||||||
|
if ($de > 0) {
|
||||||
|
$defaultEnterpriseId = $de;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// scope=enterprise 且用户未绑定企业时,用超管默认企业拉企业定价与文案
|
||||||
|
if ($scope !== 'personal' && $enterpriseId === null && $defaultEnterpriseId !== null) {
|
||||||
|
$enterpriseId = $defaultEnterpriseId;
|
||||||
|
$pricingType = 'enterprise';
|
||||||
|
}
|
||||||
|
|
||||||
$config = PricingConfigModel::getByTypeAndEnterprise($pricingType, $enterpriseId);
|
$config = PricingConfigModel::getByTypeAndEnterprise($pricingType, $enterpriseId);
|
||||||
if ($config && !empty($config->config)) {
|
if ($config && !empty($config->config)) {
|
||||||
// PricingConfig 模型已对 config 做 JSON 转换,这里直接当数组/对象用即可
|
// PricingConfig 模型已对 config 做 JSON 转换,这里直接当数组/对象用即可
|
||||||
@@ -103,16 +127,6 @@ class AppConfig extends BaseController
|
|||||||
}
|
}
|
||||||
$siteTitle = $miniprogramName !== '' ? $miniprogramName : ($siteName !== '' ? $siteName : '神仙团队AI性格测试');
|
$siteTitle = $miniprogramName !== '' ? $miniprogramName : ($siteName !== '' ? $siteName : '神仙团队AI性格测试');
|
||||||
|
|
||||||
// 审核模式(原 maintenanceMode):开启后首页展示「开始性格测试」并跳转 test-select
|
|
||||||
$maintenanceMode = false;
|
|
||||||
$systemRow = Db::name('system_config')->where('key', 'system')->find();
|
|
||||||
if ($systemRow && !empty($systemRow['value'])) {
|
|
||||||
$sysVal = is_string($systemRow['value']) ? json_decode($systemRow['value'], true) : $systemRow['value'];
|
|
||||||
if (is_array($sysVal) && !empty($sysVal['maintenanceMode'])) {
|
|
||||||
$maintenanceMode = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 小程序文案配置(分析中提示、按钮、报告标题等)
|
// 小程序文案配置(分析中提示、按钮、报告标题等)
|
||||||
$textConfig = [
|
$textConfig = [
|
||||||
'analyzingTitle' => '正在分析中',
|
'analyzingTitle' => '正在分析中',
|
||||||
@@ -155,6 +169,7 @@ class AppConfig extends BaseController
|
|||||||
'siteTitle' => $siteTitle,
|
'siteTitle' => $siteTitle,
|
||||||
'textConfig' => $textConfig,
|
'textConfig' => $textConfig,
|
||||||
'maintenanceMode' => $maintenanceMode,
|
'maintenanceMode' => $maintenanceMode,
|
||||||
|
'defaultEnterpriseId' => $defaultEnterpriseId,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ class Payment extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 测试结果未带 enterpriseId 时,使用小程序请求中的企业上下文(scene/绑定/超管默认企业)
|
||||||
|
if (empty($enterpriseId) && $enterpriseIdParam > 0) {
|
||||||
|
$enterpriseId = $enterpriseIdParam;
|
||||||
|
}
|
||||||
|
|
||||||
// 充值场景:优先使用显式传入的企业ID,否则回退到当前用户已绑定企业
|
// 充值场景:优先使用显式传入的企业ID,否则回退到当前用户已绑定企业
|
||||||
if ($productType === 'recharge') {
|
if ($productType === 'recharge') {
|
||||||
if ($enterpriseIdParam > 0) {
|
if ($enterpriseIdParam > 0) {
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ class Test extends BaseController
|
|||||||
$requiresPayment = (int) ($row['requiresPayment'] ?? 0);
|
$requiresPayment = (int) ($row['requiresPayment'] ?? 0);
|
||||||
$isPaid = (int) ($row['isPaid'] ?? 0);
|
$isPaid = (int) ($row['isPaid'] ?? 0);
|
||||||
$orderId = isset($row['orderId']) ? (int) $row['orderId'] : null;
|
$orderId = isset($row['orderId']) ? (int) $row['orderId'] : null;
|
||||||
|
$paidAmountRow = isset($row['paidAmount']) ? (int) $row['paidAmount'] : 0;
|
||||||
|
$needPayUnlock = $requiresPayment && !$isPaid && $paidAmountRow > 0;
|
||||||
|
$profileIncomplete = !self::isWechatProfileComplete($userId);
|
||||||
|
|
||||||
$raw = $row['resultData'] ?? ($row['result'] ?? null);
|
$raw = $row['resultData'] ?? ($row['result'] ?? null);
|
||||||
$data = null;
|
$data = null;
|
||||||
@@ -87,8 +90,14 @@ class Test extends BaseController
|
|||||||
$decoded = json_decode($raw, true);
|
$decoded = json_decode($raw, true);
|
||||||
$data = is_array($decoded) ? $decoded : $raw;
|
$data = is_array($decoded) ? $decoded : $raw;
|
||||||
}
|
}
|
||||||
if ($requiresPayment && !$isPaid && $data !== null) {
|
if ($data !== null && is_array($data)) {
|
||||||
$data = $this->filterResultToPartial($testType, $data);
|
if (in_array($testType, ['face', 'ai'], true)) {
|
||||||
|
if ($needPayUnlock || $profileIncomplete) {
|
||||||
|
$data = self::filterFaceResultToPreview($data);
|
||||||
|
}
|
||||||
|
} elseif ($requiresPayment && !$isPaid) {
|
||||||
|
$data = $this->filterResultToPartial($testType, $data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$paymentFields = [
|
$paymentFields = [
|
||||||
@@ -358,8 +367,15 @@ class Test extends BaseController
|
|||||||
$testType = $row['testType'] ?? '';
|
$testType = $row['testType'] ?? '';
|
||||||
// 仅当需要付款且未付款且金额>0 时才脱敏;系统设置需付款但金额为0 则直接可查看
|
// 仅当需要付款且未付款且金额>0 时才脱敏;系统设置需付款但金额为0 则直接可查看
|
||||||
$needPaymentToUnlock = $requiresPayment && !$isPaid && $paidAmount > 0;
|
$needPaymentToUnlock = $requiresPayment && !$isPaid && $paidAmount > 0;
|
||||||
if ($needPaymentToUnlock && $data !== null) {
|
$profileIncomplete = !self::isWechatProfileComplete($userId);
|
||||||
$data = $this->filterResultToPartial($testType, $data);
|
if ($data !== null && is_array($data)) {
|
||||||
|
if (in_array($testType, ['face', 'ai'], true)) {
|
||||||
|
if ($needPaymentToUnlock || $profileIncomplete) {
|
||||||
|
$data = self::filterFaceResultToPreview($data);
|
||||||
|
}
|
||||||
|
} elseif ($needPaymentToUnlock) {
|
||||||
|
$data = $this->filterResultToPartial($testType, $data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success([
|
return success([
|
||||||
@@ -550,12 +566,6 @@ class Test extends BaseController
|
|||||||
if (!is_array($data)) {
|
if (!is_array($data)) {
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
if ($testType === 'face' || $testType === 'ai') {
|
|
||||||
$out = $data;
|
|
||||||
$out['faceAnalysis'] = null;
|
|
||||||
$out['boneAnalysis'] = null;
|
|
||||||
return $out;
|
|
||||||
}
|
|
||||||
if ($testType === 'mbti') {
|
if ($testType === 'mbti') {
|
||||||
return [
|
return [
|
||||||
'mbtiType' => $data['mbtiType'] ?? $data['mbti'] ?? '',
|
'mbtiType' => $data['mbtiType'] ?? $data['mbti'] ?? '',
|
||||||
@@ -577,6 +587,82 @@ class Test extends BaseController
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信用户资料是否与小程序 isProfileComplete 一致:头像、昵称、手机号必填
|
||||||
|
*/
|
||||||
|
public static function isWechatProfileComplete(int $userId): bool
|
||||||
|
{
|
||||||
|
if ($userId <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$row = Db::name('wechat_users')->where('id', $userId)->field('nickname,avatar,phone')->find();
|
||||||
|
if (!$row) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$nick = trim((string) ($row['nickname'] ?? ''));
|
||||||
|
$avatar = trim((string) ($row['avatar'] ?? ''));
|
||||||
|
$phone = trim((string) ($row['phone'] ?? ''));
|
||||||
|
|
||||||
|
return $nick !== '' && $avatar !== '' && $phone !== '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸/AI 分析报告:未付费或资料未完善时仅返回预览级字段(防止抓包看全文)
|
||||||
|
*/
|
||||||
|
public static function filterFaceResultToPreview(array $data): array
|
||||||
|
{
|
||||||
|
$out = $data;
|
||||||
|
$out['faceAnalysis'] = null;
|
||||||
|
$out['boneAnalysis'] = null;
|
||||||
|
unset($out['faceAnalysisText'], $out['boneAnalysisText']);
|
||||||
|
$out['relationship'] = '';
|
||||||
|
$out['portrait'] = null;
|
||||||
|
$out['hrView'] = null;
|
||||||
|
$out['bossView'] = null;
|
||||||
|
$out['resumeHighlights'] = '';
|
||||||
|
if (isset($out['careers'])) {
|
||||||
|
$out['careers'] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sum = (string) ($out['personalitySummary'] ?? '');
|
||||||
|
$ov = (string) ($out['overview'] ?? '');
|
||||||
|
$out['personalitySummary'] = self::truncatePreviewText($sum, 72);
|
||||||
|
$out['overview'] = self::truncatePreviewText($ov, 72);
|
||||||
|
$out['gallupTop3'] = [];
|
||||||
|
|
||||||
|
$adv = $out['advantages'] ?? [];
|
||||||
|
if (is_array($adv) && $adv !== []) {
|
||||||
|
$slice = array_slice($adv, 0, 2);
|
||||||
|
$out['advantages'] = array_map(function ($x) {
|
||||||
|
return self::truncatePreviewText((string) $x, 28);
|
||||||
|
}, $slice);
|
||||||
|
} else {
|
||||||
|
$out['advantages'] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function truncatePreviewText(string $s, int $maxChars): string
|
||||||
|
{
|
||||||
|
$s = trim($s);
|
||||||
|
if ($s === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (function_exists('mb_strlen') && function_exists('mb_substr')) {
|
||||||
|
if (mb_strlen($s, 'UTF-8') > $maxChars) {
|
||||||
|
return mb_substr($s, 0, $maxChars, 'UTF-8') . '…';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
if (strlen($s) > $maxChars) {
|
||||||
|
return substr($s, 0, $maxChars) . '…';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前用户最近的 MBTI / DISC / PDP 测试记录(暂不使用人脸/AI 结果),供简历综合分析使用
|
* 获取当前用户最近的 MBTI / DISC / PDP 测试记录(暂不使用人脸/AI 结果),供简历综合分析使用
|
||||||
* @param int $userId 微信用户 ID
|
* @param int $userId 微信用户 ID
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace app\controller\superadmin;
|
|||||||
use app\BaseController;
|
use app\BaseController;
|
||||||
use app\model\SystemConfig as SystemConfigModel;
|
use app\model\SystemConfig as SystemConfigModel;
|
||||||
use app\model\User as UserModel;
|
use app\model\User as UserModel;
|
||||||
|
use app\model\Enterprise as EnterpriseModel;
|
||||||
use think\facade\Request;
|
use think\facade\Request;
|
||||||
use think\facade\Db;
|
use think\facade\Db;
|
||||||
|
|
||||||
@@ -55,7 +56,8 @@ class Settings extends BaseController
|
|||||||
'miniprogramName' => '神仙团队AI性格测试',
|
'miniprogramName' => '神仙团队AI性格测试',
|
||||||
'maintenanceMode' => false,
|
'maintenanceMode' => false,
|
||||||
'maxTestsPerDay' => 100,
|
'maxTestsPerDay' => 100,
|
||||||
'trialTestCount' => 10
|
'trialTestCount' => 10,
|
||||||
|
'defaultEnterpriseId' => null,
|
||||||
],
|
],
|
||||||
'notification' => $notificationConfig ? $notificationConfig->value : [
|
'notification' => $notificationConfig ? $notificationConfig->value : [
|
||||||
'emailNotification' => true,
|
'emailNotification' => true,
|
||||||
@@ -100,12 +102,30 @@ class Settings extends BaseController
|
|||||||
$input = [];
|
$input = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$allowedKeys = ['siteName', 'siteDescription', 'miniprogramName', 'maintenanceMode', 'maxTestsPerDay', 'trialTestCount'];
|
$allowedKeys = ['siteName', 'siteDescription', 'miniprogramName', 'maintenanceMode', 'maxTestsPerDay', 'trialTestCount', 'defaultEnterpriseId'];
|
||||||
$data = array_intersect_key($input, array_flip($allowedKeys));
|
$data = array_intersect_key($input, array_flip($allowedKeys));
|
||||||
// 兼容 fallback:JSON 解析失败时尝试 Request::only
|
// 兼容 fallback:JSON 解析失败时尝试 Request::only
|
||||||
if (empty($data)) {
|
if (empty($data)) {
|
||||||
$data = Request::only($allowedKeys);
|
$data = Request::only($allowedKeys);
|
||||||
}
|
}
|
||||||
|
// 默认企业:0 或空视为不启用
|
||||||
|
if (array_key_exists('defaultEnterpriseId', $data)) {
|
||||||
|
$de = $data['defaultEnterpriseId'];
|
||||||
|
if ($de === '' || $de === null) {
|
||||||
|
$data['defaultEnterpriseId'] = null;
|
||||||
|
} else {
|
||||||
|
$deInt = (int) $de;
|
||||||
|
if ($deInt <= 0) {
|
||||||
|
$data['defaultEnterpriseId'] = null;
|
||||||
|
} else {
|
||||||
|
$exists = EnterpriseModel::where('id', $deInt)->find();
|
||||||
|
if (!$exists) {
|
||||||
|
return error('所选默认企业不存在', 400);
|
||||||
|
}
|
||||||
|
$data['defaultEnterpriseId'] = $deInt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
$textConfig = $input['textConfig'] ?? (Request::param('textConfig') ?: []);
|
$textConfig = $input['textConfig'] ?? (Request::param('textConfig') ?: []);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -117,7 +137,13 @@ class Settings extends BaseController
|
|||||||
$config->enterprise_id = 0;
|
$config->enterprise_id = 0;
|
||||||
$config->description = '系统基础配置';
|
$config->description = '系统基础配置';
|
||||||
}
|
}
|
||||||
$config->value = $data;
|
// 合并保存,避免仅提交部分字段时丢失其它键(如 defaultEnterpriseId)
|
||||||
|
$oldVal = $config->value;
|
||||||
|
$oldArr = is_array($oldVal) ? $oldVal : (is_string($oldVal) ? (json_decode($oldVal, true) ?: []) : []);
|
||||||
|
if (!is_array($oldArr)) {
|
||||||
|
$oldArr = [];
|
||||||
|
}
|
||||||
|
$config->value = array_merge($oldArr, $data);
|
||||||
$config->save();
|
$config->save();
|
||||||
|
|
||||||
// 更新站点信息
|
// 更新站点信息
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ App({
|
|||||||
appScope: 'personal',
|
appScope: 'personal',
|
||||||
// 扫码进入企业页时 scene 解析出的企业ID(e_123),提交测试/分析时优先使用
|
// 扫码进入企业页时 scene 解析出的企业ID(e_123),提交测试/分析时优先使用
|
||||||
enterpriseIdFromScene: null,
|
enterpriseIdFromScene: null,
|
||||||
|
// 超管配置的默认企业 ID(无 scene/eid 等入口参数时回落)
|
||||||
|
defaultEnterpriseId: null,
|
||||||
// API基础地址(开发时用本地,生产环境替换为实际域名)
|
// API基础地址(开发时用本地,生产环境替换为实际域名)
|
||||||
apiBase: 'https://mbtiapi.quwanzhi.com',
|
apiBase: 'https://mbtiapi.quwanzhi.com',
|
||||||
//apiBase: 'http://mbti.com',
|
//apiBase: 'http://mbti.com',
|
||||||
@@ -41,6 +43,11 @@ App({
|
|||||||
if (cfg) {
|
if (cfg) {
|
||||||
if (cfg.siteTitle) this.globalData.siteTitle = cfg.siteTitle
|
if (cfg.siteTitle) this.globalData.siteTitle = cfg.siteTitle
|
||||||
if (cfg.maintenanceMode !== undefined) this.globalData.maintenanceMode = !!cfg.maintenanceMode
|
if (cfg.maintenanceMode !== undefined) this.globalData.maintenanceMode = !!cfg.maintenanceMode
|
||||||
|
if (cfg.defaultEnterpriseId != null && Number(cfg.defaultEnterpriseId) > 0) {
|
||||||
|
this.globalData.defaultEnterpriseId = Number(cfg.defaultEnterpriseId)
|
||||||
|
} else {
|
||||||
|
this.globalData.defaultEnterpriseId = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
@@ -275,20 +282,16 @@ App({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 保存测试结果
|
// 保存测试结果
|
||||||
saveTestResult(type, result) {
|
saveTestResult(type, result) {
|
||||||
|
const { getEnterpriseIdForApiPayload } = require('./utils/enterpriseContext.js')
|
||||||
const key = `${type}Result`
|
const key = `${type}Result`
|
||||||
wx.setStorageSync(key, result)
|
wx.setStorageSync(key, result)
|
||||||
this.globalData[key] = result
|
this.globalData[key] = result
|
||||||
|
|
||||||
// 同步到服务器(需携带 token,后端从 JWT 解析 userId)
|
// 同步到服务器(需携带 token,后端从 JWT 解析 userId)
|
||||||
if (this.globalData.token) {
|
if (this.globalData.token) {
|
||||||
const scope = this.globalData.appScope || 'personal'
|
const enterpriseId = getEnterpriseIdForApiPayload()
|
||||||
const storedUser = wx.getStorageSync('userInfo') || null
|
|
||||||
const enterpriseId =
|
|
||||||
scope === 'enterprise'
|
|
||||||
? (this.globalData.enterpriseIdFromScene || (this.globalData.userInfo && this.globalData.userInfo.enterpriseId) || (storedUser && storedUser.enterpriseId) || null)
|
|
||||||
: null
|
|
||||||
wx.request({
|
wx.request({
|
||||||
url: `${this.globalData.apiBase}/api/test/submit`,
|
url: `${this.globalData.apiBase}/api/test/submit`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -301,7 +304,7 @@ App({
|
|||||||
answers: result.answers || [],
|
answers: result.answers || [],
|
||||||
result: result,
|
result: result,
|
||||||
userId: this.globalData.userInfo?.id ?? this.globalData.openId,
|
userId: this.globalData.userInfo?.id ?? this.globalData.openId,
|
||||||
enterpriseId: enterpriseId || undefined,
|
enterpriseId: enterpriseId != null ? enterpriseId : undefined,
|
||||||
testDuration: result.testDuration || 0,
|
testDuration: result.testDuration || 0,
|
||||||
timestamp: new Date().toISOString()
|
timestamp: new Date().toISOString()
|
||||||
}
|
}
|
||||||
@@ -335,6 +338,11 @@ App({
|
|||||||
if (data.siteTitle) this.globalData.siteTitle = data.siteTitle
|
if (data.siteTitle) this.globalData.siteTitle = data.siteTitle
|
||||||
if (data.textConfig) this.globalData.textConfig = data.textConfig
|
if (data.textConfig) this.globalData.textConfig = data.textConfig
|
||||||
if (data.maintenanceMode !== undefined) this.globalData.maintenanceMode = !!data.maintenanceMode
|
if (data.maintenanceMode !== undefined) this.globalData.maintenanceMode = !!data.maintenanceMode
|
||||||
|
if (data.defaultEnterpriseId != null && Number(data.defaultEnterpriseId) > 0) {
|
||||||
|
this.globalData.defaultEnterpriseId = Number(data.defaultEnterpriseId)
|
||||||
|
} else {
|
||||||
|
this.globalData.defaultEnterpriseId = null
|
||||||
|
}
|
||||||
resolve(data)
|
resolve(data)
|
||||||
} else {
|
} else {
|
||||||
reject(new Error(res.data && res.data.message ? res.data.message : '获取配置失败'))
|
reject(new Error(res.data && res.data.message ? res.data.message : '获取配置失败'))
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// pages/enterprise/index.js - 企业版首页
|
// pages/enterprise/index.js - 企业版首页
|
||||||
const app = getApp()
|
const app = getApp()
|
||||||
const { request } = require('../../utils/request')
|
const { request } = require('../../utils/request')
|
||||||
|
const { getEffectiveEnterpriseId } = require('../../utils/enterpriseContext.js')
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
@@ -70,9 +71,9 @@ Page({
|
|||||||
maintenanceMode
|
maintenanceMode
|
||||||
})
|
})
|
||||||
|
|
||||||
// 未绑定企业的用户:若从邀请码扫码进入(有 enterpriseIdFromScene)也允许使用企业版
|
// 未绑定企业的用户:扫码带 eid 或超管配置了默认企业时也允许使用企业版
|
||||||
const userInfo = app.globalData.userInfo || wx.getStorageSync('userInfo') || {}
|
const userInfo = app.globalData.userInfo || wx.getStorageSync('userInfo') || {}
|
||||||
const fromInvite = !!app.globalData.enterpriseIdFromScene
|
const fromInvite = !!app.globalData.enterpriseIdFromScene || !!(app.globalData.defaultEnterpriseId && Number(app.globalData.defaultEnterpriseId) > 0)
|
||||||
const redirectBack = () => {
|
const redirectBack = () => {
|
||||||
wx.showToast({ title: '您尚未绑定任何企业,无法使用企业版', icon: 'none', duration: 2500 })
|
wx.showToast({ title: '您尚未绑定任何企业,无法使用企业版', icon: 'none', duration: 2500 })
|
||||||
setTimeout(() => wx.switchTab({ url: '/pages/index/index' }), 600)
|
setTimeout(() => wx.switchTab({ url: '/pages/index/index' }), 600)
|
||||||
@@ -119,7 +120,7 @@ Page({
|
|||||||
maintenanceMode
|
maintenanceMode
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if ((cfg && cfg.pricingType) !== 'enterprise' && !app.globalData.enterpriseIdFromScene) {
|
if ((cfg && cfg.pricingType) !== 'enterprise' && !app.globalData.enterpriseIdFromScene && !(app.globalData.defaultEnterpriseId && Number(app.globalData.defaultEnterpriseId) > 0)) {
|
||||||
redirectBack()
|
redirectBack()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -176,7 +177,7 @@ Page({
|
|||||||
wx.navigateTo({ url: '/pages/test-select/index' })
|
wx.navigateTo({ url: '/pages/test-select/index' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const eid = (app.globalData && app.globalData.enterpriseIdFromScene) || (app.globalData && app.globalData.userInfo && app.globalData.userInfo.enterpriseId) || (wx.getStorageSync('userInfo') || {}).enterpriseId || null
|
const eid = getEffectiveEnterpriseId()
|
||||||
const query = eid ? `?enterpriseId=${eid}&pageSize=1` : '?pageSize=1'
|
const query = eid ? `?enterpriseId=${eid}&pageSize=1` : '?pageSize=1'
|
||||||
request({
|
request({
|
||||||
url: '/api/enterprise/resume-uploads' + query,
|
url: '/api/enterprise/resume-uploads' + query,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// pages/enterprise/resume-history.js - 简历上传记录(历史)
|
// pages/enterprise/resume-history.js - 简历上传记录(历史)
|
||||||
const app = getApp()
|
const app = getApp()
|
||||||
|
const { getEffectiveEnterpriseId } = require('../../utils/enterpriseContext.js')
|
||||||
const { request } = require('../../utils/request')
|
const { request } = require('../../utils/request')
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
@@ -21,7 +22,7 @@ Page({
|
|||||||
|
|
||||||
loadList() {
|
loadList() {
|
||||||
this.setData({ loading: true })
|
this.setData({ loading: true })
|
||||||
const eid = (app.globalData && app.globalData.enterpriseIdFromScene) || (app.globalData && app.globalData.userInfo && app.globalData.userInfo.enterpriseId) || (wx.getStorageSync('userInfo') || {}).enterpriseId || null
|
const eid = getEffectiveEnterpriseId()
|
||||||
const query = eid ? `?enterpriseId=${eid}&pageSize=100` : '?pageSize=100'
|
const query = eid ? `?enterpriseId=${eid}&pageSize=100` : '?pageSize=100'
|
||||||
request({
|
request({
|
||||||
url: '/api/enterprise/resume-uploads' + query,
|
url: '/api/enterprise/resume-uploads' + query,
|
||||||
@@ -48,7 +49,7 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
uploadResume() {
|
uploadResume() {
|
||||||
const eid = (app.globalData && app.globalData.enterpriseIdFromScene) || (app.globalData && app.globalData.userInfo && app.globalData.userInfo.enterpriseId) || (wx.getStorageSync('userInfo') || {}).enterpriseId || null
|
const eid = getEffectiveEnterpriseId()
|
||||||
wx.chooseMessageFile({
|
wx.chooseMessageFile({
|
||||||
count: 1,
|
count: 1,
|
||||||
type: 'file',
|
type: 'file',
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// pages/history/index.js - 测试历史记录(一次拉取全部,时间行右侧展示企业名)
|
// pages/history/index.js - 测试历史记录(一次拉取全部,时间行右侧展示企业名)
|
||||||
const app = getApp()
|
const app = getApp()
|
||||||
|
const { getEffectiveEnterpriseId } = require('../../utils/enterpriseContext.js')
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
@@ -15,10 +16,7 @@ Page({
|
|||||||
const gd = app.globalData || {}
|
const gd = app.globalData || {}
|
||||||
const storedUser = wx.getStorageSync('userInfo') || null
|
const storedUser = wx.getStorageSync('userInfo') || null
|
||||||
const scope = gd.appScope || 'personal'
|
const scope = gd.appScope || 'personal'
|
||||||
const enterpriseId = gd.enterpriseIdFromScene
|
const enterpriseId = getEffectiveEnterpriseId()
|
||||||
|| (gd.userInfo && gd.userInfo.enterpriseId)
|
|
||||||
|| (storedUser && storedUser.enterpriseId)
|
|
||||||
|| null
|
|
||||||
return scope === 'enterprise' || !!enterpriseId
|
return scope === 'enterprise' || !!enterpriseId
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
const app = getApp()
|
const app = getApp()
|
||||||
const payment = require('../../utils/payment')
|
const payment = require('../../utils/payment')
|
||||||
const { hasPhone, bindPhoneByCode, isProfileComplete } = require('../../utils/phoneAuth.js')
|
const { hasPhone, bindPhoneByCode, isProfileComplete } = require('../../utils/phoneAuth.js')
|
||||||
|
const { getEnterpriseIdForApiPayload } = require('../../utils/enterpriseContext.js')
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
@@ -182,12 +183,8 @@ Page({
|
|||||||
this.setData({ progress: Math.floor(progress), analyzingTip: tips[tipIndex] })
|
this.setData({ progress: Math.floor(progress), analyzingTip: tips[tipIndex] })
|
||||||
}, 200)
|
}, 200)
|
||||||
|
|
||||||
// 调用后端API:appScope='enterprise' 时才传 enterpriseId,个人版不传
|
// 个人版入口不带企业参数;企业版才回落绑定/默认企业
|
||||||
const userInfo = app.globalData.userInfo || wx.getStorageSync('userInfo') || {}
|
const enterpriseId = getEnterpriseIdForApiPayload()
|
||||||
const scope = (app.globalData && app.globalData.appScope) || 'personal'
|
|
||||||
const enterpriseId = scope === 'enterprise'
|
|
||||||
? (app.globalData.enterpriseIdFromScene || userInfo.enterpriseId || null)
|
|
||||||
: null
|
|
||||||
wx.request({
|
wx.request({
|
||||||
url: `${app.globalData.apiBase}/api/analyze`,
|
url: `${app.globalData.apiBase}/api/analyze`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -198,7 +195,7 @@ Page({
|
|||||||
data: {
|
data: {
|
||||||
photoUrls: photos,
|
photoUrls: photos,
|
||||||
userId: app.globalData.openId || '',
|
userId: app.globalData.openId || '',
|
||||||
...(enterpriseId ? { enterpriseId: Number(enterpriseId) } : {})
|
...(enterpriseId != null ? { enterpriseId: Number(enterpriseId) } : {})
|
||||||
},
|
},
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
clearInterval(timer)
|
clearInterval(timer)
|
||||||
|
|||||||
@@ -53,98 +53,108 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 性格类型分析卡片 -->
|
<!-- 报告预览区:未解锁时整区加盖高遮罩,避免概述/盖洛普等全文外露 -->
|
||||||
<view class="card personality-card" wx:if="{{!hasError}}">
|
<view class="report-gate-wrap" wx:if="{{!hasError}}">
|
||||||
<text class="card-title">性格类型分析</text>
|
<view
|
||||||
|
class="card personality-card {{(!isProfileComplete || (isProfileComplete && payInfo.requiresPayment && !payInfo.isPaid)) ? 'personality-card--locked' : ''}}"
|
||||||
|
>
|
||||||
|
<text class="card-title">性格类型分析</text>
|
||||||
|
|
||||||
<!-- MBTI类型 -->
|
<view class="personality-type">
|
||||||
<view class="personality-type">
|
<text class="type-code">{{result.mbti}}</text>
|
||||||
<text class="type-code">{{result.mbti}}</text>
|
<text class="type-name">{{result.title}}</text>
|
||||||
<text class="type-name">{{result.title}}</text>
|
<text class="type-desc">{{result.summary}}</text>
|
||||||
<text class="type-desc">{{result.summary}}</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- PDP和DISC -->
|
|
||||||
<view class="type-details">
|
|
||||||
<view class="type-box pdp-box">
|
|
||||||
<text class="type-label">PDP主性格</text>
|
|
||||||
<text class="type-value">{{result.pdp || '--'}}</text>
|
|
||||||
<text class="type-sub" wx:if="{{result.pdpAux}}">辅助: {{result.pdpAux}}</text>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="type-box disc-box">
|
|
||||||
<text class="type-label">DISC类型</text>
|
<view class="type-details">
|
||||||
<text class="type-value">{{result.disc || '--'}}型</text>
|
<view class="type-box pdp-box">
|
||||||
<text class="type-sub" wx:if="{{result.discAux}}">辅助: {{result.discAux}}</text>
|
<text class="type-label">PDP主性格</text>
|
||||||
|
<text class="type-value">{{result.pdp || '--'}}</text>
|
||||||
|
<text class="type-sub" wx:if="{{result.pdpAux}}">辅助: {{result.pdpAux}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="type-box disc-box">
|
||||||
|
<text class="type-label">DISC类型</text>
|
||||||
|
<text class="type-value">{{result.disc || '--'}}型</text>
|
||||||
|
<text class="type-sub" wx:if="{{result.discAux}}">辅助: {{result.discAux}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="advantages-box" wx:if="{{result.traits.length > 0}}">
|
||||||
|
<text class="advantages-label">主要优势</text>
|
||||||
|
<view class="advantages-list">
|
||||||
|
<view class="advantage-item" wx:for="{{result.traits}}" wx:key="*this">
|
||||||
|
<view class="advantage-dot"></view>
|
||||||
|
<text class="advantage-text">{{item}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="next-btn" bindtap="goToMBTI">
|
||||||
|
<text class="next-btn-text">下一步:详细性格测试 →</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 主要优势 -->
|
<view
|
||||||
<view class="advantages-box" wx:if="{{result.traits.length > 0}}">
|
class="card report-gate-teaser {{(!isProfileComplete || (isProfileComplete && payInfo.requiresPayment && !payInfo.isPaid)) ? 'report-gate-teaser--locked' : ''}}"
|
||||||
<text class="advantages-label">主要优势</text>
|
wx:if="{{result.summary}}"
|
||||||
<view class="advantages-list">
|
>
|
||||||
<view class="advantage-item" wx:for="{{result.traits}}" wx:key="*this">
|
<text class="card-title">性格概述</text>
|
||||||
<view class="advantage-dot"></view>
|
<text class="card-text">{{result.summary}}</text>
|
||||||
<text class="advantage-text">{{item}}</text>
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
class="card gallup-card report-gate-teaser {{(!isProfileComplete || (isProfileComplete && payInfo.requiresPayment && !payInfo.isPaid)) ? 'report-gate-teaser--locked' : ''}}"
|
||||||
|
wx:if="{{result.gallupTop3.length > 0}}"
|
||||||
|
>
|
||||||
|
<text class="card-title">盖洛普前三大优势</text>
|
||||||
|
<view class="gallup-list">
|
||||||
|
<view class="gallup-item" wx:for="{{result.gallupTop3}}" wx:key="*this">
|
||||||
|
<text class="gallup-rank">{{index + 1}}</text>
|
||||||
|
<text class="gallup-text">{{item}}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="next-btn" bindtap="goToMBTI">
|
<!-- 全幅遮罩 + 底部操作(覆盖性格概述、盖洛普等主要预览,仅留顶部少量「悬念」) -->
|
||||||
<text class="next-btn-text">下一步:详细性格测试 →</text>
|
<view
|
||||||
</view>
|
class="report-gate-overlay"
|
||||||
</view>
|
wx:if="{{!isProfileComplete || (isProfileComplete && payInfo.requiresPayment && !payInfo.isPaid)}}"
|
||||||
|
>
|
||||||
<!-- 性格概述 -->
|
<view class="report-gate-gradient"></view>
|
||||||
<view class="card" wx:if="{{!hasError && result.summary}}">
|
<!-- 底部白区内:标题 + 说明 + 按钮作为一组上下居中 -->
|
||||||
<text class="card-title">性格概述</text>
|
<view class="report-gate-cta-wrap">
|
||||||
<text class="card-text">{{result.summary}}</text>
|
<view class="report-gate-panel">
|
||||||
</view>
|
<text class="paywall-fake-title">完整版性格深度解析</text>
|
||||||
|
<text class="paywall-tip">解锁后将展示完整报告内容</text>
|
||||||
<!-- 盖洛普前三大优势(付费后/免费皆展示,有数据才显示) -->
|
<view
|
||||||
<view class="card gallup-card" wx:if="{{!hasError && result.gallupTop3.length > 0}}">
|
class="paywall-btn paywall-btn-inline"
|
||||||
<text class="card-title">盖洛普前三大优势</text>
|
wx:if="{{!isProfileComplete}}"
|
||||||
<view class="gallup-list">
|
bindtap="goToCompleteProfile"
|
||||||
<view class="gallup-item" wx:for="{{result.gallupTop3}}" wx:key="*this">
|
>
|
||||||
<text class="gallup-rank">{{index + 1}}</text>
|
<text class="paywall-btn-main">完善资料</text>
|
||||||
<text class="gallup-text">{{item}}</text>
|
</view>
|
||||||
</view>
|
<block wx:elif="{{isProfileComplete && payInfo.requiresPayment && !payInfo.isPaid}}">
|
||||||
</view>
|
<button
|
||||||
</view>
|
class="paywall-btn paywall-btn-inline"
|
||||||
|
wx:if="{{!hasPhone}}"
|
||||||
<!-- 付费解锁:未完善资料显示「完善资料」;已完善且有价格显示「解锁完整报告」;已完善且无价格则不显示 -->
|
open-type="getPhoneNumber"
|
||||||
<view class="card paywall-card" wx:if="{{!hasError && (!isProfileComplete || (isProfileComplete && payInfo.requiresPayment && !payInfo.isPaid))}}">
|
bindgetphonenumber="onGetPhoneNumberForFacePay"
|
||||||
<view class="paywall-content">
|
>
|
||||||
<text class="paywall-fake-title">完整版性格深度解析</text>
|
<text class="paywall-btn-main">解锁完整报告</text>
|
||||||
<text class="paywall-tip">解锁后将展示完整报告内容</text>
|
<text class="paywall-btn-price">¥{{payInfo.amountYuan || 0}} / 次</text>
|
||||||
<!-- 未完善资料:用户点击后手动跳转 -->
|
</button>
|
||||||
<view
|
<view
|
||||||
class="paywall-btn"
|
class="paywall-btn paywall-btn-inline"
|
||||||
wx:if="{{!isProfileComplete}}"
|
wx:elif="{{hasPhone}}"
|
||||||
bindtap="goToCompleteProfile"
|
bindtap="unlockFullReport"
|
||||||
>
|
>
|
||||||
<text class="paywall-btn-main">完善资料</text>
|
<text class="paywall-btn-main">解锁完整报告</text>
|
||||||
</view>
|
<text class="paywall-btn-price">¥{{payInfo.amountYuan || 0}} / 次</text>
|
||||||
<!-- 已完善资料且有价格:解锁按钮 -->
|
</view>
|
||||||
<block wx:elif="{{isProfileComplete && payInfo.requiresPayment && !payInfo.isPaid}}">
|
</block>
|
||||||
<button
|
<text class="paywall-tip paywall-tip-panel" wx:if="{{isProfileComplete}}">一次性解锁本次{{reportTitle || '分析报告'}},永久保存在「历史记录」中</text>
|
||||||
class="paywall-btn"
|
|
||||||
wx:if="{{!hasPhone}}"
|
|
||||||
open-type="getPhoneNumber"
|
|
||||||
bindgetphonenumber="onGetPhoneNumberForFacePay"
|
|
||||||
>
|
|
||||||
<text class="paywall-btn-main">解锁完整报告</text>
|
|
||||||
<text class="paywall-btn-price">¥{{payInfo.amountYuan || 0}} / 次</text>
|
|
||||||
</button>
|
|
||||||
<view
|
|
||||||
class="paywall-btn"
|
|
||||||
wx:elif="{{hasPhone}}"
|
|
||||||
bindtap="unlockFullReport"
|
|
||||||
>
|
|
||||||
<text class="paywall-btn-main">解锁完整报告</text>
|
|
||||||
<text class="paywall-btn-price">¥{{payInfo.amountYuan || 0}} / 次</text>
|
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</view>
|
||||||
<text class="paywall-tip" wx:if="{{isProfileComplete}}">一次性解锁本次{{reportTitle || '分析报告'}},永久保存在「历史记录」中</text>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|||||||
@@ -273,6 +273,156 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.paywall-tip-panel {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
padding: 0 8rpx;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 报告预览门禁(人脸分析报告):整区遮罩 + 预览截断 ========== */
|
||||||
|
.report-gate-wrap {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-gate-overlay {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 20;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: stretch;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 占据遮罩下半区,组内标题/说明/按钮垂直居中,避免贴底留白过大 */
|
||||||
|
.report-gate-cta-wrap {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* 占遮罩层约一半高度,保证内部 flex 垂直居中真正留白上下对称 */
|
||||||
|
height: 48%;
|
||||||
|
min-height: 400rpx;
|
||||||
|
max-height: 640rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: stretch;
|
||||||
|
/* 整体上移,避免贴底 */
|
||||||
|
margin-bottom: 96rpx;
|
||||||
|
padding: 16rpx 0 calc(20rpx + env(safe-area-inset-bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-gate-gradient {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
/* 高透明白雾,避免大块灰底发闷 */
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(255, 255, 255, 0) 0%,
|
||||||
|
rgba(255, 255, 255, 0.22) 10%,
|
||||||
|
rgba(255, 255, 255, 0.48) 28%,
|
||||||
|
rgba(255, 255, 255, 0.72) 48%,
|
||||||
|
rgba(255, 255, 255, 0.88) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-gate-panel {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20rpx 20rpx 8rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: linear-gradient(180deg, transparent 0%, rgba(255, 255, 255, 0.5) 18%, rgba(255, 255, 255, 0.96) 55%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-gate-panel .paywall-fake-title {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-gate-panel .paywall-tip {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 遮罩内主按钮:不再用绝对定位贴底,避免区域过矮 */
|
||||||
|
.paywall-btn-inline {
|
||||||
|
position: relative !important;
|
||||||
|
left: auto !important;
|
||||||
|
right: auto !important;
|
||||||
|
bottom: auto !important;
|
||||||
|
width: 90% !important;
|
||||||
|
max-width: 640rpx;
|
||||||
|
margin: 28rpx auto 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-gate-panel .paywall-btn-inline::after {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 未解锁:限制概述与盖洛普可见行数 */
|
||||||
|
.report-gate-teaser--locked .card-text {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 5;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-gate-teaser--locked .gallup-list {
|
||||||
|
max-height: 96rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-gate-teaser--locked .gallup-list::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 48rpx;
|
||||||
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0), #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 未解锁:压缩首屏性格区可读内容 */
|
||||||
|
.personality-card--locked .type-desc {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.personality-card--locked .advantages-box {
|
||||||
|
max-height: 140rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.personality-card--locked .advantages-box::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 56rpx;
|
||||||
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0), #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.personality-card--locked .next-btn {
|
||||||
|
opacity: 0.45;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========== 性格类型卡片 ========== */
|
/* ========== 性格类型卡片 ========== */
|
||||||
.personality-card {
|
.personality-card {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
const { getApiBase } = require('../../utils/request')
|
const { getApiBase } = require('../../utils/request')
|
||||||
|
const { getEffectiveEnterpriseId } = require('../../utils/enterpriseContext.js')
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
@@ -21,9 +22,7 @@ Page({
|
|||||||
const token = wx.getStorageSync('token') || gd.token || ''
|
const token = wx.getStorageSync('token') || gd.token || ''
|
||||||
const scope = gd.appScope || 'personal'
|
const scope = gd.appScope || 'personal'
|
||||||
// 企业 ID:按优先级取 scene > globalData.userInfo > storage.userInfo
|
// 企业 ID:按优先级取 scene > globalData.userInfo > storage.userInfo
|
||||||
const eid = scope === 'enterprise'
|
const eid = scope === 'enterprise' ? getEffectiveEnterpriseId() : null
|
||||||
? (gd.enterpriseIdFromScene || (gd.userInfo && gd.userInfo.enterpriseId) || storedUser.enterpriseId || null)
|
|
||||||
: null
|
|
||||||
let url = apiBase.replace(/\/$/, '') + '/api/distribution/poster'
|
let url = apiBase.replace(/\/$/, '') + '/api/distribution/poster'
|
||||||
if (eid) url += `?eid=${eid}&scope=enterprise`
|
if (eid) url += `?eid=${eid}&scope=enterprise`
|
||||||
else if (scope === 'enterprise') url += '?scope=enterprise' // 企业模式但 eid 未知,后端从 DB 取
|
else if (scope === 'enterprise') url += '?scope=enterprise' // 企业模式但 eid 未知,后端从 DB 取
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const app = getApp()
|
const app = getApp()
|
||||||
const payment = require('../../utils/payment')
|
const payment = require('../../utils/payment')
|
||||||
const { request } = require('../../utils/request')
|
const { request } = require('../../utils/request')
|
||||||
|
const { getEffectiveEnterpriseId } = require('../../utils/enterpriseContext.js')
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
@@ -29,15 +30,31 @@ Page({
|
|||||||
app.globalData.enterpriseIdFromScene = enterpriseId
|
app.globalData.enterpriseIdFromScene = enterpriseId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resolveEnterpriseId = () => {
|
||||||
|
if (enterpriseId > 0) return enterpriseId
|
||||||
|
return getEffectiveEnterpriseId() || 0
|
||||||
|
}
|
||||||
|
|
||||||
this.setData({
|
this.setData({
|
||||||
enterpriseId,
|
enterpriseId: resolveEnterpriseId(),
|
||||||
enterpriseName: (app.globalData.userInfo && app.globalData.userInfo.enterpriseName) || '',
|
enterpriseName: (app.globalData.userInfo && app.globalData.userInfo.enterpriseName) || '',
|
||||||
amountFen,
|
amountFen,
|
||||||
amountYuan
|
amountYuan
|
||||||
})
|
})
|
||||||
|
|
||||||
app.ensureLogin()
|
app.ensureLogin()
|
||||||
|
.then((ok) => {
|
||||||
|
if (!ok) {
|
||||||
|
wx.showToast({ title: '请先登录', icon: 'none' })
|
||||||
|
return Promise.reject(new Error('no login'))
|
||||||
|
}
|
||||||
|
return app.getRuntimeConfig().catch(() => {})
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
const finalEid = resolveEnterpriseId()
|
||||||
|
if (finalEid > 0 && enterpriseId <= 0) {
|
||||||
|
this.setData({ enterpriseId: finalEid })
|
||||||
|
}
|
||||||
if (enterpriseId > 0) {
|
if (enterpriseId > 0) {
|
||||||
request({
|
request({
|
||||||
url: '/api/enterprise/bind',
|
url: '/api/enterprise/bind',
|
||||||
@@ -52,9 +69,7 @@ Page({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {})
|
||||||
wx.showToast({ title: '请先登录', icon: 'none' })
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
submitRecharge() {
|
submitRecharge() {
|
||||||
|
|||||||
@@ -187,11 +187,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.paywall-card { margin-top: 24rpx; border-radius: 24rpx; overflow: hidden; }
|
.paywall-card { margin-top: 24rpx; border-radius: 24rpx; overflow: hidden; }
|
||||||
.paywall-content { position: relative; }
|
.paywall-content { position: relative; min-height: 360rpx; }
|
||||||
.paywall-blur { padding: 32rpx 24rpx 140rpx; border-radius: 24rpx; background: rgba(255,255,255,0.7); backdrop-filter: blur(18rpx); }
|
.paywall-blur { padding: 32rpx 24rpx 200rpx; border-radius: 24rpx; background: rgba(255,255,255,0.97); backdrop-filter: blur(6rpx); }
|
||||||
.paywall-mask { position: absolute; left: 0; top: 0; right: 0; bottom: 0; border-radius: 24rpx; background: linear-gradient(180deg, rgba(255,255,255,0.1), rgba(245,245,245,0.98)); pointer-events: none; }
|
.paywall-mask { position: absolute; left: 0; top: 0; right: 0; bottom: 0; border-radius: 24rpx; z-index: 1; background: linear-gradient(180deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.28) 38%, rgba(255,255,255,0.58) 100%); pointer-events: none; }
|
||||||
.paywall-fake-title { display: block; font-size: 30rpx; font-weight: 600; color: #444; margin-bottom: 16rpx; }
|
.paywall-fake-title { display: block; font-size: 30rpx; font-weight: 600; color: #444; margin-bottom: 16rpx; }
|
||||||
.paywall-fake-line { display: block; font-size: 26rpx; color: #888; line-height: 1.8; }
|
.paywall-fake-line { display: block; font-size: 26rpx; color: #888; line-height: 1.8; }
|
||||||
.paywall-btn { position: absolute; left: 5%; right: 5%; width: 90%; bottom: 56rpx; padding: 20rpx 0; border-radius: 999rpx; background: linear-gradient(135deg, #3B82F6 0%, #60a5fa 100%); box-shadow: 0 8rpx 24rpx rgba(59,130,246,0.35); display: flex; flex-direction: row; align-items: baseline; justify-content: center; gap: 12rpx; }
|
.paywall-btn { position: absolute; left: 5%; right: 5%; width: 90%; bottom: 132rpx; z-index: 3; padding: 20rpx 0; border-radius: 999rpx; background: linear-gradient(135deg, #3B82F6 0%, #60a5fa 100%); box-shadow: 0 8rpx 24rpx rgba(59,130,246,0.35); display: flex; flex-direction: row; align-items: baseline; justify-content: center; gap: 12rpx; }
|
||||||
.paywall-btn-main { font-size: 30rpx; color: #fff; font-weight: 600; }
|
.paywall-btn-main { font-size: 30rpx; color: #fff; font-weight: 600; }
|
||||||
.paywall-btn-price { font-size: 24rpx; color: #ffe5f0; }
|
.paywall-btn-price { font-size: 24rpx; color: #ffe5f0; }
|
||||||
|
|||||||
@@ -205,27 +205,36 @@
|
|||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.paywall-content { position: relative; }
|
.paywall-content { position: relative; min-height: 360rpx; }
|
||||||
.paywall-blur {
|
.paywall-blur {
|
||||||
padding: 32rpx 24rpx 140rpx;
|
padding: 32rpx 24rpx 200rpx;
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
background: rgba(255, 255, 255, 0.7);
|
background: rgba(255, 255, 255, 0.97);
|
||||||
backdrop-filter: blur(18rpx);
|
backdrop-filter: blur(6rpx);
|
||||||
}
|
}
|
||||||
.paywall-mask {
|
.paywall-mask {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0; top: 0; right: 0; bottom: 0;
|
left: 0; top: 0; right: 0; bottom: 0;
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.1), rgba(245,245,245,0.98));
|
z-index: 1;
|
||||||
|
/* 更轻的白纱,底部也保持通透 */
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(255, 255, 255, 0.08) 0%,
|
||||||
|
rgba(255, 255, 255, 0.28) 38%,
|
||||||
|
rgba(255, 255, 255, 0.58) 100%
|
||||||
|
);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.paywall-fake-title { display: block; font-size: 30rpx; font-weight: 600; color: #444; margin-bottom: 16rpx; }
|
.paywall-fake-title { display: block; font-size: 30rpx; font-weight: 600; color: #444; margin-bottom: 16rpx; }
|
||||||
.paywall-fake-line { display: block; font-size: 26rpx; color: #888; line-height: 1.8; }
|
.paywall-fake-line { display: block; font-size: 26rpx; color: #888; line-height: 1.8; }
|
||||||
.paywall-btn {
|
.paywall-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 5%; right: 5%;
|
left: 5%;
|
||||||
|
right: 5%;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
bottom: 56rpx;
|
bottom: 132rpx;
|
||||||
|
z-index: 3;
|
||||||
padding: 20rpx 0;
|
padding: 20rpx 0;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
background: linear-gradient(135deg, #FF6B8A 0%, #ff8fa3 100%);
|
background: linear-gradient(135deg, #FF6B8A 0%, #ff8fa3 100%);
|
||||||
|
|||||||
@@ -201,11 +201,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.paywall-card { margin-top: 24rpx; border-radius: 24rpx; overflow: hidden; }
|
.paywall-card { margin-top: 24rpx; border-radius: 24rpx; overflow: hidden; }
|
||||||
.paywall-content { position: relative; }
|
.paywall-content { position: relative; min-height: 360rpx; }
|
||||||
.paywall-blur { padding: 32rpx 24rpx 140rpx; border-radius: 24rpx; background: rgba(255,255,255,0.7); backdrop-filter: blur(18rpx); }
|
.paywall-blur { padding: 32rpx 24rpx 200rpx; border-radius: 24rpx; background: rgba(255,255,255,0.97); backdrop-filter: blur(6rpx); }
|
||||||
.paywall-mask { position: absolute; left: 0; top: 0; right: 0; bottom: 0; border-radius: 24rpx; background: linear-gradient(180deg, rgba(255,255,255,0.1), rgba(245,245,245,0.98)); pointer-events: none; }
|
.paywall-mask { position: absolute; left: 0; top: 0; right: 0; bottom: 0; border-radius: 24rpx; z-index: 1; background: linear-gradient(180deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.28) 38%, rgba(255,255,255,0.58) 100%); pointer-events: none; }
|
||||||
.paywall-fake-title { display: block; font-size: 30rpx; font-weight: 600; color: #444; margin-bottom: 16rpx; }
|
.paywall-fake-title { display: block; font-size: 30rpx; font-weight: 600; color: #444; margin-bottom: 16rpx; }
|
||||||
.paywall-fake-line { display: block; font-size: 26rpx; color: #888; line-height: 1.8; }
|
.paywall-fake-line { display: block; font-size: 26rpx; color: #888; line-height: 1.8; }
|
||||||
.paywall-btn { position: absolute; left: 5%; right: 5%; width: 90%; bottom: 56rpx; padding: 20rpx 0; border-radius: 999rpx; background: linear-gradient(135deg, #F59E0B 0%, #fbbf24 100%); box-shadow: 0 8rpx 24rpx rgba(245,158,11,0.35); display: flex; flex-direction: row; align-items: baseline; justify-content: center; gap: 12rpx; }
|
.paywall-btn { position: absolute; left: 5%; right: 5%; width: 90%; bottom: 132rpx; z-index: 3; padding: 20rpx 0; border-radius: 999rpx; background: linear-gradient(135deg, #F59E0B 0%, #fbbf24 100%); box-shadow: 0 8rpx 24rpx rgba(245,158,11,0.35); display: flex; flex-direction: row; align-items: baseline; justify-content: center; gap: 12rpx; }
|
||||||
.paywall-btn-main { font-size: 30rpx; color: #fff; font-weight: 600; }
|
.paywall-btn-main { font-size: 30rpx; color: #fff; font-weight: 600; }
|
||||||
.paywall-btn-price { font-size: 24rpx; color: #ffe5f0; }
|
.paywall-btn-price { font-size: 24rpx; color: #ffe5f0; }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// pages/result/resume.js - 简历综合分析结果页
|
// pages/result/resume.js - 简历综合分析结果页
|
||||||
const app = getApp()
|
const app = getApp()
|
||||||
const payment = require('../../utils/payment')
|
const payment = require('../../utils/payment')
|
||||||
|
const { getEnterpriseIdForApiPayload } = require('../../utils/enterpriseContext.js')
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
@@ -111,13 +112,7 @@ Page({
|
|||||||
const apiBase = (app.globalData && app.globalData.apiBase) || wx.getStorageSync('apiBase') || ''
|
const apiBase = (app.globalData && app.globalData.apiBase) || wx.getStorageSync('apiBase') || ''
|
||||||
const token = (app.globalData && app.globalData.token) || wx.getStorageSync('token') || ''
|
const token = (app.globalData && app.globalData.token) || wx.getStorageSync('token') || ''
|
||||||
|
|
||||||
// 获取 enterpriseId
|
const enterpriseId = getEnterpriseIdForApiPayload()
|
||||||
const gd = app.globalData || {}
|
|
||||||
const storedUser = wx.getStorageSync('userInfo') || null
|
|
||||||
const enterpriseId = gd.enterpriseIdFromScene
|
|
||||||
|| (gd.userInfo && gd.userInfo.enterpriseId)
|
|
||||||
|| (storedUser && storedUser.enterpriseId)
|
|
||||||
|| null
|
|
||||||
|
|
||||||
const postData = {}
|
const postData = {}
|
||||||
if (this.data.fileUrl) postData.fileUrl = this.data.fileUrl
|
if (this.data.fileUrl) postData.fileUrl = this.data.fileUrl
|
||||||
|
|||||||
52
miniprogram/utils/enterpriseContext.js
Normal file
52
miniprogram/utils/enterpriseContext.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* 小程序企业上下文:显式入口参数 > 用户绑定企业 > 超管配置的默认企业
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业版落地页、分享带 eid、充值等:完整回落链
|
||||||
|
* @returns {number|null}
|
||||||
|
*/
|
||||||
|
function getEffectiveEnterpriseId() {
|
||||||
|
const app = getApp()
|
||||||
|
const gd = app.globalData || {}
|
||||||
|
const fromScene = gd.enterpriseIdFromScene
|
||||||
|
if (fromScene != null && Number(fromScene) > 0) {
|
||||||
|
return Number(fromScene)
|
||||||
|
}
|
||||||
|
const u = gd.userInfo || wx.getStorageSync('userInfo') || {}
|
||||||
|
const bound = u.enterpriseId
|
||||||
|
if (bound != null && Number(bound) > 0) {
|
||||||
|
return Number(bound)
|
||||||
|
}
|
||||||
|
const def = gd.defaultEnterpriseId
|
||||||
|
if (def != null && Number(def) > 0) {
|
||||||
|
return Number(def)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交给后端的 enterpriseId(analyze、test/submit、支付创建订单、简历分析等)
|
||||||
|
* - 个人版 Tab(appScope=personal):仅传递「本次入口携带的 eid」(enterpriseIdFromScene),
|
||||||
|
* 不因「已绑定企业」或「超管默认企业」带参,避免个人入口却走企业定价/落库企业字段。
|
||||||
|
* - 企业版(appScope=enterprise):与 getEffectiveEnterpriseId 一致。
|
||||||
|
* @returns {number|null}
|
||||||
|
*/
|
||||||
|
function getEnterpriseIdForApiPayload() {
|
||||||
|
const app = getApp()
|
||||||
|
const gd = app.globalData || {}
|
||||||
|
const scope = gd.appScope || 'personal'
|
||||||
|
if (scope === 'personal') {
|
||||||
|
const fromScene = gd.enterpriseIdFromScene
|
||||||
|
if (fromScene != null && Number(fromScene) > 0) {
|
||||||
|
return Number(fromScene)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return getEffectiveEnterpriseId()
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getEffectiveEnterpriseId,
|
||||||
|
getEnterpriseIdForApiPayload
|
||||||
|
}
|
||||||
@@ -2,6 +2,13 @@
|
|||||||
// 微信支付工具类 - 复刻自Soul项目
|
// 微信支付工具类 - 复刻自Soul项目
|
||||||
|
|
||||||
const app = getApp()
|
const app = getApp()
|
||||||
|
const { getEnterpriseIdForApiPayload } = require('./enterpriseContext.js')
|
||||||
|
|
||||||
|
/** 创建订单时传给后端的 enterpriseId(0 表示无企业上下文);与个人/企业 Tab 一致 */
|
||||||
|
function enterpriseIdForOrder() {
|
||||||
|
const eid = getEnterpriseIdForApiPayload()
|
||||||
|
return eid != null && Number(eid) > 0 ? Number(eid) : 0
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成符合微信规则的订单号
|
* 生成符合微信规则的订单号
|
||||||
@@ -364,6 +371,7 @@ function purchaseByPricing(productType, description, extra, maybeFail) {
|
|||||||
description,
|
description,
|
||||||
productType,
|
productType,
|
||||||
testResultId,
|
testResultId,
|
||||||
|
enterpriseId: enterpriseIdForOrder(),
|
||||||
success,
|
success,
|
||||||
fail
|
fail
|
||||||
})
|
})
|
||||||
@@ -486,6 +494,7 @@ function purchasePersonalDeepService(arg1, arg2, arg3) {
|
|||||||
description: desc,
|
description: desc,
|
||||||
productType: 'deep_personal',
|
productType: 'deep_personal',
|
||||||
deepProductId,
|
deepProductId,
|
||||||
|
enterpriseId: enterpriseIdForOrder(),
|
||||||
success,
|
success,
|
||||||
fail
|
fail
|
||||||
})
|
})
|
||||||
@@ -502,6 +511,7 @@ function purchaseTeamDeepService(success, fail) {
|
|||||||
amount: 0,
|
amount: 0,
|
||||||
description: '团队深度服务(团队画像+策略)',
|
description: '团队深度服务(团队画像+策略)',
|
||||||
productType: 'deep_team',
|
productType: 'deep_team',
|
||||||
|
enterpriseId: enterpriseIdForOrder(),
|
||||||
success,
|
success,
|
||||||
fail
|
fail
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
* 接收方(落地页 onLoad options)直接读 options.uid / options.eid
|
* 接收方(落地页 onLoad options)直接读 options.uid / options.eid
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const { getEffectiveEnterpriseId } = require('./enterpriseContext.js')
|
||||||
|
|
||||||
function getApp_() {
|
function getApp_() {
|
||||||
try { return getApp() } catch (e) { return null }
|
try { return getApp() } catch (e) { return null }
|
||||||
}
|
}
|
||||||
@@ -24,9 +26,7 @@ function buildShareQuery() {
|
|||||||
const parts = []
|
const parts = []
|
||||||
if (uid) parts.push('uid=' + uid)
|
if (uid) parts.push('uid=' + uid)
|
||||||
if (scope === 'enterprise') {
|
if (scope === 'enterprise') {
|
||||||
const eid = (app && app.globalData && app.globalData.enterpriseIdFromScene)
|
const eid = getEffectiveEnterpriseId() || ''
|
||||||
|| userInfo.enterpriseId
|
|
||||||
|| ''
|
|
||||||
if (eid) parts.push('eid=' + eid)
|
if (eid) parts.push('eid=' + eid)
|
||||||
}
|
}
|
||||||
return parts.join('&')
|
return parts.join('&')
|
||||||
|
|||||||
Reference in New Issue
Block a user