6 Commits

Author SHA1 Message Date
d0369bab36 feat: ui 2025-08-28 10:37:40 +08:00
898c6ab6ca Merge branch 'trunk' into feat/share-coupon 2025-08-28 08:56:37 +08:00
763a6245d2 feat: update 2025-08-28 08:56:26 +08:00
670a389f12 feat: share 2025-08-26 22:55:19 +08:00
2cb532c3d7 feat: 2025-08-24 17:35:13 +08:00
6a2c94c7cf feat: build 2025-08-17 13:44:41 +08:00
28 changed files with 6479 additions and 12958 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
dist/ dist/
dist-dev/
deploy_versions/ deploy_versions/
.temp/ .temp/
.rn_temp/ .rn_temp/

View File

@ -12,6 +12,20 @@ const MockPlugin: PluginItem = [
} }
]; ];
const CIPluginOpt = () => {
const brand = process.env.BRAND as 'prod' | 'dev'; // 取环境变量
const map = {
prod: { appid: 'wxf0724a83f8e377d2', privateKeyPath: 'keys/private.wxf0724a83f8e377d2.key' },
dev: { appid: 'wx2d56597fd541f1a6', privateKeyPath: 'keys/private.wx2d56597fd541f1a6.key' },
};
return {
weapp: map[brand] || map.prod,
version: process.env.VERSION || '1.0.0',
desc: `build for ${brand}`,
};
};
// https://taro-docs.jd.com/docs/next/config#defineconfig-辅助函数 // https://taro-docs.jd.com/docs/next/config#defineconfig-辅助函数
export default defineConfig(async (merge, _env: ConfigEnv) => { export default defineConfig(async (merge, _env: ConfigEnv) => {
const baseConfig: UserConfigExport = { const baseConfig: UserConfigExport = {
@ -25,13 +39,15 @@ export default defineConfig(async (merge, _env: ConfigEnv) => {
828: 1.81 / 2 828: 1.81 / 2
}, },
sourceRoot: 'src', sourceRoot: 'src',
outputRoot: 'dist', outputRoot: process.env.OUTPUT_ROOT || 'dist',
plugins: ['@tarojs/plugin-html'], plugins: [['@tarojs/plugin-mini-ci', CIPluginOpt()], '@tarojs/plugin-html'],
// plugins: ['@tarojs/plugin-html', MockPlugin], // plugins: ['@tarojs/plugin-html', MockPlugin],
defineConstants: { defineConstants: {
'process.env.BRAND': JSON.stringify(process.env.BRAND),
}, },
copy: { copy: {
patterns: [ patterns: [
{from: 'project.config.dev.json',to: 'dist-dev/project.config.json'},
], ],
options: { options: {
} }

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEArjidDs/HGidBTzyOssyhX/Yvlr+BZxO3Qqe1iFBIJYWVXwiJ
KFVZw14rPKnh6ORB9qpMq3+fYJ7VsodmobnVlTaFXxJ8yi+tVZSZyZPtHabu2JVO
qu7LX709p5NTFcrmOY6+NJA827+hg6V0Nl3b4CWLsouPHgiIxpqnLeaOka3lbPMq
vQuDeMCbQNFe5Jz7C0gc6dXwEpDExNX4WiVfi4UP5bcYiUKlbdben5i6qbFrZ4QK
woYoAIhr60jQGfB6Jg7YkbbAyh42XR3BMkf2TPQqieZM1/IKNuw2evtA2BqLJuiz
cQ1qNBBXczbJv9KjBVAzAJgT4InUyJF+QfFJ6wIDAQABAoIBAQCf2kohIPvqP0Jp
VYMJA0C+L8CSbLxqu2hWvFKP9Dl+VAct30MZwtZNr8W0L5uceHMdxDv8z2iI2rPw
ztOYaE5UTmYpSWk+imhcMbC5iAT0RAq6pqQ7qkboXVaIv2BoinabMSHMUNvGNRoZ
FGKAz7XDADAhbnOudt4ofBYQw47kkko8vaDZBJS6UGN+QVJpyBtJKohaXKC6HRva
2c8zDwVZlKMrPl4WB4cg0+WPv6vUZymv8U7flwY0xJBBWwZUxqbmjqbTg8BGb5Mu
tpIZRvTGNxbDu9Ms7mdYdGGe/PFmqgj1hOomeXvBlnYz+fmWHu5ElyPGBHD92N7x
Hdcopp4BAoGBANqQUfxzjGcBvSSSowehSvgVCnUFsTxSE8c9HQRX4LtMnLCo6c6m
Hxf+l67FyY5704EW29PLu5ETdLBm6pCaIk8aJo467l8M9BOHmE/CwNciloHxXa4h
/gUKex6EsFJoT+1gaCaDJeu0gDJl49QnpYOrma2CZ8vyG3+NCotuYturAoGBAMwP
8G2ObLZUFPZAfhGZrobUom2dCtJXenYupxSvJ/rNd7zY+F3pcyi461eMIkKFaxQX
bRyDi/LRCQRKrSDuw3Dt4Ne9gkpdlI/LUDTUUbWdDuCXxfsXSRAYHC1ae0rsiGQv
PaTotkDSjdAIKdgd0bmeufFZ2Ozmid2lHzSZfwrBAoGAQXSVSSClvLeVmJ1du8w/
MnrCrfctdB40lCemSAW1ZQJ1rqZ3lw7DIyF49buAOG63EeLxpMVQAAuul6HKv9GZ
Us1HHLNjbg3oDu093S07KXLPVk0dvCer9oCEDMi6MYPR5ApKRrZiJevhtLY0+/V/
qSY8GO2D/l0chR+NN+KwMo8CgYB4Y07s04G/b4uOXC4EJC6azQems2eXAJT29D8O
LOfhRybE+xxMC1YtSCtP0xTDOgMaL1fn4pPGBRzUs1nAfBxBm5VyshMT3HGxA7ml
8TzjcG0+g0wB/pLUM+UrvJ3QbgtpT5WGnOQpCg8wFCDbp3v7jnEUunUIDlp3sNrg
JU6WAQKBgDjcfRDtnmSxSiejsZaZM7gCAYlZq6WBuvQ6WF+nD9mzEgzkw3F+1cHC
Y905VPGb/vCPAV+JdN7LxnMn2G3JoWPqrhOIT6KgPgAYbVAq1hmLqXMjGi53n9uY
39GL4UgJkywIdEkla/8zNFNKZgQulWPDJqb/MFcVo3/VegEfwdbk
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA1Tl6FYIIWB8b+OjYY9s6cOJf71Vn0J/u/kdq5CH/LMOdNrUh
fq3shAwdDkXmuRIpHU7Noxisu71tB2EumigIwBDRVyrdwPu/p6QWyaMgrh0bdtaC
LKW/j2teNU1MCSWyCDyEeZ9PJteK5+ieX+ZPDg17HLV2dISpB71AGyM461DIHCAV
uaanUJ4MYCtp9t7OFgrD4dNzDMH0lBJBczRQAmnit0GpJD/y2rfgtL+HaKpDN8rc
w80+3HVfhKq3niy/vBbI6alqFb1Mh9O5q6/c1tEWQKPn3TzneGIDhMupGzHEzrVR
j87+1cyYi8PtBdNMPls+zPn7MoajjrASFyo1hQIDAQABAoIBABHu652zehAvTaL5
snlzjs6/u2HdxQV+7hLk3tChK10QdsCLK24EIshYXHk+19Do/hxA7HqzMJP5spnU
Sp8cjt/YikLSkCQTCGOJIYGD/tOmDxFHqVsn9ZySYzIIdkSurvKSZHH2PCoAJuaq
Yeee7zc3WwtnF7dlEPJdsG6X38mqslzaLOuiftkHJ8hQ+1rWM9FFEp/S3pLfLB+7
jEQhuVk0WjLTqmWmKvi0Nz5tUibBpF1OHtCfIhPjb1N8k/bcv1jumETx+2PDxA62
zpPNGespBaET+jeEqNCqLO7Zq8+iUO8d4XpZsFCR2cyE6zzXK2mhQ+2pW2BRU/DI
w/ZylmECgYEA6uPRJ4uk+NavoJlQCv7R9B8CGbwzbRaG8sg/NuwvTOO6D4FGUdcu
f8qA2kCd8bSCuWrS1mVgPpvzwHt5Bh3k7FC/0SfW5ZDC5Lp1IssI0jeka39vfPOD
ZdcvgJ3dUnHUrvb4L4PclgCa3KPXLTVDnK+4ExvaYOxNAaG6wROCGBsCgYEA6GMy
nCsPr21kKmhybCrhcTYoENb45hz6CCnXr4MGnYzF9c2ss2KXjR/boCdhF+3wxmmm
F4TKgcicOUfOJIXSIHBD9nphLa5CfrksLxfX0iIyNCG74aXIWl6M6QgQZdWqV4qC
xYTtFYACELIb8qK/mraMP28c9BzDpwd909ZlAt8CgYEAmpXCIa+CrA3GWgBsMEBR
9sKthDha8/E+cOuexsubuZOp8OhYWiYuwQWJ1ZlvGRJ+cf6+sUDYnXvPaJ8aIA9u
iKQACWuZv02NJjEcRACxVoAuIl0lB2vPzydWaOP8M3UczuVUoxi6BLJzOMBPLb5/
N9BhaZoMF3uMloVUvhrTpH8CgYA9sQfgeXYChjHPKEcn/AI5Qb1FKyyMOikOPb1q
dIgvDw4GgQFV5diBuHFfhNS7u4jtw2I6YCA6b/05H5zUCUqNHgCM0FQ4AkjYx2O5
ZMUAnd9iA4qTDqWvh+Y0ftWLkztTXgv1T6J40LC7qezNbvMaqVd2B5NSIsi18MEw
mXvbVQKBgQC0Rh5TJEfeBWRoIixwFuDUgHYRsdk3SV1hymYO3aKBr0uD8Arv4v1M
XO6DchFjcpKuwScjXX5yEot5PJOUTPG2T2uBPnJggtNig2dnRzQDLM+bK0vVecoz
QL9YMOYv6DNH6Z2yEfMZHZLto9Oaqm9J62hZahZ2GukFLOMBGZAVhA==
-----END RSA PRIVATE KEY-----

View File

@ -10,29 +10,10 @@
"framework": "React" "framework": "React"
}, },
"scripts": { "scripts": {
"build:weapp": "taro build --type weapp", "build:weapp": "BRAND=prod taro build --type weapp",
"build:swan": "taro build --type swan", "build:dev:weapp": "BRAND=dev OUTPUT_ROOT=dist-dev taro build --type weapp --upload",
"build:alipay": "taro build --type alipay", "dev:weapp": "BRAND=prod npm run build:weapp -- --watch",
"build:tt": "taro build --type tt", "dev:dev:weapp": "BRAND=dev OUTPUT_ROOT=dist-dev taro build --type weapp --watch"
"build:h5": "taro build --type h5",
"build:rn": "taro build --type rn",
"build:qq": "taro build --type qq",
"build:jd": "taro build --type jd",
"build:quickapp": "taro build --type quickapp",
"build:harmony-hybrid": "taro build --type harmony-hybrid",
"dev:weapp": "npm run build:weapp -- --watch",
"dev:swan": "npm run build:swan -- --watch",
"dev:alipay": "npm run build:alipay -- --watch",
"dev:tt": "npm run build:tt -- --watch",
"dev:h5": "npm run build:h5 -- --watch",
"dev:rn": "npm run build:rn -- --watch",
"dev:qq": "npm run build:qq -- --watch",
"dev:jd": "npm run build:jd -- --watch",
"dev:quickapp": "npm run build:quickapp -- --watch",
"dev:harmony-hybrid": "npm run build:harmony-hybrid -- --watch",
"test": "jest",
"lint:format": "npx prettier --write",
"lint:format-all": "npx prettier --write 'src/**/*.{ts,js,css,jsx,html,vue,tsx}'"
}, },
"browserslist": [ "browserslist": [
"last 3 versions", "last 3 versions",
@ -76,6 +57,7 @@
"@babel/core": "^7.8.0", "@babel/core": "^7.8.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
"@tarojs/cli": "4.0.9", "@tarojs/cli": "4.0.9",
"@tarojs/plugin-mini-ci": "^4.1.5",
"@tarojs/plugin-mock": "^0.0.9", "@tarojs/plugin-mock": "^0.0.9",
"@tarojs/taro-loader": "4.0.9", "@tarojs/taro-loader": "4.0.9",
"@tarojs/test-utils-react": "^0.1.1", "@tarojs/test-utils-react": "^0.1.1",
@ -95,6 +77,7 @@
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-hooks": "^4.2.0",
"jest": "^29.3.1", "jest": "^29.3.1",
"jest-environment-jsdom": "^29.5.0", "jest-environment-jsdom": "^29.5.0",
"miniprogram-ci": "^2.1.14",
"postcss": "^8.4.18", "postcss": "^8.4.18",
"prettier": "^3.3.1", "prettier": "^3.3.1",
"react-refresh": "^0.11.0", "react-refresh": "^0.11.0",
@ -110,5 +93,5 @@
"@tarojs/binding" "@tarojs/binding"
] ]
}, },
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" "packageManager": "pnpm@10.12.4+sha512.5ea8b0deed94ed68691c9bad4c955492705c5eeb8a87ef86bc62c74a26b037b08ff9570f108b2e4dbd1dd1a9186fea925e527f141c648e85af45631074680184"
} }

5985
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

47
project.config.dev.json Normal file
View File

@ -0,0 +1,47 @@
{
"miniprogramRoot": "./",
"description": "boluo app",
"setting": {
"urlCheck": true,
"es6": false,
"enhance": false,
"compileHotReLoad": false,
"postcss": false,
"minified": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"coverView": false,
"showShadowRootInWxmlPanel": false,
"packNpmRelationList": [],
"ignoreUploadUnusedFiles": true,
"compileWorklet": false,
"uglifyFileName": false,
"uploadWithSourceMap": true,
"packNpmManually": false,
"minifyWXSS": true,
"minifyWXML": true,
"localPlugins": false,
"disableUseStrict": false,
"useCompilerPlugins": false,
"condition": false,
"swc": false,
"disableSWC": true
},
"compileType": "miniprogram",
"srcMiniprogramRoot": "dist/",
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
},
"libVersion": "3.4.6",
"packOptions": {
"ignore": [],
"include": []
},
"appid": "wx2d56597fd541f1a6",
"simulatorPluginLibVersion": {}
}

View File

@ -11,6 +11,16 @@
border-radius: 16px; border-radius: 16px;
background: #FFFFFF; background: #FFFFFF;
margin-bottom: 24px; margin-bottom: 24px;
position: relative;
}
&__mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.4);
} }
&__header { &__header {

View File

@ -5,13 +5,13 @@ import React, { useCallback } from 'react';
import { CertificationStatusIcon } from '@/components/certification-status'; import { CertificationStatusIcon } from '@/components/certification-status';
import { PageUrl } from '@/constants/app'; import { PageUrl } from '@/constants/app';
import { CITY_CODE_TO_NAME_MAP, COUNTY_CODE_TO_NAME_MAP } from '@/constants/city'; // import { CITY_CODE_TO_NAME_MAP, COUNTY_CODE_TO_NAME_MAP } from '@/constants/city';
import { CertificationStatusType } from '@/constants/company'; import { CertificationStatusType } from '@/constants/company';
import { EMPLOY_TYPE_TITLE_MAP, EmployType } from '@/constants/job'; import { EMPLOY_TYPE_TITLE_MAP, EmployType } from '@/constants/job';
import { JobInfo } from '@/types/job'; import { JobInfo } from '@/types/job';
import { LocationInfo } from '@/types/location'; // import { LocationInfo } from '@/types/location';
import { getJobSalary, getJobTitle } from '@/utils/job'; import { getJobSalary, getJobTitle } from '@/utils/job';
import { calcDistance } from '@/utils/location'; // import { calcDistance } from '@/utils/location';
import { navigateTo, redirectTo } from '@/utils/route'; import { navigateTo, redirectTo } from '@/utils/route';
import './index.less'; import './index.less';
@ -23,16 +23,16 @@ interface IProps {
} }
const PREFIX = 'job-card'; const PREFIX = 'job-card';
const getCityDes = (location: LocationInfo) => { // const getCityDes = (location: LocationInfo) => {
if (!location) { // if (!location) {
return ''; // return '';
} // }
let des = CITY_CODE_TO_NAME_MAP.get(location.cityCode); // let des = CITY_CODE_TO_NAME_MAP.get(location.cityCode);
if (location.countyCode) { // if (location.countyCode) {
des += `-${COUNTY_CODE_TO_NAME_MAP.get(location.countyCode)}`; // des += `-${COUNTY_CODE_TO_NAME_MAP.get(location.countyCode)}`;
} // }
return des; // return des;
}; // };
function JobCard(props: IProps) { function JobCard(props: IProps) {
const { className, data, redirectOpen } = props; const { className, data, redirectOpen } = props;
@ -45,7 +45,7 @@ function JobCard(props: IProps) {
publisher, publisher,
publisherAvatar, publisherAvatar,
jobLocation, jobLocation,
distance, // distance,
isAuthed = false, isAuthed = false,
} = data; } = data;
@ -104,6 +104,7 @@ function JobCard(props: IProps) {
</div> </div>
{/*<div className={`${PREFIX}__city`}>{getCityDes(jobLocation)}</div>*/} {/*<div className={`${PREFIX}__city`}>{getCityDes(jobLocation)}</div>*/}
</div> </div>
{data.isRead && <div className={`${PREFIX}__mask`} />}
</div> </div>
); );
} }

View File

@ -1,3 +1,5 @@
import Taro from '@tarojs/taro';
import { List, PullRefresh } from '@taroify/core'; import { List, PullRefresh } from '@taroify/core';
import classNames from 'classnames'; import classNames from 'classnames';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
@ -5,6 +7,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
import JobCard from '@/components/job-card'; import JobCard from '@/components/job-card';
import ListPlaceholder from '@/components/list-placeholder'; import ListPlaceholder from '@/components/list-placeholder';
import { EventName } from '@/constants/app';
import { JobType, EmployType, SortType } from '@/constants/job'; import { JobType, EmployType, SortType } from '@/constants/job';
import { JobInfo, GetJobsRequest } from '@/types/job'; import { JobInfo, GetJobsRequest } from '@/types/job';
import { logWithPrefix } from '@/utils/common'; import { logWithPrefix } from '@/utils/common';
@ -58,6 +61,23 @@ function JobList(props: IJobListProps) {
const prevRequestProps = useRef<IRequestProps>({}); const prevRequestProps = useRef<IRequestProps>({});
const onListEmptyRef = useRef(onListEmpty); const onListEmptyRef = useRef(onListEmpty);
const handleReadJob = useCallback(
(jobId: string) => {
const index = dataList.findIndex(d => String(d.id) === jobId);
if (index < 0) {
return;
}
const job = dataList[index];
if (!job || job.isRead) {
return;
}
log('auto mark read', jobId);
dataList.splice(index, 1, { ...job, isRead: true });
setDataList([...dataList]);
},
[dataList]
);
const handleRefresh = useCallback(async () => { const handleRefresh = useCallback(async () => {
log('start pull refresh'); log('start pull refresh');
try { try {
@ -109,6 +129,13 @@ function JobList(props: IJobListProps) {
onListEmptyRef.current = onListEmpty; onListEmptyRef.current = onListEmpty;
}, [onListEmpty]); }, [onListEmpty]);
useEffect(() => {
Taro.eventCenter.on(EventName.VIEW_JOB_SUCCESS, handleReadJob);
return () => {
Taro.eventCenter.off(EventName.VIEW_JOB_SUCCESS, handleReadJob);
};
}, [handleReadJob]);
useEffect(() => { useEffect(() => {
log('request params changed'); log('request params changed');
requestProps.current = { requestProps.current = {

View File

@ -39,9 +39,7 @@ function JoinEntry({ onBindSuccess }: JoinEntryProps) {
</Button> </Button>
)} )}
</div> </div>
{visible && ( {visible && <LoginDialog onCancel={() => setVisible(false)} onSuccess={onBindSuccess} needPhone={needPhone} />}
<LoginDialog disableCheck onCancel={() => setVisible(false)} onSuccess={onBindSuccess} needPhone={needPhone} />
)}
</> </>
); );
} }

View File

@ -57,21 +57,21 @@ export default function PartnerIntro() {
const canvas = res[0].node; const canvas = res[0].node;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
canvas.width = 1500; canvas.width = 550*2;
canvas.height = 2668; canvas.height = 918*2;
ctx.scale(2, 2); ctx.scale(2, 2);
// 绘制背景图片 // 绘制背景图片
const bgImage = canvas.createImage(); const bgImage = canvas.createImage();
const poster = 'https://publiccdn.neighbourhood.com.cn/img/poster.png' const poster = 'https://publiccdn.neighbourhood.com.cn/img/share-coupon-poster.png';
bgImage.src = poster; bgImage.src = poster;
bgImage.onload = () => { bgImage.onload = () => {
ctx.drawImage(bgImage, 0, 0, 750, 1334); ctx.drawImage(bgImage, 0, 0, 550, 918);
const qrCodeImage = canvas.createImage(); const qrCodeImage = canvas.createImage();
qrCodeImage.src = qrCode; // 假设 getQrcode() 返回的是二维码图片的路径 qrCodeImage.src = qrCode; // 假设 getQrcode() 返回的是二维码图片的路径
qrCodeImage.onload = () => { qrCodeImage.onload = () => {
ctx.drawImage(qrCodeImage, 235, 894, 280, 280); // 绘制二维码,位置和大小 ctx.drawImage(qrCodeImage, 196, 600, 160, 160); // 绘制二维码,位置和大小
saveCanvasToTempFile().then(tempPath => { saveCanvasToTempFile().then(tempPath => {
resolve(tempPath); resolve(tempPath);
}); });
@ -163,10 +163,10 @@ export default function PartnerIntro() {
<div className={`${PREFIX}__footer`}> <div className={`${PREFIX}__footer`}>
<Button className={`${PREFIX}__download-button`} onClick={savePoster}> <Button className={`${PREFIX}__download-button`} onClick={savePoster}>
</Button> </Button>
<Button className={`${PREFIX}__share-button`} openType="share"> <Button className={`${PREFIX}__share-button`} openType="share">
</Button> </Button>
</div> </div>
</div> </div>

View File

@ -8,7 +8,51 @@
background: #6d3df5; background: #6d3df5;
color: #fff; color: #fff;
&__simple { &-simple {
padding: 39px 35px;
height: 120px;
box-sizing: border-box;
&__bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
border-radius: 16px;
height: 100%;
}
&__content {
.flex-row();
line-height: 42px;
position: relative;
z-index: 1;
}
&__title {
font-size: 26px;
color: #FFFFFF;
}
&__money {
font-weight: 800;
margin-left: 12px;
font-size: 44px;
}
&__button {
position: absolute;
z-index: 2;
top: 44px;
right: 24px;
font-size: 28px;
line-height: 32px;
&-image {
width: 24px;
height: 24px;
display: inline-block;
margin-left: 8px;
}
}
} }
&__bg { &__bg {
@ -28,20 +72,7 @@
z-index: 1; z-index: 1;
} }
&__button {
position: absolute;
z-index: 2;
top: 44px;
right: 56px;
font-size: 24px;
line-height: 24px;
&-image {
width: 20px;
height: 20px;
display: inline-block;
margin-left: 4px;
}
}
&__title { &__title {
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -144,24 +144,37 @@ export default function PartnerKanban({ simple }: PartnerKanbanProps) {
useEffect(() => { useEffect(() => {
getProfitStats(); getProfitStats();
}, []); }, []);
if (simple) {
return (
<div className={`${PREFIX} ${PREFIX}-simple`}>
<Image
className={`${PREFIX}-simple__bg`}
src="https://publiccdn.neighbourhood.com.cn/img/partner_bg.png"
mode="aspectFill"
/>
<div className={`${PREFIX}-simple__content`}>
<div className={`${PREFIX}-simple__title`}>()</div>
<div className={`${PREFIX}-simple__money`}>{formatMoney(total)}</div>
</div>
<div className={`${PREFIX}-simple__button`} onClick={handleNavigate}>
<Image
className={`${PREFIX}-simple__button-image`}
mode="aspectFit"
src={require('@/statics/svg/caret-right.svg')}
/>
</div>
</div>
);
}
return ( return (
<div className={`${PREFIX} ${simple ? `${PREFIX}__simple` : ''}`}> <div className={PREFIX}>
<Image <Image
className={`${PREFIX}__bg`} className={`${PREFIX}__bg`}
src="https://publiccdn.neighbourhood.com.cn/img/partner_bg.png" src="https://publiccdn.neighbourhood.com.cn/img/partner_bg.png"
mode="aspectFill" mode="aspectFill"
/> />
<div className={`${PREFIX}__content`}> <div className={`${PREFIX}__content`}>
{simple && (
<div className={`${PREFIX}__button`} onClick={handleNavigate}>
<Image
className={`${PREFIX}__button-image`}
mode="aspectFit"
src={require('@/statics/svg/caret-right.svg')}
/>
</div>
)}
<div className={`${PREFIX}__total`}> <div className={`${PREFIX}__total`}>
<div className={`${PREFIX}__title`}></div> <div className={`${PREFIX}__title`}></div>
<div className={`${PREFIX}__money`}>{formatMoney(total)}</div> <div className={`${PREFIX}__money`}>{formatMoney(total)}</div>
@ -183,25 +196,21 @@ export default function PartnerKanban({ simple }: PartnerKanbanProps) {
<div className={`${PREFIX}__money`}>{formatMoney(stats.availableProfit)}</div> <div className={`${PREFIX}__money`}>{formatMoney(stats.availableProfit)}</div>
</div> </div>
</div> </div>
{!simple && ( <div className={`${PREFIX}__buttons`}>
<div className={`${PREFIX}__buttons`}> <Button className={`${PREFIX}__withdraw`} onClick={handleViewWithdraw}>
<Button className={`${PREFIX}__withdraw`} onClick={handleViewWithdraw}>
</Button>
</Button> <Button className={`${PREFIX}__record`} onClick={handleNavigateRecord}>
<Button className={`${PREFIX}__record`} onClick={handleNavigateRecord}>
</Button>
</Button> </div>
</div>
)}
</div> </div>
{!simple && <TipDialog open={tipOpen} onClose={handleTipClose} />} <TipDialog open={tipOpen} onClose={handleTipClose} />
{!simple && ( <WithdrawDialog
<WithdrawDialog count={Math.min(Number(formatMoney(stats.availableBalance)), 200)}
count={Math.min(Number(formatMoney(stats.availableBalance)), 200)} open={withdrawOpen}
open={withdrawOpen} onClose={handleWithdrawClose}
onClose={handleWithdrawClose} />
/>
)}
</div> </div>
); );
} }

View File

@ -226,6 +226,20 @@
margin-top: 32px; margin-top: 32px;
} }
&__hint {
font-size: 24px;
line-height: 40px;
text-align: center;
color: @blColorG1;
margin-top: 24px;
.highlight {
color: @blHighlightColor;
display: inline;
}
}
} }
// ============================================= 群 ================================================= // // ============================================= 群 ================================================= //

View File

@ -152,6 +152,9 @@ export default function JobBuy(props: IProps) {
); );
})} })}
</div> </div>
<div className={`${PREFIX}__job-buy__hint`}>
<div className="highlight">24</div>
</div>
<Button className={`${PREFIX}__job-buy__button`} onClick={handleBuy}> <Button className={`${PREFIX}__job-buy__button`} onClick={handleBuy}>
{`支付 ${selectItem.amt}`} {`支付 ${selectItem.amt}`}
</Button> </Button>

View File

@ -24,6 +24,7 @@ export enum EventName {
SELECT_MY_PUBLISH_JOB = 'select_my_publish_job', SELECT_MY_PUBLISH_JOB = 'select_my_publish_job',
EXIT_CHAT_PAGE = 'exit_chat_page', EXIT_CHAT_PAGE = 'exit_chat_page',
VIEW_MATERIAL_SUCCESS = 'view_material_success', VIEW_MATERIAL_SUCCESS = 'view_material_success',
VIEW_JOB_SUCCESS = 'view_job_success',
} }
export enum OpenSource { export enum OpenSource {
@ -75,6 +76,7 @@ export enum PageUrl {
Partner = 'pages/partner/index', Partner = 'pages/partner/index',
WithdrawRecord = 'pages/withdraw-record/index', WithdrawRecord = 'pages/withdraw-record/index',
GroupDelegatePublish = 'pages/group-delegate-publish/index', GroupDelegatePublish = 'pages/group-delegate-publish/index',
GiveVip = 'pages/give-vip/index',
} }
export enum PluginUrl { export enum PluginUrl {

View File

@ -18,7 +18,8 @@ import {
ALL_SORT_TYPES, ALL_SORT_TYPES,
EMPLOY_TYPE_TITLE_MAP, EMPLOY_TYPE_TITLE_MAP,
EmployType, EmployType,
JOB_TABS, JobSourceType, JOB_TABS,
JobSourceType,
JobType, JobType,
SORT_TYPE_TITLE_MAP, SORT_TYPE_TITLE_MAP,
SortType, SortType,
@ -143,12 +144,7 @@ function JobFragment(props: IProps) {
return ( return (
<div className={`${PREFIX}__container`}> <div className={`${PREFIX}__container`}>
<div className={`${PREFIX}__top-search-bar`}> <div className={`${PREFIX}__top-search-bar`}>
<SearchInput <SearchInput disabled className={`${PREFIX}__search`} placeholder="试试 女装" onClick={handleClickSearch} />
disabled
className={`${PREFIX}__search`}
placeholder="试试 女装"
onClick={handleClickSearch}
/>
<div className={classNames(`${PREFIX}__employType-select`)} onClick={handleClickEmployTypeSelect}> <div className={classNames(`${PREFIX}__employType-select`)} onClick={handleClickEmployTypeSelect}>
<div className="title"> <div className="title">
{employType && employType !== EmployType.All ? EMPLOY_TYPE_TITLE_MAP[employType] : '类型'} {employType && employType !== EmployType.All ? EMPLOY_TYPE_TITLE_MAP[employType] : '类型'}

View File

@ -98,6 +98,7 @@ export const APP_CONFIG: AppConfigType = {
PageUrl.Partner, PageUrl.Partner,
PageUrl.WithdrawRecord, PageUrl.WithdrawRecord,
PageUrl.GroupDelegatePublish, PageUrl.GroupDelegatePublish,
PageUrl.GiveVip,
// PageUrl.DevDebug, // PageUrl.DevDebug,
], ],
window: { window: {

View File

@ -1,5 +1,6 @@
// export const DOMAIN = 'http://192.168.60.191:8082'; // export const DOMAIN = 'http://192.168.60.191:8082';
export const DOMAIN = 'https://neighbourhood.cn'; export const DOMAIN = process.env.BRAND === 'dev' ? 'https://dev.neighbourhood.cn' : 'https://neighbourhood.cn';
// export const DOMAIN = 'https://dev.neighbourhood.cn';
export const BASE_URL = `${DOMAIN}/api`; export const BASE_URL = `${DOMAIN}/api`;
export enum API { export enum API {

View File

@ -0,0 +1,3 @@
export default definePageConfig({
navigationBarTitleText: '赠送会员',
});

View File

@ -0,0 +1,130 @@
@import '@/styles/variables.less';
@import '@/styles/common.less';
.give-vip {
padding: 40px 24px 200px 24px;
&__hint {
font-size: 28px;
line-height: 48px;
color: @blColorG2;
gap: 12px;
.flex-row();
justify-content: center;
}
&__icon {
width: 65px;
height: 65px;
}
&__title {
margin-top: 24px;
font-weight: 500;
font-size: 40px;
line-height: 48px;
color: @blColor;
text-align: center;
flex: 0 1 auto;
gap: 12px;
.flex-row();
justify-content: center;
.highlight {
margin-left: -12px;
display: inline-block;
color: @blHighlightColor;
}
}
&__bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
&__info {
&-block {
margin-top: 48px;
}
&-title {
font-weight: 500;
font-size: 32px;
line-height: 32px;
color: #1d2129;
margin-bottom: 24px;
}
&-card {
box-sizing: border-box;
background: #ffffff;
border-radius: 24px;
padding: 32px;
}
&-body {
font-weight: 400;
font-size: 28px;
line-height: 40px;
color: #333333;
margin-bottom: 32px;
}
&-img {
width: 100%;
height: 614px;
}
}
&__footer {
position: fixed;
bottom: 0;
width: 100%;
padding: 12px 32px;
box-shadow: 0px -4px 20px 0px #00000014;
box-sizing: border-box;
background: #ffffff;
}
&__footer-body {
.flex-row();
justify-content: center;
}
&__button {
.button(@height: 88px; @fontSize: 32px; @fontWeight: 500; @borderRadius: 44px;);
width: 400px;
}
&__coupon {
&-info {
position: relative;
margin-top: 32px;
padding: 24px;
box-sizing: border-box;
border-radius: 24px;
.flex-column();
justify-content: center;
}
&-title {
font-weight: 500;
font-size: 32px;
line-height: 48px;
color: @blHighlightColor;
margin-bottom: 8px;
}
&-intro {
font-size: 28px;
line-height: 40px;
margin-bottom: 12px;
color: @blColor;
gap: 4px;
.flex-row();
.highlight {
font-weight: 600;
font-size: 32px;
line-height: 56px;
color: @blHighlightColor;
}
}
&-valid {
font-size: 28px;
line-height: 40px;
color: @blColorG2;
}
}
}

View File

@ -0,0 +1,71 @@
import { Image, Button } from '@tarojs/components';
import { Fragment, useCallback } from 'react';
import SafeBottomPadding from '@/components/safe-bottom-padding';
import { PageUrl } from '@/constants/app';
import { logWithPrefix } from '@/utils/common';
import { switchTab } from '@/utils/route';
import './index.less';
const PREFIX = 'give-vip';
const log = logWithPrefix(PREFIX);
export default function GiveVip() {
const handleNavigate = useCallback(() => {
switchTab(PageUrl.Job);
}, []);
return (
<div className={PREFIX}>
<Fragment>
<div className={`${PREFIX}__title`}>
<Image src="https://publiccdn.neighbourhood.com.cn/img/partner-yes.svg" className={`${PREFIX}__icon`} />
<div></div>
</div>
<div className={`${PREFIX}__coupon-info`}>
<Image src="https://publiccdn.neighbourhood.com.cn/img/parnet-share-bg.png" className={`${PREFIX}__bg`} />
<div className={`${PREFIX}__coupon-title`}></div>
<div className={`${PREFIX}__coupon-intro`}>
<div className="highlight">10</div>
</div>
<div className={`${PREFIX}__coupon-valid`}>2025/8/26 22:23:56</div>
</div>
</Fragment>
<Fragment>
<div className={`${PREFIX}__hint`}>
<Image
src="https://publiccdn.neighbourhood.com.cn/img/link-invalid.svg"
mode="aspectFit"
className={`${PREFIX}__icon`}
/>
<div className={`${PREFIX}__hint-title`}></div>
</div>
<div className={`${PREFIX}__title`}>
<div className="highlight"></div>
</div>
</Fragment>
<div className={`${PREFIX}__info-block`}>
<div className={`${PREFIX}__info-title`}></div>
<div className={`${PREFIX}__info-card`}>
<div className={`${PREFIX}__info-body`}>
便
</div>
<Image
className={`${PREFIX}__info-img`}
src="https://publiccdn.neighbourhood.com.cn/img/partner-share-coupon-img.png"
mode="heightFix"
/>
</div>
</div>
<div className={`${PREFIX}__footer`}>
<div className={`${PREFIX}__footer-body`}>
<Button className={`${PREFIX}__button`} onClick={handleNavigate}>
使
</Button>
</div>
<SafeBottomPadding />
</div>
</div>
);
}

View File

@ -286,6 +286,7 @@ export default function JobDetail() {
if (!jobId) { if (!jobId) {
return; return;
} }
Taro.eventCenter.trigger(EventName.VIEW_JOB_SUCCESS, jobId);
try { try {
const res = await requestJobDetail(jobId); const res = await requestJobDetail(jobId);
setData(res); setData(res);

View File

@ -20,7 +20,12 @@ export default function Partner() {
}; };
useShareAppMessage(() => { useShareAppMessage(() => {
console.log('Partner inviteCode', inviteCode); console.log('Partner inviteCode', inviteCode);
return getCommonShareMessage({ useCapture: false, inviteCode }); return getCommonShareMessage({
useCapture: false,
inviteCode,
title: '宝子,送你个播络会员,找工作更方便',
imageUrl: 'https://publiccdn.neighbourhood.com.cn/img/share-coupon.png',
});
}); });
return ( return (

View File

@ -17,6 +17,7 @@ export interface JobInfo {
distance?: number; // 距离。一期没有 distance?: number; // 距离。一期没有
isAuthed?: boolean; // 是否认证 isAuthed?: boolean; // 是否认证
companyName?: string; companyName?: string;
isRead?: boolean;
} }
export interface CreateJobInfo extends Pick<JobInfo, 'title' | 'employType' | 'jobDescription'> { export interface CreateJobInfo extends Pick<JobInfo, 'title' | 'employType' | 'jobDescription'> {

View File

@ -20,6 +20,7 @@ interface ShareAppProps {
inviteCode?: string; inviteCode?: string;
title?: string; title?: string;
path?: PageUrl; path?: PageUrl;
imageUrl?: string;
params?: Record<string, BL.Anything>; params?: Record<string, BL.Anything>;
} }
@ -28,6 +29,7 @@ export const getCommonShareMessage = ({
inviteCode, inviteCode,
title, title,
path, path,
imageUrl: _imageUrl,
params = {}, params = {},
}: ShareAppProps = {}): ShareAppMessageReturn => { }: ShareAppProps = {}): ShareAppMessageReturn => {
const inviteParams = inviteCode ? { c: inviteCode } : undefined; const inviteParams = inviteCode ? { c: inviteCode } : undefined;
@ -36,6 +38,6 @@ export const getCommonShareMessage = ({
return { return {
title: title || `昨天新增了${getRandomCount()}条主播通告,宝子快来看看`, title: title || `昨天新增了${getRandomCount()}条主播通告,宝子快来看看`,
path: sharePath, path: sharePath,
imageUrl: useCapture ? undefined : imageUrl, imageUrl: useCapture ? undefined : _imageUrl || imageUrl,
}; };
}; };

12833
yarn.lock

File diff suppressed because it is too large Load Diff