品牌列表

main
一杯沧海 1 year ago committed by king
parent d404784233
commit 8aa7beb948
  1. 1
      .env
  2. 1
      .gitignore
  3. 8
      src/api/brand.ts
  4. 1
      src/app.config.ts
  5. 8
      src/app.scss
  6. 4
      src/pages/brand/info/info.config.ts
  7. 31
      src/pages/brand/info/info.module.scss
  8. 57
      src/pages/brand/info/info.tsx
  9. 3
      src/pages/brand/list/components/BrandView.config.ts
  10. 176
      src/pages/brand/list/components/BrandView.tsx
  11. 60
      src/pages/brand/list/list.module.scss
  12. 58
      src/pages/brand/list/list.tsx

@ -1,5 +1,6 @@
TARO_APP_API=https://yjx.dev.yaojiankang.top TARO_APP_API=https://yjx.dev.yaojiankang.top
#TARO_APP_API=https://mooc.yaojiankang.top #TARO_APP_API=https://mooc.yaojiankang.top
#TARO_APP_API=https://shopfix.yaojiankang.top
#TARO_APP_API=https://playedu.yaojiankang.top #TARO_APP_API=https://playedu.yaojiankang.top
TARO_APP_LGOIN=true TARO_APP_LGOIN=true

1
.gitignore vendored

@ -5,3 +5,4 @@ deploy_versions/
node_modules/ node_modules/
.DS_Store .DS_Store
.swc .swc
.env

@ -1,6 +1,7 @@
import {request} from "@/api/request"; import {request} from "@/api/request";
export type BrandRecord = { export type BrandRecord = {
name: string;
id: number id: number
introductory_video: string[] introductory_video: string[]
brand_album: string[] brand_album: string[]
@ -9,14 +10,15 @@ export type BrandRecord = {
} }
export const brandApi = { export const brandApi = {
/** 品牌列表 */
list(page: number , page_size: number) { list(page: number , page_size: number) {
return request<{ return request<{
data: BrandRecord[], data: BrandRecord[],
total: number total: number
}>(`/api/v1/department/index?page=${page}&page_size=${page_size}` , "GET") }>(`/home/v1/brand/list?page=${page}&page_size=${page_size}` , "GET")
}, },
/** 学习记录 */ /** 品牌详情 */
info(id: number) { info(id: number) {
return request<BrandRecord>(`/api/v1/user/record/${id}`, "GET") return request<BrandRecord>(`/home/v1/brand/${id}`, "GET")
}, },
} }

@ -83,6 +83,7 @@ export default defineAppConfig({
root: 'pages/brand', root: 'pages/brand',
pages: [ pages: [
'list/list', 'list/list',
'info/info',
] ]
} }
], ],

@ -325,4 +325,12 @@
.border-none{border: none} .border-none{border: none}
.text-row1 {
display: -webkit-box;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient:vertical;
-webkit-line-clamp:1;
}

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: '',
onReachBottomDistance: 30
})

@ -0,0 +1,31 @@
.box {
display: flex;
margin-bottom: 20rpx;
background-color: #fff;
border-radius: 16rpx;
padding: 24rpx;
box-sizing: border-box;
}
.image{
width: 128rpx;
height:128rpx;
background-color: pink;
border-radius: 8rpx;
}
.rightBox{
padding-left: 24rpx;
box-sizing: border-box;
flex: 1;
}
.desc{
font-size: 24rpx;
font-weight: 500;
color: #909795;
line-height: 34rpx;
display: -webkit-box;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
}

@ -0,0 +1,57 @@
import {FC, useCallback, useEffect, useState} from "react";
import {Image, Swiper, SwiperItem, View} from "@tarojs/components";
import {brandApi, BrandRecord} from "@/api";
import Taro, {useRouter} from "@tarojs/taro";
type Params = {
id: number
}
const MeetingsConfig: FC = () => {
const {id} = useRouter().params as unknown as Params
const [brandInfo, setBrandInfo] = useState<BrandRecord>()
useEffect(() => {
getData()
}, [id])
const getData = async () => {
try {
const data = await brandApi.info(id)
Taro.setNavigationBarTitle({title:data.name})
setBrandInfo(data)
} catch (e) {
}
}
return (
<View className='p-2'>
{
// brands.length ? brands.map((d) =>
// <View onClick={() => jumpInfo(d.id)} className={styles.box} key={d.id}>
// <Image src={d.brand_album?.[0]} mode='aspectFill' className={styles.image}/>
// <View className={styles.rightBox}>
// <View className='font-weight mb-2 font-28'>{d.name}</View>
// <View className={styles.desc}>{d.graphic_introduction.repeat(30)}</View>
// </View>
// </View>)
// : <Empty name='空空如也'/>
<Swiper
className='test-h'
indicatorColor='#999'
indicatorActiveColor='#333'
indicatorDots
>
{ brandInfo?.brand_album?.length
&& brandInfo?.brand_album.map((d) =>
<SwiperItem>
<Image src={d}></Image>
</SwiperItem>)
}
</Swiper>
}
</View>
);
}
export default MeetingsConfig

@ -1,3 +0,0 @@
export default definePageConfig({
navigationBarTitleText: '登记',
})

@ -1,176 +0,0 @@
import {FC, useCallback, useEffect, useState} from "react";
import {Form, Input, View} from "@tarojs/components";
import Taro, {useRouter} from "@tarojs/taro";
import {userApi, loginApi, LoginParams, meetingAPi, Meeting} from "@/api";
import {Profile} from '@/store'
import {regexTel} from "@/utils/regu";
import MyButton from "@/components/button/MyButton";
interface Params {
meeting_id: string
phone_number?: string
user_name?: string
}
const MeetingLogin: FC = () => {
const {setUser, setToken, setCompany} = Profile.useContainer()
const [codeTime, setCodeTime] = useState(0)
const [phone_number, setPhone_number] = useState<number | null>()
const [userName, setUserName] = useState('')
const [code, setCode] = useState('')
const [h5params, setH5Params] = useState<LoginParams | null>(null)
const [meeting, setMeeting] = useState<Meeting | null>(null)
const params = useRouter().params as unknown as Params
useEffect(() => {
loginApi.getMeetingParams().then((res) => {
setH5Params(res)
})
if (params.user_name && params.phone_number) {
setPhone_number(Number(params.phone_number))
setUserName(params.user_name)
Taro.showToast({title: '验证码错误', icon: 'error'})
}
}, [])
useEffect(() => {
if (codeTime > 0) {
setTimeout(() => {
setCodeTime(codeTime - 1)
}, 1000)
}
}, [codeTime])
Taro.useLoad(() => {
meetingAPi.meetingInfo(params.meeting_id).then(res => {
if (res.type !== 1) {
Taro.showModal({
title: res.type === 0 ? '暂未开始' : '二维码已过期',
success() {
Taro.reLaunch({url: '/pages/login/login'})
}
})
return
}
setMeeting(res.data)
})
})
function submit(e) {
const value = e.detail.value
if (!value.user_name) {
Taro.showToast({title: '请写用户名', icon: "error"})
return
}
if (!regexTel.exec(value.phone_number)) {
Taro.showToast({title: '手机号错误', icon: 'error'})
return
}
if (!value.phone_code) {
Taro.showToast({title: '请获取手机验证码', icon: 'error'})
return;
}
if (process.env.TARO_ENV === 'h5') {
if (h5params == null) {
Taro.showToast({title: '页面参数错误,请刷新页面!', icon: 'error'})
return;
}
location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=" + h5params!.appid +
"&redirect_uri=" +
encodeURIComponent(
h5params!.route +
`?dep_id=${meeting?.dep_id}&company_id=${meeting?.companyId}&phone_number=${value.phone_number}&user_name=${value.user_name}&meeting_id=${params.meeting_id}&phone_code=${value.phone_code}`
) +
"&response_type=code" +
"&scope=snsapi_userinfo" +
"#wechat_redirect";
} else {
Taro.login({
success: async (res) => {
const data = await userApi.meetingSave({
...value,
code: res.code,
meeting_id: params.meeting_id
})
setCompany(data.company)
setUser(data.user)
setToken(data.token)
Taro.switchTab({url: '/pages/index/index'})
},
fail: () => {
Taro.showToast({title: '获取微信登录失败', icon: "error"})
}
})
}
}
const getCode = useCallback(async () => {
if (codeTime > 0) return;
if (!phone_number || !regexTel.exec(String(phone_number))) {
Taro.showToast({title: '请输入正确的手机号', icon: 'error'})
return
}
try {
await userApi.getCode(phone_number)
Taro.showToast({title: '请注意查收', icon: "none"})
setCodeTime(60)
} catch (e) {
Taro.showToast({title: '获取短信验证码失败', icon: "error"})
}
}, [codeTime, phone_number])
return (
<View style={{position: 'fixed', top: 0, left: 0, bottom: 0, right: 0, padding: "0 15px", background: '#fff'}}>
<Form className='form' onSubmit={submit}>
<View className='item'>
<View></View>
<Input
placeholder='请输入用户名'
focus
name='user_name'
value={userName}
onInput={(e) => setUserName(e.detail.value)}/>
</View>
<View className='item'>
<View></View>
<Input
type='number'
name='phone_number'
placeholder={'请输入手机号'}
value={phone_number as unknown as string}
onInput={(e) => setPhone_number(Number(e.detail.value))}/>
</View>
<View className='item'>
<View></View>
<View className='flex flex-1'>
<Input
type='number'
name='phone_code'
className='flex-1 mr-2'
value={code}
onInput={(e) => setCode(e.detail.value)}
placeholder='输入验证码'/>
<View onClick={getCode}>
{codeTime > 0 ? `${codeTime}` : '获取验证码'}
</View>
</View>
</View>
<MyButton className='mt-3' formType='submit'></MyButton>
</Form>
</View>
)
}
export default MeetingLogin

@ -1,43 +1,31 @@
.meeting { .box {
display: flex; display: flex;
justify-content: space-between;
margin-bottom: 20rpx; margin-bottom: 20rpx;
background-color: #fff;
border-radius: 16rpx;
padding: 24rpx;
box-sizing: border-box;
} }
.image{
.title { width: 128rpx;
position: relative; height:128rpx;
flex: 1; background-color: pink;
width: 70%; border-radius: 8rpx;
background: #fff; }
padding: 20rpx; .rightBox{
border-radius: 10rpx; padding-left: 24rpx;
overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
flex: 1;
} }
.desc{
font-size: 24rpx;
.overdue { font-weight: 500;
position: absolute; color: #909795;
top: 0; line-height: 34rpx;
bottom: 0; display: -webkit-box;
right: 0; text-overflow: ellipsis;
left: 0; overflow: hidden;
text-align: center; -webkit-box-orient:vertical;
color: #fff; -webkit-line-clamp:2;
display: flex;
justify-content: center;
align-items: center;
background: rgba(#000, .8);
} }
.del {
border-radius: 10rpx;
background: #FF3A2F;
display: flex;
align-items: center;
color: #fff;
width: 100rpx;
justify-content: center;
margin-left: 20rpx;
}

@ -1,11 +1,9 @@
import {FC, useCallback, useEffect, useState} from "react"; import {FC, useCallback, useEffect, useState} from "react";
import {View} from "@tarojs/components"; import {Image, View} from "@tarojs/components";
import {brandApi, BrandRecord, Meeting} from "@/api"; import {brandApi, BrandRecord} from "@/api";
import styles from './list.module.scss' import styles from './list.module.scss'
import Taro, {useReachBottom} from "@tarojs/taro"; import Taro, {useReachBottom} from "@tarojs/taro";
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
import {formatDate} from "@/utils/time";
import brandView from "@/pages/brand/list/components/BrandView";
const MeetingsConfig: FC = () => { const MeetingsConfig: FC = () => {
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
@ -18,38 +16,18 @@ const MeetingsConfig: FC = () => {
const getData = useCallback( async () => { const getData = useCallback( async () => {
try { try {
// const res = await brandApi.list(1, 10) const res = await brandApi.list(1, 10)
// setTotal(res.total) setTotal(res.total)
// setBrands([ setBrands([
// ...res.data ...res.data
// ]) ])
} catch (e) { } catch (e) {
} }
}, [page]) }, [page])
function del(id: number, index: number) {
try {
Taro.showModal({
title: '确定删除',
async success({confirm}) {
if (confirm) {
await meetingAPi.del(id)
const oldMeeting: Meeting[] = JSON.parse(JSON.stringify(brandView))
oldMeeting.splice(index, 1)
setBrands(oldMeeting)
}
}
})
} catch (e) {
}
}
function jumpInfo(item: Meeting) { function jumpInfo(id: number) {
if (Date.now() > item.estimate_end_time || item.status > 0) { Taro.navigateTo({url: `/pages/brand/info/info?id=${id}`})
return
}
Taro.navigateTo({url: `/pages/manage/spotMeeting/spotMeeting?id=${item.id}`})
} }
useReachBottom(useCallback(() => { useReachBottom(useCallback(() => {
@ -62,20 +40,14 @@ const MeetingsConfig: FC = () => {
return ( return (
<View className='p-2'> <View className='p-2'>
{ {
brands.length ? brands.length ? brands.map((d) =>
brands.map((d, index) => <View className={styles.meeting} key={d.id}> <View onClick={() => jumpInfo(d.id)} className={styles.box} key={d.id}>
<View className={styles.title} onClick={() => jumpInfo(d)}> <Image src={d.brand_album?.[0]} mode='aspectFill' className={styles.image}/>
<View className='font-weight mb-1'>{d.name}</View> <View className={styles.rightBox}>
<View>{formatDate(new Date(d.estimate_start_time), "MM-dd")} {formatDate(new Date(d.estimate_start_time), "MM-dd")}</View> <View className='font-weight mb-2 font-28'>{d.name}</View>
{ <View className={styles.desc}>{d.graphic_introduction.repeat(30)}</View>
(Date.now() > d.estimate_end_time || d.status > 1) && <View className={styles.overdue}>
{d.status > 1 ? '已结束' : "已过期"}
</View>
}
</View> </View>
<View className={styles.del} onClick={() => del(d.id, index)}></View>
</View>) </View>)
: <Empty name='空空如也'/> : <Empty name='空空如也'/>
} }

Loading…
Cancel
Save