首次提交
This commit is contained in:
4
src/bszx/bm-cert/bm-cert.config.ts
Normal file
4
src/bszx/bm-cert/bm-cert.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '邀请函',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
13
src/bszx/bm-cert/bm-cert.scss
Normal file
13
src/bszx/bm-cert/bm-cert.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
.cert-bg{
|
||||
width: 750px;
|
||||
height: 1320px;
|
||||
margin: 0 auto;
|
||||
background: url("https://oss.wsdns.cn/20250304/5147356628a3460e811cf5fb90df26a7.png") no-repeat;
|
||||
background-size: 100%;
|
||||
}
|
||||
.cert-content{
|
||||
width: 480px;
|
||||
height: 720px;
|
||||
font-size: 24px;
|
||||
padding-top: 250px;
|
||||
}
|
||||
89
src/bszx/bm-cert/bm-cert.tsx
Normal file
89
src/bszx/bm-cert/bm-cert.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import './bm-cert.scss'
|
||||
import {useEffect, useState} from "react";
|
||||
import Taro from '@tarojs/taro'
|
||||
import {getPoster} from "@/api/bszx/bszxBm";
|
||||
import {ConfigProvider, Loading} from "@nutui/nutui-react-taro";
|
||||
|
||||
function BmCert() {
|
||||
const [poster, setPoster] = useState<string>('')
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
|
||||
const generatePoster = () => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// setPoster("https://oss.wsdns.cn/20250306/deec1c968aed4bc58a168a0f63ac8c87.jpg")
|
||||
}
|
||||
// 保存到临时地址
|
||||
Taro.downloadFile({
|
||||
url: poster,
|
||||
success: function (res) {
|
||||
Taro.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: function () {
|
||||
Taro.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
},
|
||||
fail: function (err) {
|
||||
if (err.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const reload = () => {
|
||||
getPoster().then(img => {
|
||||
setPoster(`${img}`)
|
||||
setTimeout(() => {
|
||||
setLoading(false)
|
||||
},1000)
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// setPoster("https://oss.wsdns.cn/20250306/deec1c968aed4bc58a168a0f63ac8c87.jpg")
|
||||
}
|
||||
})
|
||||
}
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
loading ?
|
||||
<div className={'bg-white w-full flex justify-center items-center'} style={{height: '100vh'}}>
|
||||
<ConfigProvider theme={{ nutuiLoadingIconSize: '28px' }}>
|
||||
<Loading type="spinner">加载中</Loading>
|
||||
</ConfigProvider>
|
||||
</div>
|
||||
:
|
||||
<div className={'flex justify-center'}>
|
||||
<img src={poster} width={'100vw'} height={'91vh'}/>
|
||||
{/*<div className={'cert-content'}>*/}
|
||||
{/* <p className={'py-2'}>尊敬的 {nickName} 校友 :</p>*/}
|
||||
{/* 百廿风华,桃李百中。2025年,<i className={'text-red-500 font-bold'}>百色市百色中学</i>迎来建校 120*/}
|
||||
{/* 周年。十秩沧桑砺洗、薪火相继,百色中学走过百折不挠、上下求索的光辉历程;爱党爱国、无私奉献、团结务实、积极进取的百中精神,始终引领学校风雨兼程、砥砺奋进;一代代百中人的耕耘与拼搏,闪耀着不同时期特有的亮点,积淀深厚的文化底蕴,承载着国家和人民殷切期望,铸造了今日的辉煌。兹定于*/}
|
||||
{/* 2025年5月1日(星期四)上午9:00 举行百色中学建校 120*/}
|
||||
{/* 周年庆典活动。诚邀您拨冗莅临出席、共襄盛举,为母校的改革发展献计献策!相约浓浓绎夏,畅谈别后心路,共话同窗师友情;相信您的到来必定令校庆活动添光异彩。*/}
|
||||
{/* 专此诚邀,敬祈惠允。*/}
|
||||
{/* <p className={'mt-2 text-right'}>百色市百色中学</p>*/}
|
||||
{/* <p className={'text-right'}>2025年1月2日</p>*/}
|
||||
{/*</div>*/}
|
||||
<div className={'fixed bottom-10'}>
|
||||
{/*<Button />*/}
|
||||
<button
|
||||
className={'item px-20 py-3 bg-yellow-300 text-black flex items-center gap-2 text-nowrap whitespace-nowrap'}
|
||||
onClick={() => {
|
||||
generatePoster()
|
||||
}}>
|
||||
保存到相册
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default BmCert;
|
||||
4
src/bszx/bm-log/bm-log.config.ts
Normal file
4
src/bszx/bm-log/bm-log.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '我的报名',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
33
src/bszx/bm-log/bm-log.tsx
Normal file
33
src/bszx/bm-log/bm-log.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Cell } from '@nutui/nutui-react-taro'
|
||||
import {useEffect, useState} from "react";
|
||||
import {myPageBszxBm} from "@/api/bszx/bszxBm";
|
||||
import {BszxBm} from "@/api/bszx/bszxBm/model";
|
||||
import navTo from "@/utils/common";
|
||||
|
||||
const BmLog = () => {
|
||||
const [list, setList] = useState<BszxBm[]>()
|
||||
const reload = () => {
|
||||
myPageBszxBm({limit: 1000}).then(res => {
|
||||
if(res.list){
|
||||
setList(res.list);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={'p-4'}>
|
||||
{list?.map((item, index) => {
|
||||
return (
|
||||
<Cell title={item.name} extra={item.createTime} key={index} onClick={() => {
|
||||
navTo('/bszx/bm-cert/bm-cert?id=' + item.id,true)
|
||||
}} />
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default BmLog
|
||||
4
src/bszx/bm.config.ts
Normal file
4
src/bszx/bm.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '我要报名',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
388
src/bszx/bm.tsx
Normal file
388
src/bszx/bm.tsx
Normal file
@@ -0,0 +1,388 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
import Taro, {getCurrentInstance} from '@tarojs/taro'
|
||||
import {
|
||||
Form,
|
||||
Button,
|
||||
Input,
|
||||
Radio,
|
||||
SideNavBar,
|
||||
SubSideNavBar,
|
||||
SideNavBarItem
|
||||
} from '@nutui/nutui-react-taro'
|
||||
import {DictData} from "@/api/system/dict-data/model";
|
||||
import {Picker} from '@nutui/nutui-react-taro'
|
||||
import {pageDictData} from "@/api/system/dict-data";
|
||||
import {addBszxBm, myPageBszxBm} from "@/api/bszx/bszxBm";
|
||||
import {BszxBm} from "@/api/bszx/bszxBm/model";
|
||||
import {getBszxClassForTree} from "@/api/bszx/bszxClass";
|
||||
// import {User} from "@/api/system/user/model";
|
||||
// import Banner from "../pages/index/Banner";
|
||||
|
||||
const {router} = getCurrentInstance()
|
||||
const Bm = () => {
|
||||
const formId = Number(router?.params.id)
|
||||
|
||||
const [form] = Form.useForm()
|
||||
const [sex, setSex] = useState<DictData[]>()
|
||||
const [gradeName, setGradeName] = useState<string>('')
|
||||
const [className, setClassName] = useState<string>('')
|
||||
const [phone, setPhone] = useState<string>('')
|
||||
const [classList, setClassList] = useState<any[]>()
|
||||
const [gradeList, setGradeList] = useState<any[]>()
|
||||
const [present, setPresent] = useState<DictData[]>()
|
||||
const [isVisibleClass, setIsVisibleClass] = useState(false)
|
||||
const [isVisibleGrade, setIsVisibleGrade] = useState(false)
|
||||
const [FormData, setFormData] = useState<BszxBm>(
|
||||
{
|
||||
type: 0,
|
||||
name: undefined,
|
||||
sex: undefined,
|
||||
phone: undefined,
|
||||
className: undefined,
|
||||
gradeName: undefined,
|
||||
address: undefined,
|
||||
workUnit: undefined,
|
||||
position: undefined,
|
||||
present: undefined,
|
||||
formId: undefined,
|
||||
comments: undefined
|
||||
}
|
||||
)
|
||||
|
||||
// 提交表单
|
||||
const submitSucceed = (values: any) => {
|
||||
addBszxBm({
|
||||
formId,
|
||||
name: values.name || FormData.name,
|
||||
sex: values.sex || FormData.sex,
|
||||
phone: phone,
|
||||
type: values.type || FormData.type,
|
||||
className: className || FormData.className,
|
||||
gradeName: gradeName || FormData.gradeName,
|
||||
address: values.address || FormData.address,
|
||||
workUnit: values.workUnit || FormData.workUnit,
|
||||
position: values.position || FormData.position,
|
||||
present: values.present ? '能' : '',
|
||||
comments: values.comments || FormData.comments
|
||||
}).then((data) => {
|
||||
if (data) {
|
||||
console.log(data,'data')
|
||||
Taro.showToast({title: `报名成功`, icon: 'success'})
|
||||
// setFormData();
|
||||
Taro.setStorageSync('NickName', values.name || FormData.name)
|
||||
setTimeout(() => {
|
||||
Taro.navigateTo({
|
||||
url: '/bszx/bm-cert/bm-cert'
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
}).catch(() => {
|
||||
Taro.showToast({
|
||||
title: '请勿重复报名',
|
||||
icon: 'error'
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
const submitFailed = (error: any) => {
|
||||
console.log(error, 'err...')
|
||||
// Taro.showToast({ title: error[0].message, icon: 'error' })
|
||||
}
|
||||
|
||||
const classConfirmPicker = (
|
||||
options: any[]
|
||||
) => {
|
||||
let description = ''
|
||||
options.forEach((option: any) => {
|
||||
description += ` ${option.text}`
|
||||
})
|
||||
setClassName(description)
|
||||
}
|
||||
const gradeNameConfirmPicker = (
|
||||
options: any[]
|
||||
) => {
|
||||
let description = ''
|
||||
options.forEach((option: any) => {
|
||||
description += ` ${option.text}`
|
||||
})
|
||||
setGradeName(description)
|
||||
}
|
||||
const changePicker = (options: any[], values: any, columnIndex: number) => {
|
||||
form.setFieldValue('className', values)
|
||||
console.log(options, columnIndex)
|
||||
}
|
||||
|
||||
const [navBarState, setNavBarState] = useState({
|
||||
visible: false
|
||||
})
|
||||
const changeNarBar = (visible) => {
|
||||
setNavBarState({
|
||||
visible
|
||||
})
|
||||
}
|
||||
|
||||
const onClassChange = (gradeName: string, className: string) => {
|
||||
console.log(gradeName,className)
|
||||
setGradeName(gradeName);
|
||||
setClassName(className);
|
||||
setFormData({
|
||||
...FormData,
|
||||
gradeName,
|
||||
className
|
||||
})
|
||||
setNavBarState({
|
||||
visible: false
|
||||
})
|
||||
}
|
||||
|
||||
const reload = () => {
|
||||
if (!Taro.getStorageSync('access_token')) {
|
||||
Taro.showModal({
|
||||
title: '提示',
|
||||
content: '请先登录',
|
||||
showCancel: false,
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
Taro.switchTab({
|
||||
url: '/pages/user/user'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return false;
|
||||
}
|
||||
myPageBszxBm().then(res => {
|
||||
const item = res.list[0];
|
||||
console.log(item, 'myPageBszxBm')
|
||||
if (item) {
|
||||
setFormData(item)
|
||||
if (item.gradeName) {
|
||||
setGradeName(item.gradeName)
|
||||
}
|
||||
if (item.className) {
|
||||
setClassName(item.className)
|
||||
}
|
||||
}
|
||||
})
|
||||
getBszxClassForTree().then(res => {
|
||||
console.log(res, 'setClassList');
|
||||
setClassList(res);
|
||||
})
|
||||
pageDictData({limit: 200}).then(res => {
|
||||
setSex(res?.list.filter((item) => item.dictCode === 'sex'))
|
||||
setPresent(res?.list.filter((item) => item.dictCode === 'present'))
|
||||
// setClassList([res?.list.filter((item) => item.dictCode === 'Class')])
|
||||
setGradeList(res?.list.filter((item) => {
|
||||
if (item.dictCode === 'Grade') {
|
||||
item.value = item.dictDataCode;
|
||||
item.text = item.dictDataName;
|
||||
return item
|
||||
}
|
||||
}))
|
||||
})
|
||||
setPhone(Taro.getStorageSync('Phone'))
|
||||
form.setFieldValue('phone', Taro.getStorageSync('Phone')) // 确保 form 已经初始化
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [form]) // 确保 form 已经初始化
|
||||
|
||||
return (
|
||||
<>
|
||||
{/*<Banner/>*/}
|
||||
{/*<div className={'fixed top-14 left-4 text-white'}>*/}
|
||||
{/* <image src={{ 'https://oss.wsdns.cn/20250224/5187dab5bc5047bda4521069696fd4dd.png' }} />*/}
|
||||
{/* <span>返回</span>*/}
|
||||
{/*</div>*/}
|
||||
<div className={'p-4'}>
|
||||
<Form
|
||||
divider
|
||||
initialValues={FormData}
|
||||
labelPosition="left"
|
||||
onFinish={(values) => submitSucceed(values)}
|
||||
onFinishFailed={(errors) => submitFailed(errors)}
|
||||
footer={
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Button nativeType="submit" block type="primary">
|
||||
提交
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Form.Item
|
||||
label="类型"
|
||||
name="type"
|
||||
style={{marginTop: '10px'}}
|
||||
required
|
||||
initialValue={FormData.type}
|
||||
>
|
||||
<Radio.Group defaultValue={FormData.type} direction="horizontal">
|
||||
<Radio value={0}>校友</Radio>
|
||||
<Radio value={1}>单位</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="姓名"
|
||||
name="name"
|
||||
required
|
||||
initialValue={FormData.name}
|
||||
rules={[{message: '请输入你的真实姓名'}]}
|
||||
>
|
||||
<Input placeholder="请输入姓名" type="text"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="性别"
|
||||
name="sex"
|
||||
required
|
||||
initialValue={FormData.sex}
|
||||
rules={[
|
||||
{message: '请选择性别'}
|
||||
]}
|
||||
>
|
||||
<Radio.Group defaultValue={FormData.sex} direction="horizontal">
|
||||
{
|
||||
sex?.map((item, index) => (
|
||||
<Radio key={index} value={item.dictDataCode}>
|
||||
{item.dictDataName}
|
||||
</Radio>
|
||||
))
|
||||
}
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="手机号码"
|
||||
name="phone"
|
||||
required
|
||||
initialValue={phone}
|
||||
rules={[{max: 11, message: '请输入手机号码'}]}
|
||||
>
|
||||
<Input placeholder="手机号码" maxLength={11} type="number"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="所在班级"
|
||||
name="className"
|
||||
required
|
||||
initialValue={FormData.className}
|
||||
rules={[{message: '请输入您的年级'}]}
|
||||
>
|
||||
<Button onClick={() => changeNarBar(true)}>{ className ? gradeName + ' ' + className : '请选择班级' }</Button>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="居住地"
|
||||
name="address"
|
||||
initialValue={FormData.address}
|
||||
rules={[{message: '请输入现居住地'}]}
|
||||
>
|
||||
<Input placeholder="请输入现居住地" type="text"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="工作单位"
|
||||
name="workUnit"
|
||||
required
|
||||
initialValue={FormData.workUnit}
|
||||
rules={[{message: '请输入您就职工作单位'}]}
|
||||
>
|
||||
<Input placeholder="请输入您就职工作单位" type="text"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="职务"
|
||||
name="position"
|
||||
required
|
||||
initialValue={FormData.position}
|
||||
rules={[{message: '请输入您的职务'}]}
|
||||
>
|
||||
<Input placeholder="请输入您的职务" type="text"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="是否能到场"
|
||||
name="present"
|
||||
required
|
||||
rules={[{required: true, message: '请选择是否能到场'}]}
|
||||
>
|
||||
<Radio.Group direction="horizontal">
|
||||
{
|
||||
present?.map((item, index) => (
|
||||
<Radio key={index} value={item.dictDataCode}>
|
||||
{item.dictDataName}
|
||||
</Radio>
|
||||
))
|
||||
}
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="备注信息"
|
||||
name="comments"
|
||||
initialValue={FormData.comments}
|
||||
rules={[{message: '备注信息'}]}
|
||||
>
|
||||
<Input placeholder="如找不到或忘记所在班级请备注一下" type="text"/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<Picker
|
||||
visible={isVisibleClass}
|
||||
options={classList}
|
||||
onConfirm={(list) => classConfirmPicker(list)}
|
||||
defaultValue={[2]}
|
||||
threeDimensional={false}
|
||||
duration={1000}
|
||||
onClose={() => setIsVisibleClass(false)}
|
||||
onChange={changePicker}
|
||||
/>
|
||||
<Picker
|
||||
visible={isVisibleGrade}
|
||||
options={gradeList}
|
||||
onConfirm={(list) => gradeNameConfirmPicker(list)}
|
||||
defaultValue={[2]}
|
||||
threeDimensional={false}
|
||||
duration={1000}
|
||||
onClose={() => setIsVisibleGrade(false)}
|
||||
onChange={changePicker}
|
||||
/>
|
||||
<SideNavBar
|
||||
title="选择班级"
|
||||
visible={navBarState.visible}
|
||||
onClose={() => {
|
||||
changeNarBar(false)
|
||||
}}
|
||||
>
|
||||
{
|
||||
classList?.map((item) => {
|
||||
return (
|
||||
<SubSideNavBar title={item.name} open={false} value={item.id}>
|
||||
{
|
||||
item.children?.map((sub) => {
|
||||
return (
|
||||
<>
|
||||
<SubSideNavBar title={sub.name} open={false} value={item.id + '-' + sub.id}>
|
||||
{
|
||||
sub.children?.map((sub2) => {
|
||||
return (
|
||||
<SideNavBarItem title={sub2.name} value={item.id + '-' + sub.id + '-' + sub2.id} onClick={() => {
|
||||
onClassChange(sub.name,sub2.name)
|
||||
}}/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</SubSideNavBar>
|
||||
</>
|
||||
)
|
||||
})
|
||||
}
|
||||
</SubSideNavBar>
|
||||
);
|
||||
})
|
||||
}
|
||||
</SideNavBar>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Bm
|
||||
13
src/bszx/cert-query/cert-query.scss
Normal file
13
src/bszx/cert-query/cert-query.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
.cert-bg{
|
||||
width: 720px;
|
||||
height: 1320px;
|
||||
margin: 15px auto;
|
||||
background: url("https://oss.wsdns.cn/20250127/cb1088c3b1354a118477a0b1a3cdac41.png") no-repeat;
|
||||
background-size: 100%;
|
||||
}
|
||||
.cert-content{
|
||||
width: 480px;
|
||||
height: 720px;
|
||||
font-size: 24px;
|
||||
padding-top: 450px;
|
||||
}
|
||||
4
src/bszx/cert-query/cert-query.ts
Normal file
4
src/bszx/cert-query/cert-query.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '捐款凭证',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
39
src/bszx/cert-query/cert-query.tsx
Normal file
39
src/bszx/cert-query/cert-query.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import './pay-cert.scss'
|
||||
import {useEffect, useState} from "react";
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import dayjs from 'dayjs'
|
||||
import {getBszxPay} from "@/api/bszx/bszxPay";
|
||||
import {BszxPay} from "@/api/bszx/bszxPay/model";
|
||||
function CertQuery() {
|
||||
const {params} = useRouter();
|
||||
const [nickName, setNickName] = useState<string>()
|
||||
const [payLog, setPayLog] = useState<BszxPay>()
|
||||
|
||||
const reload = () => {
|
||||
if (params.id) {
|
||||
getBszxPay(Number(params.id)).then(res => {
|
||||
if(res){
|
||||
setNickName(res.name)
|
||||
setPayLog(res);
|
||||
console.log(nickName)
|
||||
console.log(res,'log.....')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, []);
|
||||
return (
|
||||
<div className={'cert-bg flex justify-center'}>
|
||||
<div className={'cert-content'}>
|
||||
<p className={'py-2'}>亲爱的 { payLog?.name || '匿名'} :</p>
|
||||
感谢您支持捐赠百色市百色中学温暖校园项目!您捐赠金额:{payLog?.price || 0}元,单号:{payLog?.id},时间:{payLog?.createTime}。对您的奉献表示诚挚的敬意,特此证明!
|
||||
<p className={'mt-2 text-right'}>百色市百色中学</p>
|
||||
<p className={'text-right'}>{dayjs(payLog?.createTime).format('YYYY-MM-DD')}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CertQuery;
|
||||
4
src/bszx/flash.config.ts
Normal file
4
src/bszx/flash.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '烟花特效',
|
||||
navigationBarBackgroundColor: '#000000'
|
||||
})
|
||||
58
src/bszx/flash.scss
Normal file
58
src/bszx/flash.scss
Normal file
@@ -0,0 +1,58 @@
|
||||
.fireworks-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.firework {
|
||||
position: absolute;
|
||||
left: var(--x);
|
||||
top: var(--y);
|
||||
}
|
||||
|
||||
.particle {
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--color);
|
||||
transform-origin: center;
|
||||
animation: explode 1.5s ease-out forwards;
|
||||
opacity: 0;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background-color: var(--color);
|
||||
animation: particle-glow 1.5s ease-out forwards;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes explode {
|
||||
0% {
|
||||
transform: rotate(var(--angle)) translateX(0) scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: rotate(var(--angle)) translateX(100px) scale(0);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes particle-glow {
|
||||
0% {
|
||||
filter: brightness(1) blur(0);
|
||||
}
|
||||
100% {
|
||||
filter: brightness(2) blur(3px);
|
||||
}
|
||||
}
|
||||
101
src/bszx/flash.tsx
Normal file
101
src/bszx/flash.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import './flash.scss'
|
||||
import {CmsAd} from "@/api/cms/cmsAd/model";
|
||||
import {getCmsAd} from "@/api/cms/cmsAd";
|
||||
import { Swiper } from '@nutui/nutui-react-taro'
|
||||
|
||||
interface Firework {
|
||||
id: number
|
||||
x: number
|
||||
y: number
|
||||
color: string
|
||||
}
|
||||
|
||||
const MyPage = () => {
|
||||
const [item, setItem] = useState<CmsAd>()
|
||||
const reload = () => {
|
||||
getCmsAd(366).then(data => {
|
||||
setItem(data)
|
||||
})
|
||||
}
|
||||
const [fireworks, setFireworks] = useState<Firework[]>([])
|
||||
|
||||
// 生成随机颜色
|
||||
const getRandomColor = () => {
|
||||
const colors = [
|
||||
'#ff0000', '#00ff00', '#0000ff', '#ffff00',
|
||||
'#ff00ff', '#00ffff', '#ff9900', '#ff0099'
|
||||
]
|
||||
return colors[Math.floor(Math.random() * colors.length)]
|
||||
}
|
||||
|
||||
// 创建新烟花
|
||||
const createFirework = () => {
|
||||
const firework: Firework = {
|
||||
id: Date.now(),
|
||||
x: Math.random() * 100, // 随机横向位置 (0-100%)
|
||||
y: Math.random() * 40, // 修改为随机纵向位置 (0-40%)
|
||||
color: getRandomColor()
|
||||
}
|
||||
setFireworks(prev => [...prev, firework])
|
||||
|
||||
// 1.5秒后移除烟花
|
||||
setTimeout(() => {
|
||||
setFireworks(prev => prev.filter(f => f.id !== firework.id))
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload();
|
||||
// 初始创建更多烟花
|
||||
for (let i = 0; i < 6; i++) { // 修改初始烟花数量为6个
|
||||
createFirework()
|
||||
}
|
||||
|
||||
// 缩短创建间隔,增加密度
|
||||
const interval = setInterval(() => {
|
||||
createFirework()
|
||||
}, 500) // 修改为500ms创建一次
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Swiper defaultValue={0} height={279} indicator style={{ height: '280px' }}>
|
||||
{item?.imageList?.map((item) => (
|
||||
<Swiper.Item key={item}>
|
||||
<img width="100%" height="100%" src={item.url} alt="" style={{ height: '280px' }} />
|
||||
</Swiper.Item>
|
||||
))}
|
||||
</Swiper>
|
||||
<div className="fireworks-container">
|
||||
{fireworks.map(firework => (
|
||||
<div
|
||||
key={firework.id}
|
||||
className="firework"
|
||||
style={{
|
||||
'--x': `${firework.x}%`,
|
||||
'--y': `${firework.y}%`,
|
||||
'--color': firework.color
|
||||
} as React.CSSProperties}
|
||||
>
|
||||
{/* 生成30个粒子 */}
|
||||
{Array.from({ length: 30 }).map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="particle"
|
||||
style={{
|
||||
'--angle': `${(i * 12)}deg`,
|
||||
'--delay': `${Math.random() * 0.2}s`
|
||||
} as React.CSSProperties}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default MyPage
|
||||
4
src/bszx/item.config.ts
Normal file
4
src/bszx/item.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '文章详情',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
11
src/bszx/item.scss
Normal file
11
src/bszx/item.scss
Normal file
@@ -0,0 +1,11 @@
|
||||
.content{
|
||||
padding: 32px;
|
||||
line-height: 2.4rem;
|
||||
}
|
||||
.content p{
|
||||
text-indent: 2rem;
|
||||
}
|
||||
|
||||
.nr-bg{
|
||||
background: linear-gradient(to bottom, #ffe0e0, #ffffff);
|
||||
}
|
||||
67
src/bszx/item.tsx
Normal file
67
src/bszx/item.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
import {Tag} from '@nutui/nutui-react-taro'
|
||||
import {useRouter, useShareAppMessage, useShareTimeline} from '@tarojs/taro'
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model"
|
||||
import {Eye} from '@nutui/icons-react-taro'
|
||||
// 显示html富文本
|
||||
import {View, RichText} from '@tarojs/components'
|
||||
import './item.scss'
|
||||
import {wxParse} from "@/utils/common";
|
||||
import {getCmsArticle} from "@/api/cms/cmsArticle";
|
||||
|
||||
function Item() {
|
||||
const {params} = useRouter();
|
||||
// 文章详情
|
||||
const [item, setItem] = useState<CmsArticle>()
|
||||
// 浏览量
|
||||
const [views, setViews] = useState<number>()
|
||||
|
||||
const reload = () => {
|
||||
getCmsArticle(Number(params.id)).then(data => {
|
||||
if(data){
|
||||
data.content = wxParse(data.content)
|
||||
setItem(data)
|
||||
setViews(data.actualViews)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useShareTimeline(() => {
|
||||
return {
|
||||
title: item?.title,
|
||||
path: `/bszx/item?id=${item?.articleId}`
|
||||
};
|
||||
});
|
||||
|
||||
useShareAppMessage(() => {
|
||||
return {
|
||||
title: item?.title,
|
||||
path: `/bszx/item?id=${item?.articleId}`,
|
||||
success: function (res) {
|
||||
console.log('分享成功', res);
|
||||
},
|
||||
fail: function (res) {
|
||||
console.log('分享失败', res);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
reload();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={'bg-white nr-bg'}>
|
||||
<div className={'p-3 font-bold text-lg'}>{item?.title}</div>
|
||||
<div className={'flex justify-between px-3'}>
|
||||
<Tag type={'success'}>{item?.categoryName}</Tag>
|
||||
<div className={'flex items-center gap-2 text-sm text-gray-400'}><Eye size={14}/>{views}</div>
|
||||
</div>
|
||||
<View className={'content text-gray-700 text-sm'}>
|
||||
<RichText nodes={item?.content}/>
|
||||
</View>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Item
|
||||
4
src/bszx/pay-cert/pay-cert.config.ts
Normal file
4
src/bszx/pay-cert/pay-cert.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '捐款凭证',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
13
src/bszx/pay-cert/pay-cert.scss
Normal file
13
src/bszx/pay-cert/pay-cert.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
.cert-bg{
|
||||
width: 750px;
|
||||
height: 100vh;
|
||||
margin: 0 auto;
|
||||
background: url("https://oss.wsdns.cn/20250127/cb1088c3b1354a118477a0b1a3cdac41.png") no-repeat;
|
||||
background-size: 100%;
|
||||
}
|
||||
.cert-content{
|
||||
width: 480px;
|
||||
height: 720px;
|
||||
font-size: 24px;
|
||||
padding-top: 450px;
|
||||
}
|
||||
84
src/bszx/pay-cert/pay-cert.tsx
Normal file
84
src/bszx/pay-cert/pay-cert.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import './pay-cert.scss'
|
||||
import {useEffect, useState} from "react";
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {getPayCert} from "@/api/bszx/bszxPay";
|
||||
import {ConfigProvider, Loading} from "@nutui/nutui-react-taro";
|
||||
|
||||
function PayCert() {
|
||||
const {params} = useRouter();
|
||||
const [poster, setPoster] = useState<string>('')
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
|
||||
const generatePayCert = () => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// setPoster("https://oss.wsdns.cn/20250304/8a9aac182ac94494a806c4bda5766fee.png")
|
||||
}
|
||||
// 保存到临时地址
|
||||
Taro.downloadFile({
|
||||
url: poster,
|
||||
success: function (res) {
|
||||
Taro.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: function () {
|
||||
Taro.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
},
|
||||
fail: function (err) {
|
||||
if (err.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const reload = () => {
|
||||
if (params.id) {
|
||||
getPayCert(Number(params.id)).then(img => {
|
||||
console.log(img, 'img....')
|
||||
setPoster(`${img}`)
|
||||
setTimeout(() => {
|
||||
setLoading(false)
|
||||
},1000)
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// setPoster("https://oss.wsdns.cn/20250304/8a9aac182ac94494a806c4bda5766fee.png")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
{loading ?
|
||||
<div className={'bg-white w-full flex justify-center items-center'} style={{height: '100vh'}}>
|
||||
<ConfigProvider theme={{nutuiLoadingIconSize: '28px'}}>
|
||||
<Loading type="spinner">加载中</Loading>
|
||||
</ConfigProvider>
|
||||
</div> :
|
||||
|
||||
<div className={'flex justify-center'}>
|
||||
<img src={poster} width={'750rpx'} height={'1060rpx'}/>
|
||||
<div className={'fixed bottom-10'}>
|
||||
{/*<Button />*/}
|
||||
<button
|
||||
className={'item px-20 py-3 bg-yellow-300 text-black flex items-center gap-2 text-nowrap whitespace-nowrap'}
|
||||
onClick={() => {
|
||||
generatePayCert()
|
||||
}}>
|
||||
保存到相册
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default PayCert;
|
||||
4
src/bszx/pay-log/pay-log.config.ts
Normal file
4
src/bszx/pay-log/pay-log.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '捐款记录',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
104
src/bszx/pay-log/pay-log.tsx
Normal file
104
src/bszx/pay-log/pay-log.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import {Avatar, Button, Cell, Space} from '@nutui/nutui-react-taro'
|
||||
import {useEffect, useState, CSSProperties} from "react";
|
||||
import {BszxPay} from "@/api/bszx/bszxPay/model";
|
||||
import {myPageBszxPay} from "@/api/bszx/bszxPay";
|
||||
import {InfiniteLoading} from '@nutui/nutui-react-taro'
|
||||
import dayjs from "dayjs";
|
||||
import navTo from "@/utils/common";
|
||||
|
||||
const InfiniteUlStyle: CSSProperties = {
|
||||
height: '80vh',
|
||||
width: '100%',
|
||||
padding: '0',
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
}
|
||||
function PayRecord() {
|
||||
const [list, setList] = useState<BszxPay[]>([])
|
||||
const [page, setPage] = useState(1)
|
||||
const [hasMore, setHasMore] = useState(true)
|
||||
const reload = async () => {
|
||||
myPageBszxPay({page}).then(res => {
|
||||
if (res?.list && res?.list.length > 0) {
|
||||
const newList = list?.concat(res.list)
|
||||
setList(newList);
|
||||
setHasMore(true)
|
||||
} else {
|
||||
setHasMore(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const reloadMore = async () => {
|
||||
setPage(page + 1)
|
||||
reload();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setPage(2)
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={'px-2'}>
|
||||
<Cell>
|
||||
<ul style={InfiniteUlStyle} id="scroll">
|
||||
<InfiniteLoading
|
||||
target="scroll"
|
||||
hasMore={hasMore}
|
||||
onLoadMore={reloadMore}
|
||||
onScroll={() => {
|
||||
console.log('onScroll')
|
||||
}}
|
||||
onScrollToUpper={() => {
|
||||
console.log('onScrollToUpper')
|
||||
}}
|
||||
loadingText={
|
||||
<>
|
||||
加载中
|
||||
</>
|
||||
}
|
||||
loadMoreText={
|
||||
<>
|
||||
没有更多了
|
||||
</>
|
||||
}
|
||||
>
|
||||
{list?.map(item => {
|
||||
return (
|
||||
<Cell style={{padding: '0'}}>
|
||||
<div className={'flex w-full justify-between items-center'}>
|
||||
<div className={'flex'}>
|
||||
<Space>
|
||||
<Avatar
|
||||
src={item.avatar}
|
||||
/>
|
||||
<div className={'flex flex-col'}>
|
||||
<div className={'real-name text-lg'}>
|
||||
{item.name || '匿名'}
|
||||
</div>
|
||||
<div style={{maxWidth: '200px'}} className={'text-gray-400'}>{item.formName},{dayjs(item.createTime).format('YYYY-MM-DD HH:mm')}</div>
|
||||
<div className={'text-green-600 my-1'}>心愿:{item.comments}</div>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
<div className={'price'}>
|
||||
<span className={' text-red-500 text-xl text-center font-bold'}>¥{item.price}</span>
|
||||
<Button className={'whitespace-nowrap'} onClick={() => {
|
||||
navTo('/bszx/pay-cert/pay-cert?id=' + item.id, true)
|
||||
}}>
|
||||
查看证书
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Cell>
|
||||
)
|
||||
})}
|
||||
</InfiniteLoading>
|
||||
</ul>
|
||||
</Cell>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PayRecord
|
||||
4
src/bszx/pay-record/pay-record.config.ts
Normal file
4
src/bszx/pay-record/pay-record.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '善款明细',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
118
src/bszx/pay-record/pay-record.tsx
Normal file
118
src/bszx/pay-record/pay-record.tsx
Normal file
@@ -0,0 +1,118 @@
|
||||
import {Avatar, Cell, Space} from '@nutui/nutui-react-taro'
|
||||
import {useEffect, useState, CSSProperties} from "react";
|
||||
import {BszxPay} from "@/api/bszx/bszxPay/model";
|
||||
import {getCount, pageBszxPay} from "@/api/bszx/bszxPay";
|
||||
import {InfiniteLoading} from '@nutui/nutui-react-taro'
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const InfiniteUlStyle: CSSProperties = {
|
||||
height: '70vh',
|
||||
width: '100%',
|
||||
padding: '0',
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
}
|
||||
function PayRecord() {
|
||||
const [list, setList] = useState<BszxPay[]>([])
|
||||
const [page, setPage] = useState(1)
|
||||
const [hasMore, setHasMore] = useState(true)
|
||||
const [totalMoney, setTotalMoney] = useState()
|
||||
const [numbers, setNumbers] = useState()
|
||||
const reload = async () => {
|
||||
pageBszxPay({page}).then(res => {
|
||||
let newList: BszxPay[] | undefined = []
|
||||
if (res?.list && res?.list.length > 0) {
|
||||
newList = list?.concat(res.list)
|
||||
setHasMore(true)
|
||||
} else {
|
||||
newList = res?.list
|
||||
setHasMore(false)
|
||||
}
|
||||
setList(newList || []);
|
||||
})
|
||||
getCount().then(res => {
|
||||
setNumbers(res.numbers);
|
||||
setTotalMoney(res.totalMoney);
|
||||
})
|
||||
}
|
||||
|
||||
const reloadMore = async () => {
|
||||
setPage(page + 1)
|
||||
reload();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setPage(2)
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={'px-2'}>
|
||||
<Cell>
|
||||
<div className={'flex w-full text-center justify-around'}>
|
||||
<div className={'item py-1'}>
|
||||
<span className={'text-gray-400'}>已筹资金(元)</span>
|
||||
<span className={'text-xl py-1 font-bold'}>¥{totalMoney}元</span>
|
||||
</div>
|
||||
<div className={'item py-1'}>
|
||||
<span className={'text-gray-400'}>爱心人次</span>
|
||||
<span className={'text-xl py-1 font-bold'}>{numbers}次</span>
|
||||
</div>
|
||||
</div>
|
||||
</Cell>
|
||||
<Cell>
|
||||
<ul style={InfiniteUlStyle} id="scroll">
|
||||
<InfiniteLoading
|
||||
target="scroll"
|
||||
hasMore={hasMore}
|
||||
onLoadMore={reloadMore}
|
||||
onScroll={() => {
|
||||
console.log('onScroll')
|
||||
}}
|
||||
onScrollToUpper={() => {
|
||||
console.log('onScrollToUpper')
|
||||
}}
|
||||
loadingText={
|
||||
<>
|
||||
加载中
|
||||
</>
|
||||
}
|
||||
loadMoreText={
|
||||
<>
|
||||
没有更多了
|
||||
</>
|
||||
}
|
||||
>
|
||||
{list?.map(item => {
|
||||
return (
|
||||
<Cell style={{padding: '0'}}>
|
||||
<div className={'flex w-full justify-between items-center'}>
|
||||
<div className={'flex'}>
|
||||
<Space>
|
||||
<Avatar
|
||||
src={item.avatar}
|
||||
/>
|
||||
<div className={'flex flex-col'}>
|
||||
<div className={'real-name text-lg'}>
|
||||
{item.name || '匿名'}
|
||||
</div>
|
||||
<div style={{maxWidth: '240px'}} className={'text-gray-400'}>{item.formName},{dayjs(item.createTime).format('YYYY-MM-DD HH:mm')}</div>
|
||||
<div className={'text-green-600 my-1'}>心愿:{item.comments}</div>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
<div className={'price text-red-500 text-xl font-bold'}>
|
||||
¥{item.price}
|
||||
</div>
|
||||
</div>
|
||||
</Cell>
|
||||
)
|
||||
})}
|
||||
</InfiniteLoading>
|
||||
</ul>
|
||||
</Cell>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PayRecord
|
||||
6
src/bszx/pay/detail.config.ts
Normal file
6
src/bszx/pay/detail.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '捐款详情',
|
||||
enableShareTimeline: true,
|
||||
enableShareAppMessage: true,
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
18
src/bszx/pay/detail.scss
Normal file
18
src/bszx/pay/detail.scss
Normal file
@@ -0,0 +1,18 @@
|
||||
.content {
|
||||
padding: 32px;
|
||||
line-height: 2.4rem;
|
||||
}
|
||||
.content-bg{
|
||||
background-image: url("https://oss.wsdns.cn/20250224/7230c35b276f420a8527d08358759d8c.jpg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100%;
|
||||
background-position: bottom;
|
||||
}
|
||||
|
||||
page{
|
||||
background-color: #fff2ee !important;
|
||||
}
|
||||
|
||||
.nr-bg{
|
||||
background: linear-gradient(to bottom, #ffe0e0, #ffffff);
|
||||
}
|
||||
173
src/bszx/pay/detail.tsx
Normal file
173
src/bszx/pay/detail.tsx
Normal file
@@ -0,0 +1,173 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
import {Image, Tag} from '@nutui/nutui-react-taro'
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import {Divider} from '@nutui/nutui-react-taro'
|
||||
import dayjs from 'dayjs'
|
||||
import Taro, {
|
||||
useLoad,
|
||||
useShareAppMessage,
|
||||
useShareTimeline,
|
||||
} from '@tarojs/taro';
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model"
|
||||
import {Eye, Clock, PickedUp, Purse, Coupon} from '@nutui/icons-react-taro'
|
||||
import AddCartBar from "@/components/AddCartBar";
|
||||
// 显示html富文本
|
||||
import {View, RichText} from '@tarojs/components'
|
||||
import './detail.scss'
|
||||
import Line from "@/components/Gap";
|
||||
import {wxParse} from "@/utils/common";
|
||||
import {getCmsArticle} from "@/api/cms/cmsArticle";
|
||||
import {pageBszxPay} from "@/api/bszx/bszxPay";
|
||||
import {getUserInfo, getWxOpenId} from "@/api/layout";
|
||||
|
||||
function Detail() {
|
||||
const {params} = useRouter();
|
||||
// 文章详情
|
||||
const [item, setItem] = useState<CmsArticle>()
|
||||
// 浏览量
|
||||
const [views, setViews] = useState<number>()
|
||||
// 报名人数
|
||||
const [bmUsers, setBmUsers] = useState<number>()
|
||||
// 是否登录
|
||||
const [isLogin, setIsLogin] = useState<boolean>(false)
|
||||
const reload = () => {
|
||||
getCmsArticle(Number(params.id)).then(data => {
|
||||
if (data) {
|
||||
data.content = wxParse(data.content)
|
||||
setItem(data)
|
||||
setViews(data.actualViews)
|
||||
}
|
||||
})
|
||||
pageBszxPay({
|
||||
formId: Number(params.id),
|
||||
}).then(res => {
|
||||
if (res) {
|
||||
setBmUsers(res.count)
|
||||
}
|
||||
})
|
||||
// 登录
|
||||
Taro.getUserInfo({
|
||||
success: (res) => {
|
||||
console.log(res.userInfo.avatarUrl)
|
||||
getUserInfo().then((data) => {
|
||||
if (data) {
|
||||
setIsLogin(true);
|
||||
console.log(isLogin,'isLogin')
|
||||
Taro.setStorageSync('UserId', data.userId)
|
||||
// 获取openId
|
||||
if (!data.openid) {
|
||||
Taro.login({
|
||||
success: (res) => {
|
||||
getWxOpenId({code: res.code}).then(() => {
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}).catch(() => {
|
||||
console.log('未登录')
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
useLoad(async () => {
|
||||
//获取进入页面参数 scene为1154===朋友圈进入
|
||||
const data = Taro.getLaunchOptionsSync();
|
||||
console.log(data, 'data')
|
||||
//开启分享
|
||||
Taro.showShareMenu({
|
||||
withShareTicket: true,
|
||||
});
|
||||
})
|
||||
|
||||
useShareTimeline(() => {
|
||||
return {
|
||||
title: item?.title,
|
||||
path: `/bszx/pay/detail?id=${item?.articleId}`,
|
||||
imageUrl: item?.image,
|
||||
};
|
||||
});
|
||||
|
||||
useShareAppMessage(() => {
|
||||
return {
|
||||
title: item?.title,
|
||||
path: `/bszx/pay/detail?id=${item?.articleId}`,
|
||||
imageUrl: item?.image,
|
||||
success: function (res) {
|
||||
console.log('分享成功', res);
|
||||
},
|
||||
fail: function (res) {
|
||||
console.log('分享失败', res);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
reload();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Image src={item?.image} height={375}/>
|
||||
{/*linear-gradient(to bottom, #ffe0e0, #ffb6c1)*/}
|
||||
<div className={'pb-5 nr-bg'}>
|
||||
<div className={'p-3 font-bold text-lg'}>{item?.title}</div>
|
||||
<div className={'flex justify-between px-3'}>
|
||||
<Tag type={'success'}>{item?.categoryName}</Tag>
|
||||
<div className={'flex items-center gap-2 text-sm text-gray-500'}><Eye size={14}/>{views}</div>
|
||||
</div>
|
||||
<Divider/>
|
||||
{
|
||||
item?.model == 'bm' ? '' :
|
||||
<div>
|
||||
{
|
||||
!item?.endTime ? '' :
|
||||
<>
|
||||
<div className={'flex px-3 items-center gap-2'}>
|
||||
<Clock size={14}/>
|
||||
<div
|
||||
className={'text-sm font-bold'}>{dayjs(item?.startTime).format('YYYY-MM-DD')} 至 {dayjs(item?.endTime).format('YYYY-MM-DD')}</div>
|
||||
</div>
|
||||
<Divider/>
|
||||
</>
|
||||
}
|
||||
{
|
||||
!item?.price ? '' :
|
||||
<>
|
||||
<div className={'flex px-3 items-center gap-2'}>
|
||||
<Purse size={14}/>
|
||||
<div
|
||||
className={'text-sm font-bold text-orange-500'}>{item?.price == 0 ? '线下收费' : '¥' + item?.price}
|
||||
</div>
|
||||
</div>
|
||||
<Divider/>
|
||||
</>
|
||||
}
|
||||
<div className={'flex px-3 items-center gap-2'}>
|
||||
<PickedUp size={14}/>
|
||||
<div
|
||||
className={'text-sm font-bold'}>已捐款人数 {bmUsers}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<Divider/>
|
||||
<div className={'flex px-3 items-center gap-2'}>
|
||||
<Coupon size={14}/>
|
||||
<div
|
||||
className={'text-sm font-bold'}>活动详情
|
||||
</div>
|
||||
</div>
|
||||
<View className={'content text-gray-700 text-sm relative content-bg'}>
|
||||
<RichText nodes={item?.content}/>
|
||||
</View>
|
||||
<Line height={44}/>
|
||||
</div>
|
||||
<AddCartBar/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Detail
|
||||
4
src/bszx/pay/pay.config.ts
Normal file
4
src/bszx/pay/pay.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '我要捐款',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
212
src/bszx/pay/pay.tsx
Normal file
212
src/bszx/pay/pay.tsx
Normal file
@@ -0,0 +1,212 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
import Taro, {getCurrentInstance} from '@tarojs/taro'
|
||||
import {
|
||||
Form,
|
||||
Button,
|
||||
Input,
|
||||
RadioGroup,
|
||||
Radio
|
||||
} from '@nutui/nutui-react-taro'
|
||||
import {navigateTo} from '@tarojs/taro'
|
||||
import {addBszxPay,myPageBszxPay} from "@/api/bszx/bszxPay";
|
||||
import {BszxPay} from "@/api/bszx/bszxPay/model";
|
||||
import {TenantId} from "@/utils/config";
|
||||
import {myPageBszxBm} from "@/api/bszx/bszxBm";
|
||||
|
||||
const Bm = () => {
|
||||
const { router } = getCurrentInstance();
|
||||
const [formId, setFormId] = useState<number>()
|
||||
const [gradeName, setGradeName] = useState('')
|
||||
const [className, setClassName] = useState('')
|
||||
const [FormData, setFormData] = useState<BszxPay>(
|
||||
{
|
||||
name: undefined,
|
||||
sex: undefined,
|
||||
phone: undefined,
|
||||
className: undefined,
|
||||
gradeName: undefined,
|
||||
address: undefined,
|
||||
workUnit: undefined,
|
||||
position: undefined,
|
||||
present: undefined,
|
||||
formId: undefined
|
||||
}
|
||||
)
|
||||
|
||||
// 提交表单
|
||||
const submitSucceed = (values: any) => {
|
||||
// if(values.price < 10){
|
||||
// Taro.showToast({
|
||||
// title: '捐款金额不能低于10元',
|
||||
// icon: 'none'
|
||||
// })
|
||||
// return false;
|
||||
// }
|
||||
Taro.request({
|
||||
url: 'https://cms-api.websoft.top/api/shop/shop-order',
|
||||
method: 'POST',
|
||||
header: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': Taro.getStorageSync('access_token'),
|
||||
TenantId
|
||||
},
|
||||
data: {
|
||||
totalPrice: values.price,
|
||||
payPrice: values.price,
|
||||
tenantId: TenantId,
|
||||
payType: 1,
|
||||
comments: values.comments,
|
||||
name: values.name || FormData.name,
|
||||
sex: values.sex || FormData.sex,
|
||||
phone: values.phone || FormData.phone,
|
||||
className: className || FormData.className,
|
||||
gradeName: gradeName || FormData.gradeName,
|
||||
address: values.address || FormData.address,
|
||||
workUnit: values.workUnit || FormData.workUnit,
|
||||
position: values.position || FormData.position,
|
||||
formId
|
||||
},
|
||||
success: function (res) {
|
||||
const data = res.data.data
|
||||
if(data){
|
||||
Taro.requestPayment({
|
||||
timeStamp: data.timeStamp,
|
||||
nonceStr: data.nonceStr,
|
||||
package: data.package,
|
||||
signType: data.signType,
|
||||
paySign: data.paySign,
|
||||
success: function (res) {
|
||||
if(res.errMsg == "requestPayment:ok"){
|
||||
console.log('捐款成功')
|
||||
addBszxPay({
|
||||
formId,
|
||||
orderNo: data.orderNo,
|
||||
name: values.name || FormData.name,
|
||||
sex: values.sex || FormData.sex,
|
||||
phone: values.phone || FormData.phone,
|
||||
className: className || FormData.className,
|
||||
gradeName: gradeName || FormData.gradeName,
|
||||
address: values.address || FormData.address,
|
||||
workUnit: values.workUnit || FormData.workUnit,
|
||||
position: values.position || FormData.position,
|
||||
present: values.present === '能',
|
||||
price: values.price || FormData.price,
|
||||
comments: values.comments,
|
||||
}).then((data) => {
|
||||
console.log(data,'payRes')
|
||||
console.log('跳转证书页面')
|
||||
setTimeout(() => {
|
||||
navigateTo({url: `/bszx/pay-cert/pay-cert?id=${data?.id}&orderNo=${data?.orderNo}`});
|
||||
}, 1000)
|
||||
}).catch(err => {
|
||||
console.log(err,'errr....')
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: function (res) {
|
||||
console.log(res)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const submitFailed = (error: any) => {
|
||||
console.log(error,'err...')
|
||||
// Taro.showToast({ title: error[0].message, icon: 'error' })
|
||||
}
|
||||
const reload = () => {
|
||||
myPageBszxBm().then(res => {
|
||||
if(res.count == 0){
|
||||
Taro.showToast({
|
||||
title: '请先完善个人资料',
|
||||
icon: 'error'
|
||||
})
|
||||
setTimeout(() => {
|
||||
Taro.navigateTo({
|
||||
url: '/user/profile/profile'
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
myPageBszxPay({limit: 1}).then(res => {
|
||||
const item = res.list[0];
|
||||
if(item){
|
||||
setFormData(item)
|
||||
if(item.gradeName){
|
||||
setGradeName(item.gradeName)
|
||||
}
|
||||
if(item.className){
|
||||
setClassName(item.className)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = router?.params.id as number | undefined;
|
||||
setFormId(id)
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={'p-4'}>
|
||||
<Form
|
||||
divider
|
||||
initialValues={FormData}
|
||||
labelPosition="left"
|
||||
onFinish={(values) => submitSucceed(values)}
|
||||
onFinishFailed={(errors) => submitFailed(errors)}
|
||||
footer={
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Button nativeType="submit" block type="primary">
|
||||
提交
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Form.Item
|
||||
name="price"
|
||||
initialValue={FormData.price}
|
||||
rules={[{message: '请选您要择捐款的金额'}]}
|
||||
>
|
||||
<RadioGroup value={FormData.price} direction="horizontal">
|
||||
<Radio shape="button" value="100"><span className={'font-bold text-sm'}>100元</span></Radio>
|
||||
<Radio shape="button" value="200"><span className={'font-bold text-sm'}>200元</span></Radio>
|
||||
<Radio shape="button" value="300"><span className={'font-bold text-sm'}>300元</span></Radio>
|
||||
<Radio shape="button" value="500"><span className={'font-bold text-sm'}>500元</span></Radio>
|
||||
<Radio shape="button" value="1000"><span className={'font-bold text-sm'}>1000元</span></Radio>
|
||||
<Radio shape="button" value="2000"><span className={'font-bold text-sm'}>2000元</span></Radio>
|
||||
<Radio shape="button" value="3000"><span className={'font-bold text-sm'}>3000元</span></Radio>
|
||||
<Radio shape="button" value="5000"><span className={'font-bold text-sm'}>5000元</span></Radio>
|
||||
<Radio shape="button" value="10000"><span className={'font-bold text-sm'}>10000元</span></Radio>
|
||||
</RadioGroup>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="捐款金额"
|
||||
name="price"
|
||||
required
|
||||
rules={[{ required: true,message: '请输入捐款数额' }]}
|
||||
>
|
||||
<Input placeholder="请输入捐款数额" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="您的心愿"
|
||||
name="comments"
|
||||
rules={[{ message: '请填写您的心意' }]}
|
||||
>
|
||||
<Input placeholder="请填写您的心意" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Bm
|
||||
4
src/bszx/pdf.config.ts
Normal file
4
src/bszx/pdf.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '文章详情',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
8
src/bszx/pdf.scss
Normal file
8
src/bszx/pdf.scss
Normal file
@@ -0,0 +1,8 @@
|
||||
.content{
|
||||
padding: 32px;
|
||||
line-height: 2.4rem;
|
||||
}
|
||||
|
||||
.nr-bg{
|
||||
background: linear-gradient(to bottom, #ffe0e0, #ffffff);
|
||||
}
|
||||
45
src/bszx/pdf.tsx
Normal file
45
src/bszx/pdf.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model"
|
||||
import {Eye} from '@nutui/icons-react-taro'
|
||||
// 显示html富文本
|
||||
import {View, RichText} from '@tarojs/components'
|
||||
import './pdf.scss'
|
||||
import {wxParse} from "@/utils/common";
|
||||
import {getCmsArticle} from "@/api/cms/cmsArticle";
|
||||
|
||||
function Item() {
|
||||
const {params} = useRouter();
|
||||
// 文章详情
|
||||
const [item, setItem] = useState<CmsArticle>()
|
||||
// 浏览量
|
||||
const [views, setViews] = useState<number>()
|
||||
|
||||
const reload = () => {
|
||||
getCmsArticle(Number(params.id)).then(data => {
|
||||
if(data){
|
||||
data.content = wxParse(data.content)
|
||||
setItem(data)
|
||||
setViews(data.actualViews)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={'bg-white nr-bg'}>
|
||||
<div className={'p-3 font-bold text-lg'}>{item?.title}</div>
|
||||
<div className={'flex justify-between px-3'}>
|
||||
<div className={'flex items-center gap-2 text-sm text-gray-400'}><Eye size={14}/>{views}</div>
|
||||
</div>
|
||||
<View className={'content text-gray-700 text-sm'}>
|
||||
<RichText nodes={item?.content}/>
|
||||
</View>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Item
|
||||
Reference in New Issue
Block a user