Compare commits

..

No commits in common. 'c37e360cb68e00a41ea14e55c5b84d01fb9d1f4c' and '68d99f86b17bdee4bbffd60a81c031960f61086c' have entirely different histories.

  1. 2
      src/api/brand.ts
  2. 1
      src/api/manage.ts
  3. 2
      src/app.scss
  4. 11
      src/components/learningRecord/learningRecord.tsx
  5. 25
      src/hooks/storageDep.ts
  6. 32
      src/pages/business/courType/courType.tsx
  7. 1
      src/pages/business/curHistory/curHistory.tsx
  8. 39
      src/pages/business/history/history.tsx
  9. 34
      src/pages/home/components/curRecommended.tsx
  10. 6
      src/pages/home/home.tsx
  11. 28
      src/pages/index/index.tsx
  12. 5
      src/pages/login/login.tsx
  13. 13
      src/pages/manage/courseAdmin/components/search.tsx
  14. 8
      src/pages/manage/courseAdmin/courseAdmin.module.scss
  15. 16
      src/pages/manage/courseAdmin/courseAdmin.tsx
  16. 1
      src/pages/manage/depAdmin/depAdmin.tsx
  17. 53
      src/pages/manage/selectDep/selectDep.tsx
  18. 3
      src/pages/manage/userInfo/userInfo.tsx
  19. 36
      src/pages/preview/brand/article/article.module.scss
  20. 32
      src/pages/preview/brand/article/article.tsx
  21. 13
      src/pages/preview/brand/info/info.tsx
  22. 26
      src/pages/preview/brand/list/list.tsx
  23. 2
      src/pages/preview/health/health.tsx
  24. 43
      src/pages/preview/illness/article/article.module.scss
  25. 22
      src/pages/preview/illness/article/article.tsx
  26. 17
      src/pages/preview/illness/list/list.tsx
  27. 1
      src/pages/preview/illness/sort/sort.module.scss
  28. 14
      src/pages/preview/illness/sort/sort.tsx
  29. 1
      src/pages/preview/profession/profession.tsx
  30. 162
      src/pages/preview/search/search/components/list.tsx
  31. 5
      src/pages/preview/search/search/index.config.ts
  32. 48
      src/pages/preview/search/search/index.module.scss
  33. 164
      src/pages/preview/search/search/index.tsx
  34. BIN
      src/static/img/del.png
  35. 18
      src/utils/time.tsx

@ -11,14 +11,12 @@ export type BrandRecord = {
introductory_video_resource: any introductory_video_resource: any
article_count: number article_count: number
created_at: string created_at: string
page_view:number
} }
export type ArticleRecord = { export type ArticleRecord = {
title: string title: string
page_view: number page_view: number
created_at: string created_at: string
content: string content: string
brands: BrandRecord[]
} }
export const brandApi = { export const brandApi = {

@ -46,6 +46,7 @@ export interface depCurProps {
interface AddCurProps { interface AddCurProps {
course_id: number[] course_id: number[]
dep_id: number[] dep_id: number[]
is_required: (1 | 0)[]
} }

@ -270,7 +270,7 @@
.text-hover-danger { color: #a71d2a;} .text-hover-danger { color: #a71d2a;}
.text-light { color: #f8f9fa;} .text-light { color: #f8f9fa;}
.text-hover-light { color: #cbd3da;} .text-hover-light { color: #cbd3da;}
.text-dark { color: #323635;} .text-dark { color: #343a40;}
.text-hover-dark{ color: #121416;} .text-hover-dark{ color: #121416;}
.text-body { color: #212529;} .text-body { color: #212529;}
.text-muted { color: #909795;} .text-muted { color: #909795;}

@ -5,7 +5,7 @@ import LineChart from "@/components/lineChart/lineChart";
import {CSSProperties, FC, useEffect, useState} from "react"; import {CSSProperties, FC, useEffect, useState} from "react";
import {StatisticsParam, userApi} from "@/api"; import {StatisticsParam, userApi} from "@/api";
import styles from './learningRecord.module.scss' import styles from './learningRecord.module.scss'
// import Spin from "@/components/spinner"; import Spin from "@/components/spinner";
import {Profile} from "@/store"; import {Profile} from "@/store";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
@ -43,19 +43,20 @@ interface Props {
*/ */
const LearningRecord: FC<Props> = ({userId, style, className}) => { const LearningRecord: FC<Props> = ({userId, style, className}) => {
const [lineData, setLineData] = useState<any[]>([]) const [lineData, setLineData] = useState<any[]>([])
// const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const {token} = Profile.useContainer() const {token} = Profile.useContainer()
async function getStatistics(data: StatisticsParam) { async function getStatistics(data: StatisticsParam) {
if (!userId) return;
try { try {
if (!userId) return; setLoading(true)
setLineData([])
const res = await userApi.statistics(userId, data) const res = await userApi.statistics(userId, data)
const everyDayValue = everyDay(data.start_time, Number(data.end_time), res.data) const everyDayValue = everyDay(data.start_time, Number(data.end_time), res.data)
setLineData(everyDayValue) setLineData(everyDayValue)
} catch (e) { } catch (e) {
setLineData([]) setLineData([])
} }
setLoading(false)
} }
function tabChange({tab}: OnChangOpt<StatisticsParam>) { function tabChange({tab}: OnChangOpt<StatisticsParam>) {
@ -73,7 +74,7 @@ const LearningRecord: FC<Props> = ({userId, style, className}) => {
return (<View className={[styles.box, className].filter(Boolean).join(' ')} style={{display: 'block', ...style}}> return (<View className={[styles.box, className].filter(Boolean).join(' ')} style={{display: 'block', ...style}}>
<Tabs tabList={tabList} onChange={tabChange} backMode/> <Tabs tabList={tabList} onChange={tabChange} backMode/>
<View style={{position: "relative"}}> <View style={{position: "relative"}}>
{/*<Spin enable={loading} block/>*/} <Spin enable={loading} block/>
<View className={styles.total}> <View className={styles.total}>
<Text style={{margin: '0 10px', color: '#00D6AC'}}> <Text style={{margin: '0 10px', color: '#00D6AC'}}>

@ -1,12 +1,14 @@
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
const KET = 'SELECT_DEP' const KET = 'SELECT_DEP'
const KET_REQUIRED = 'SELECT_REQUIRED'
/** 部门 */ /** 部门 */
function set(data: number[]) { function set(data: number[]) {
Taro.setStorageSync(KET, data) Taro.setStorageSync(KET, data)
} }
function get(): number[] { function get(): number[] {
const deps = Taro.getStorageSync(KET) const deps = Taro.getStorageSync(KET)
if (deps && deps.length) { if (deps && deps.length) {
@ -21,7 +23,28 @@ function removeDeps() {
Taro.removeStorageSync(KET) Taro.removeStorageSync(KET)
} }
/** 必修选修 */
function removeRequired() {
Taro.removeStorageSync(KET_REQUIRED)
}
function setRequired(data: number[]) {
Taro.setStorageSync(KET_REQUIRED, data)
}
/** getRequired 比 set后调用 */
function getRequired(): (0 | 1)[] {
const deps = Taro.getStorageSync(KET_REQUIRED)
if (deps && deps.length) {
removeRequired()
return deps
}
return []
}
function remove() { function remove() {
removeRequired()
removeDeps() removeDeps()
} }
@ -29,4 +52,6 @@ export default {
set, set,
get, get,
remove, remove,
setRequired,
getRequired
} }

@ -57,27 +57,17 @@ const CourType: FC = () => {
}) })
return ( return (
<> <View className='py-2 flex justify-between flex-wrap '>
{ {data.length > 0 ? data.map(c =>
data.length > 0 ? <VideoCover
<> thumb={c.thumb}
<View className='py-2 flex justify-between flex-wrap'> title={c.title}
{ id={c.id}
data.map(c => <VideoCover depId={c.id}
thumb={c.thumb} key={c.id}
title={c.title} time={formatMinute(c.course_duration)}
id={c.id} />) : <Empty name='暂无数据'/>}
depId={c.id} </View>
key={c.id}
time={formatMinute(c.course_duration)}
/>)
}
</View>
<View className='text-center font-24 text-dark'></View>
</>
: <Empty name='暂无数据'/>
}
</>
) )
} }

@ -106,7 +106,6 @@ const CurHistory = () => {
/> />
</View>) </View>)
} }
<View className='text-center font-24 text-dark mt-3'></View>
</View> </View>
: <Empty name='暂无学习记录'/> : <Empty name='暂无学习记录'/>
} }

@ -1,7 +1,7 @@
import {Text, View} from "@tarojs/components"; import {Text, View} from "@tarojs/components";
import styles from './history.module.scss' import styles from './history.module.scss'
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import React, {useEffect, useState} from "react"; import {useEffect, useState} from "react";
import {formatMinute} from "@/utils/time"; import {formatMinute} from "@/utils/time";
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
import {userApi} from "@/api"; import {userApi} from "@/api";
@ -27,28 +27,21 @@ const History = () => {
return ( return (
<View className='mt-3'> <View className='mt-3'>
{ {data.length ? data.map((d, index) =>
data.length ? <> { <View key={index} className={styles.category} onClick={() => jump(d.userCourseRecord.course_id)}>
data.map((d, index) => <View className={styles.thumb}>
<View key={index} className={styles.category} onClick={() => jump(d.userCourseRecord.course_id)}> <Img src={d.thumb} className={styles.image} width={300} height={188}/>
<View className={styles.thumb}> <View
<Img src={d.thumb} className={styles.image} width={300} height={188}/> className={styles.count}>{d.userCourseRecord.hour_count}/{d.userCourseRecord.finished_count}</View>
<View </View>
className={styles.count}>{d.userCourseRecord.hour_count}/{d.userCourseRecord.finished_count}</View> <View className={styles.text}>
</View> <View>{d.title}</View>
<View className={styles.text}> <View className={styles.describe}>
<View>{d.title}</View> <Text className='mr-4'>{formatMinute(durations[d.id])}</Text>
<View className={styles.describe}> <Text>{(d.userCourseRecord.finished_count / d.userCourseRecord.hour_count * 100).toFixed(0)}%</Text>
<Text className='mr-4'>{formatMinute(durations[d.id])}</Text> </View>
<Text>{(d.userCourseRecord.finished_count / d.userCourseRecord.hour_count * 100).toFixed(0)}%</Text> </View>
</View> </View>) : <Empty name='无观看记录'/>}
</View>
</View>)
}
<View className='text-center font-24 text-dark mt-3'></View>
</>
: <Empty name='无观看记录'/>
}
</View> </View>
) )
} }

@ -1,28 +1,12 @@
import {FC, ReactNode, useEffect, useState} from "react"; import {FC, ReactNode, useEffect, useState} from "react";
import {Image, View} from "@tarojs/components"; import {Image, View} from "@tarojs/components";
import {HomeApi} from "@/api"; import {HomeApi} from "@/api";
import Taro, {useReachBottom} from "@tarojs/taro"; import {useReachBottom} from "@tarojs/taro";
import styles from "../home.module.scss"; import styles from "../home.module.scss";
import VideoCover from "@/components/videoCover/videoCover"; import VideoCover from "@/components/videoCover/videoCover";
import courseTag from '@/static/img/courseTag.png' import courseTag from '@/static/img/courseTag.png'
import {rfc33392time} from "@/utils/day";
import Img from "@/components/image/image"; import Img from "@/components/image/image";
import {beforeTime} from "@/utils/time";
const toArticlePage = (d: any) => {
console.log({d})
switch (d.owner_type) {
case 1:
Taro.navigateTo({
url: `/pages/preview/brand/article/article?id=${d.id}`
})
return
case 2:
Taro.navigateTo({
url: `/pages/preview/illness/article/article?id=${d.id}`
})
return
}
}
const CurRecommended: FC = () => { const CurRecommended: FC = () => {
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
@ -60,15 +44,15 @@ const CurRecommended: FC = () => {
<View className="mb-5"> <View className="mb-5">
<View className='text-center my-2'></View> <View className='text-center my-2'></View>
<View className='bg-white rounded-20 clip'> <View className='bg-white rounded-20 clip'>
{articles.map((d, i) => <View className='p-3 relative' onClick={() => toArticlePage(d)}> {articles.map((d, i) => <View className='p-3 relative'>
{i > 0 && <View className='absolute top left right divided ml-3 mr-3'/>} {i > 0 && <View className='absolute top left right divided ml-3 mr-3' />}
<View className="font-34 text-black">{d.title}</View> <View className="font-34 bold text-black">{d.title}</View>
{(d.intro || '').length > 40 && (<View className='flex mt-1'> {(d.intro || '').length > 40 && (<View className='flex mt-1'>
<View className="flex-1 font-24 lh1_5">{d.intro}</View> <View className="flex-1 font-24 lh1_5">{d.intro}</View>
{d.cover && <Img className='ml-l' width={140} height={100} src={d.cover} errorType="acquiesce"/>} {d.cover && <Img className='ml-l' width={140} height={100} src={d.cover} errorType="acquiesce" />}
</View>)} </View>)}
<View className="flex mt-3 justify-between font-24 text-muted"> <View className="flex mt-3 justify-between font-24 text-muted">
<View>{beforeTime(d.created_at)}</View> <View>{rfc33392time(d.created_at).split(' ')[0]}</View>
<View> {d.page_view || 0}</View> <View> {d.page_view || 0}</View>
</View> </View>
</View>)} </View>)}
@ -102,7 +86,7 @@ const CurRecommended: FC = () => {
<> <>
{examines} {examines}
{videos} {videos}
<View className='text-center font-24 text-dark'></View> <View className='text-center text-muted font-28'>- -</View>
</> </>
) )
} }

@ -1,4 +1,4 @@
import {FC, useState} from "react"; import {FC, useEffect, useState} from "react";
import {Image, View, Text} from "@tarojs/components"; import {Image, View, Text} from "@tarojs/components";
import styles from "./home.module.scss"; import styles from "./home.module.scss";
import Adware from "@/pages/home/components/adware"; import Adware from "@/pages/home/components/adware";
@ -27,14 +27,14 @@ const Home: FC = () => {
Taro.navigateTo({url: '/pages/login/login'}) Taro.navigateTo({url: '/pages/login/login'})
} }
Taro.useDidShow(() => { useEffect(() => {
HomeApi.home().then(res => { HomeApi.home().then(res => {
setData(res) setData(res)
}) })
setTimeout(() => { setTimeout(() => {
setEnable(false) setEnable(false)
}, 600) }, 600)
}) }, [])
Taro.usePageScroll((e) => { Taro.usePageScroll((e) => {
const v = (Math.min(e.scrollTop / navbarHeight, 1) * 0.9).toFixed(6) const v = (Math.min(e.scrollTop / navbarHeight, 1) * 0.9).toFixed(6)

@ -5,9 +5,7 @@ import {VideoList} from "@/pages/index/components/videoList";
import Tabs, {OnChangOpt, TabList} from "@/components/tabs/tabs"; import Tabs, {OnChangOpt, TabList} from "@/components/tabs/tabs";
import {CoursesKey, publicApi} from "@/api/public"; import {CoursesKey, publicApi} from "@/api/public";
import NavigationBar from "@/components/navigationBar/navigationBar"; import NavigationBar from "@/components/navigationBar/navigationBar";
import Spin from "@/components/spinner"; // import Taro from "@tarojs/taro";
import Img from "@/components/image/image";
import {beforeTime} from "@/utils/time";
const category: TabList[] = [ const category: TabList[] = [
{title: "企选课程", value: 'is_required'}, {title: "企选课程", value: 'is_required'},
@ -39,38 +37,26 @@ const Index: FC = () => {
const AuditMode: FC = () => { const AuditMode: FC = () => {
const [auditMode, setAuditMode] = useState(false) const [auditMode, setAuditMode] = useState(false)
const [articles, setArticles] = useState<any[]>([]) const [articles, setArticles] = useState<any[]>([])
const [enable, setEnable] = useState(true)
useEffect(() => { useEffect(() => {
publicApi.course({page: 1, pageSize: 10}).then(res => { publicApi.course({page: 1, pageSize: 10}).then(res => {
setAuditMode(res.audit_mode) setAuditMode(res.audit_mode)
setArticles(res.articles) setArticles(res.articles)
setEnable(false) // if(res.audit_mode){
// Taro.setTabBarItem({index: 1, text: '文章'})
// }
}) })
}, []) }, [])
return ( return (
<> <>
<Spin enable={enable} overlay/>
{ {
auditMode ? auditMode ?
<> <>
<NavigationBar text='文章列表' cancelBack/> <NavigationBar text='文章' cancelBack/>
<View className='bg-white rounded-20 clip'> <View className='p-2'>
{ {
articles.map((d, i) => <View className='p-3 relative'> articles.map(d => <View className='mb-2 p-2 bg-white'>{d.title}</View>)
{i > 0 && <View className='absolute top left right divided ml-3 mr-3'/>}
<View className="font-34 bold text-black">{d.title}</View>
{(d.intro || '').length > 40 && (<View className='flex mt-1'>
<View className="flex-1 font-24 lh1_5">{d.intro}</View>
{d.cover && <Img className='ml-l' width={140} height={100} src={d.cover} errorType="acquiesce"/>}
</View>)}
<View className="flex mt-3 justify-between font-24 text-muted">
<View>{beforeTime(d.created_at)}</View>
<View> {d.page_view || 0}</View>
</View>
</View>)
} }
</View> </View>
<View className='text-center font-24 text-dark mt-2'></View>
</> </>
: <Index/> : <Index/>
} }

@ -57,8 +57,10 @@ const Login: FC = () => {
setToken(token) setToken(token)
setCompany(company) setCompany(company)
setLoading(false) setLoading(false)
Taro.navigateBack() Taro.switchTab({url: '/pages/home/home'})
} else { } else {
Taro.setStorageSync('openid', catch_key) Taro.setStorageSync('openid', catch_key)
Taro.reLaunch({url: '/pages/check/check'}) Taro.reLaunch({url: '/pages/check/check'})
} }
@ -96,6 +98,7 @@ const Login: FC = () => {
<View style={{flex: 1}}>{error}</View> <View style={{flex: 1}}>{error}</View>
<Icon name={'close'} onClick={() => setError(null)}/> <Icon name={'close'} onClick={() => setError(null)}/>
</View> : null} </View> : null}
{/*{process.env.TARO_APP_LGOIN === 'true' && <MyButton onClick={TESTLOGIN}>线下登录</MyButton>}*/} {/*{process.env.TARO_APP_LGOIN === 'true' && <MyButton onClick={TESTLOGIN}>线下登录</MyButton>}*/}
</View> </View>
) )

@ -17,7 +17,6 @@ export const Search: FC<Props> = ({param, setParam}) => {
const [show, setShow] = useState(false) const [show, setShow] = useState(false)
const [deps, setDeps] = useState<Manage[]>([]) const [deps, setDeps] = useState<Manage[]>([])
const [depId, setDepId] = useState<number>(param.dep_id) const [depId, setDepId] = useState<number>(param.dep_id)
const [title, setTitle] = useState(param.title)
async function getDepList() { async function getDepList() {
try { try {
@ -54,21 +53,19 @@ export const Search: FC<Props> = ({param, setParam}) => {
<> <>
<View className={styles.searchBox}> <View className={styles.searchBox}>
<View className={styles.searchInput}> <View className={styles.searchInput}>
<Icon name='search' size={18} color='#909795'/> <Icon name='search' size={18}/>
<Input <Input
adjustPosition={false} adjustPosition={false}
type='text' type='text'
confirmType='search' confirmType='search'
placeholder='搜索课程名称' placeholder='搜索名称'
className='ml-1 flex-1' className='ml-1 flex-1'
value={title} value={param.title}
onInput={(e) => setTitle(e.detail.value)}
onConfirm={(e) => setParam({ onConfirm={(e) => setParam({
...param, ...param,
title: e.detail.value, title: e.detail.value,
page: 1 page: 1
})} })}/>
/>
</View> </View>
<View onClick={() => setShow(true)}> <View onClick={() => setShow(true)}>
<Text></Text> <Text></Text>
@ -102,7 +99,7 @@ export const Search: FC<Props> = ({param, setParam}) => {
</View>) </View>)
} }
<View className='flex justify-around mt-2 align-center'> <View className='flex justify-around mt-2'>
<View onClick={() => setShow(false)}> <View onClick={() => setShow(false)}>
<MyButton type='default' fillet width={150}></MyButton> <MyButton type='default' fillet width={150}></MyButton>
</View> </View>

@ -3,9 +3,6 @@
padding: 24rpx 30rpx; padding: 24rpx 30rpx;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
position: sticky;
top: 0;
border-bottom: 1px solid #F5F8F7;
} }
.searchInput { .searchInput {
@ -16,6 +13,7 @@
padding-left: 24rpx; padding-left: 24rpx;
background: #F5F8F7; background: #F5F8F7;
border-radius: 32rpx; border-radius: 32rpx;
color: #909795;
overflow: hidden; overflow: hidden;
} }
@ -67,7 +65,7 @@
} }
.curList { .curList {
padding-bottom: calc(env(safe-area-inset-bottom) + 63rpx); padding-bottom: 100px;
} }
.add { .add {
@ -85,6 +83,4 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 30rpx; padding: 30rpx;
align-items: center;
box-sizing: border-box;
} }

@ -124,12 +124,13 @@ const CourseAdmin: FC = () => {
Taro.useDidShow(useCallback(async () => { Taro.useDidShow(useCallback(async () => {
const dep_id = storageDep.get() const dep_id = storageDep.get()
const is_required = storageDep.getRequired()
if (!dep_id.length || !curs.length) return; if (!dep_id.length || !is_required.length || !curs.length) return;
try { try {
await ManageApi.addCur({course_id: curs, dep_id}) await ManageApi.addCur({course_id: curs, dep_id, is_required})
Taro.showToast({title: '修改成功'}) Taro.showToast({title: '修改成功'})
// deps 中没有 筛选条件中的depid 删除已选的课程 // deps 中没有 筛选条件中的depid 删除已选的课程
if (param.dep_id && dep_id.includes(param.dep_id)) { if (param.dep_id && dep_id.includes(param.dep_id)) {
@ -150,15 +151,15 @@ const CourseAdmin: FC = () => {
return ( return (
<> <View>
<Search param={param} setParam={setParam}/>
<Spin enable={enable} overlay/> <Spin enable={enable} overlay/>
<Search param={param} setParam={setParam}/>
<View className={styles.curList}> <View className={styles.curList}>
{ {
data?.map((d, index) => <View key={d.id} className={styles.curBox}> data?.map((d, index) => <View key={d.id} className={styles.curBox}>
<View className={styles.curTitle} onClick={() => addCurs(d.id)}> <View className={styles.curTitle} onClick={() => addCurs(d.id)}>
{batch && <Radio {batch && <Radio
color='#45D4A8'
checked={curs.includes(d.id)} checked={curs.includes(d.id)}
style={{marginTop: '30px'}} style={{marginTop: '30px'}}
onClick={() => addCurs(d.id)}/>} onClick={() => addCurs(d.id)}/>}
@ -171,7 +172,6 @@ const CourseAdmin: FC = () => {
</View> </View>
</View>) </View>)
} }
<View className='text-center font-24 text-dark mt-3'></View>
</View> </View>
<View className={styles.add}> <View className={styles.add}>
@ -182,13 +182,13 @@ const CourseAdmin: FC = () => {
} }
{ {
batch && <View className={styles.addBatch}> batch && <View className={styles.addBatch}>
<Radio onClick={all} checked={data.length === curs.length} color='#45D4A8'> </Radio> <Radio onClick={all} checked={data.length === curs.length}> </Radio>
<Text onClick={() => setBatch(false)}></Text> <Text onClick={() => setBatch(false)}></Text>
<MyButton size='mini' onClick={() => batchChangDep(curs)}>{curs.length}</MyButton> <MyButton size='mini' onClick={() => batchChangDep(curs)}>{curs.length}</MyButton>
</View> </View>
} }
</View> </View>
</> </View>
) )
} }

@ -158,7 +158,6 @@ const DepAdmin: FC = () => {
onClick={() => Taro.navigateTo({url: '/pages/manage/userInfo/userInfo?userId=' + d.id})} onClick={() => Taro.navigateTo({url: '/pages/manage/userInfo/userInfo?userId=' + d.id})}
content={['学员', '管理员', '超级管理员'][d.role_type]} content={['学员', '管理员', '超级管理员'][d.role_type]}
/>)} />)}
<View className='text-center font-24 text-dark mt-3'></View>
{!manages.length && !users.length && <Empty name='暂无数据'/>} {!manages.length && !users.length && <Empty name='暂无数据'/>}

@ -1,5 +1,5 @@
import React, {FC, useCallback, useEffect, useState} from "react"; import React, {FC, useCallback, useEffect, useState} from "react";
import {Checkbox, View} from "@tarojs/components"; import {Checkbox, Switch, View} from "@tarojs/components";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import {curriculum} from "@/api"; import {curriculum} from "@/api";
import PopPut from "@/components/popPut/popPut"; import PopPut from "@/components/popPut/popPut";
@ -13,9 +13,10 @@ import Spin from "@/components/spinner";
* required * required
*/ */
const SelectDep: FC = () => { const SelectDep: FC = () => {
const params = Taro.getCurrentInstance()?.router?.params as { depIds: string} const params = Taro.getCurrentInstance()?.router?.params as { depIds: string, required: string | undefined }
const [ids, setIds] = useState<number[]>([]) const [ids, setIds] = useState<number[]>([])
const [deps, setDeps] = useState<Manage[]>([]) const [deps, setDeps] = useState<Manage[]>([])
const [required, setRequired] = useState<number[]>([])
const [enable, setEnable] = useState(true) const [enable, setEnable] = useState(true)
useEffect(() => { useEffect(() => {
@ -24,6 +25,7 @@ const SelectDep: FC = () => {
}) })
setEnable(false) setEnable(false)
setIds(JSON.parse(params.depIds)) setIds(JSON.parse(params.depIds))
setRequired(JSON.parse(params.required || "[]"))
}, []) }, [])
const onChange = useCallback((id: number) => { const onChange = useCallback((id: number) => {
@ -33,19 +35,51 @@ const SelectDep: FC = () => {
...ids, ...ids,
id id
]) ])
if (params.required) {
setRequired([...required, 0])
}
} else { } else {
const oldIds: number[] = JSON.parse(JSON.stringify(ids)) const oldIds: number[] = JSON.parse(JSON.stringify(ids))
oldIds.splice(index, 1) oldIds.splice(index, 1)
setIds(oldIds) setIds(oldIds)
if (params.required) {
const oldRequired: number[] = JSON.parse(JSON.stringify(required))
oldRequired.splice(index, 1)
setRequired(oldRequired)
}
} }
}, [ids]) }, [ids])
function ok() { function ok() {
storageDep.set(ids) storageDep.set(ids)
storageDep.setRequired(required)
Taro.navigateBack({delta: 1}) Taro.navigateBack({delta: 1})
} }
function isRequired(dep_id: number): boolean {
const index = ids.indexOf(dep_id)
if (index === -1) {
return false
} else {
return !!required?.[index]
}
}
function requiredChange(dep_id: number, value: boolean) {
const index = ids.indexOf(dep_id)
if (index === -1) {
setIds([...ids, dep_id])
setRequired([...required, value ? 1 : 0])
} else {
const oldRequired: number[] = JSON.parse(JSON.stringify(required))
oldRequired.splice(index, 1, value ? 1 : 0)
setRequired(oldRequired)
}
}
return ( return (
<View className='px-2 bg-white'> <View className='px-2 bg-white'>
<Spin overlay enable={enable}/> <Spin overlay enable={enable}/>
@ -56,10 +90,21 @@ const SelectDep: FC = () => {
key={d.id} key={d.id}
title={d.name} title={d.name}
chevron chevron
leftImage={folder}/> leftImage={folder}
content={
params?.required ?
<View className='flex align-center'>
<Switch
color='#45d4a8'
onClick={() => event?.stopImmediatePropagation()}
checked={isRequired(d.id)}
onChange={(e) => requiredChange(d.id, e.detail.value)}/>
</View>
: null
}
/>
</View> </View>
</View>)} </View>)}
<View className='text-center font-24 text-dark mt-3'></View>
<View className={'my-3'}> <View className={'my-3'}>
<MyButton onClick={ok}></MyButton> <MyButton onClick={ok}></MyButton>

@ -58,6 +58,7 @@ const UserInfo: FC = () => {
useEffect(() => { useEffect(() => {
userApi.info(userId).then(res => { userApi.info(userId).then(res => {
setData(res) setData(res)
}) })
@ -75,7 +76,7 @@ const UserInfo: FC = () => {
<View className={styles.page}> <View className={styles.page}>
<Info data={data}/> <Info data={data}/>
<LearningRecord userId={userId} style={{padding: '20px'}}/> <LearningRecord userId={userId}/>
<View className='mt-2'> <View className='mt-2'>

@ -1,33 +1,30 @@
.fixedBox { .fixedBox{
position: fixed; position: fixed;
z-index: 1000; z-index: 1000;
top: 0; top:0;
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1), rgba(255, 255, 255, 1)); background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1), rgba(255, 255, 255, 1));
&-inner{
&-inner {
position: absolute; position: absolute;
width: 100vw; width: 100vw;
top: 45vh; top:45vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
&-icon{
&-icon { image{
image {
width: 32rpx; width: 32rpx;
height: 32rpx; height: 32rpx;
} }
} }
&-box{
&-box {
margin-top: 24rpx; margin-top: 24rpx;
width: 680rpx; width: 680rpx;
left: 35rpx; left:35rpx;
height: 76rpx; height: 76rpx;
background-color: #45D4A8; background-color: #45D4A8;
color: #fff; color:#fff;
line-height: 76rpx; line-height: 76rpx;
text-align: center; text-align: center;
font-size: 32rpx; font-size: 32rpx;
@ -37,18 +34,3 @@
} }
} }
.article {
font-size: 30rpx;
display: flex;
margin-bottom: 40rpx;
}
.articleImag {
border-radius: 100rpx;
}
.articleTitle {
font-size: 40rpx;
margin-bottom: 50rpx;
}

@ -2,14 +2,12 @@ import {FC, useCallback, useEffect, useMemo, useState} from "react";
import {Image, Text, View} from "@tarojs/components"; import {Image, Text, View} from "@tarojs/components";
import Taro, {useRouter} from "@tarojs/taro"; import Taro, {useRouter} from "@tarojs/taro";
import {ArticleRecord, brandApi} from "@/api"; import {ArticleRecord, brandApi} from "@/api";
import styles from "./article.module.scss"; import styles from "@/pages/preview/illness/article/article.module.scss";
import down from "@/static/img/doubleDown.png"; import down from "@/static/img/doubleDown.png";
import {Profile} from "@/store"; import {Profile} from "@/store";
import {parse} from "@/utils/marked/marked"; import {parse} from "@/utils/marked/marked";
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
import Spin from "@/components/spinner"; import Spin from "@/components/spinner";
import {beforeTime} from "@/utils/time";
import Img from "@/components/image/image";
const article: FC = () => { const article: FC = () => {
@ -27,8 +25,8 @@ const article: FC = () => {
const query = Taro.createSelectorQuery() const query = Taro.createSelectorQuery()
query.select('#childrenNode').boundingClientRect((res) => { query.select('#childrenNode').boundingClientRect((res) => {
if (!Array.isArray(res)) { if (!Array.isArray(res)) {
console.log({childrenNode: res}) console.log({childrenNode: res})
setUltra(pageHeight * .45 <= res.height) setUltra(pageHeight * .45 <= res.height)
} }
}).exec() }).exec()
}, 300) }, 300)
@ -61,25 +59,8 @@ const article: FC = () => {
overflow: !token ? 'hidden' : 'auto' overflow: !token ? 'hidden' : 'auto'
}}> }}>
<View id="childrenNode"> <View id="childrenNode">
<View className={styles.articleTitle}>{articleInfo?.title}</View>
{ {
children.length > 0 ? children.length > 0 ? children : <Empty name='暂无数据'/>
<View>
{
articleInfo?.brands.map(d => <View className={styles.article}>
<Img src={d.logo} width={80} height={80} className={styles.articleImag}/>
<View className='ml-2'>
<View>{d?.name}</View>
<View className='flex mt-1 text-muted font-24'>
<View className='mr-2'>{beforeTime(articleInfo?.created_at)} . </View>
<View> {articleInfo.page_view || 1}</View>
</View>
</View>
</View>)
}
{children}
</View>
: <Empty name='暂无数据'/>
} }
</View> </View>
</View> </View>
@ -90,8 +71,9 @@ const article: FC = () => {
<View className={styles['fixedBox-inner-icon']}> <View className={styles['fixedBox-inner-icon']}>
<Image src={down}/> <Image src={down}/>
</View> </View>
<View className={styles['fixedBox-inner-box']} <View className={styles['fixedBox-inner-box']} onClick={() => {
onClick={() => Taro.navigateTo({url: '/pages/login/login'})}> Taro.navigateTo({url: '/pages/login/login'})
}}>
<Text></Text> <Text></Text>
</View> </View>
</View> </View>

@ -113,9 +113,11 @@ const BrandInfo: FC = () => {
</View> </View>
<View className={styles['bottom']}> <View className={styles['bottom']}>
{ {
articleList?.length ? <>{ articleList?.length ?
articleList.map((i: any) => <View className={styles.box} articleList.map((i: any) =>
onClick={() => Taro.navigateTo({url: `/pages/preview/brand/article/article?id=${i.id}`})}> <View className={styles.box} onClick={() => {
Taro.navigateTo({url: `/pages/preview/brand/article/article?id=${i.id}`})
}}>
<View className={styles.inner}> <View className={styles.inner}>
<View className={styles.leftBox}> <View className={styles.leftBox}>
<View className='font-weight mb-2 font-28 lh-40'>{i.title}</View> <View className='font-weight mb-2 font-28 lh-40'>{i.title}</View>
@ -125,9 +127,8 @@ const BrandInfo: FC = () => {
<Img width={172} height={128} src={i.cover}/> <Img width={172} height={128} src={i.cover}/>
</View> </View>
</View> </View>
</View>)} </View>
<View className='text-center font-24 text-dark'></View> )
</>
: <Empty name='空空如也'/> : <Empty name='空空如也'/>
} }
</View> </View>

@ -5,7 +5,7 @@ import Taro, {useReachBottom} from "@tarojs/taro";
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
import Spinner from "@/components/spinner"; import Spinner from "@/components/spinner";
import Img from "@/components/image/image"; import Img from "@/components/image/image";
import {beforeTime} from "@/utils/time"; import {formatDate} from "@/utils/time";
const BrandItem: FC<{ data: BrandRecord; onClick: VoidFunction }> = ({data, onClick}) => { const BrandItem: FC<{ data: BrandRecord; onClick: VoidFunction }> = ({data, onClick}) => {
let media: ReactNode let media: ReactNode
@ -16,7 +16,7 @@ const BrandItem: FC<{ data: BrandRecord; onClick: VoidFunction }> = ({data, onCl
/> />
} else if (data.brand_album) { } else if (data.brand_album) {
media = <Img media = <Img
// width={712} width={712}
height={320} height={320}
src={data.brand_album.split(",")[0]} src={data.brand_album.split(",")[0]}
mode="aspectFill" mode="aspectFill"
@ -27,32 +27,26 @@ const BrandItem: FC<{ data: BrandRecord; onClick: VoidFunction }> = ({data, onCl
return ( return (
<View className="bg-white flex flex-column justify-stretch mb-2_4 rounded-10 clip"> <View className="bg-white flex flex-column justify-stretch mb-2_4 rounded-10 clip">
{media}
<View className="p-3" onClick={onClick}> <View className="p-3" onClick={onClick}>
<View className='mb-2 font-32 flex'> <View className='font-weight mb-2 font-32 flex align-center'>
<Img <Img
width={76} width={32}
height={76} height={32}
src={data.logo} src={data.logo}
mode='aspectFill' mode='aspectFill'
errorType='avatar'
className="rounded-10 clip" className="rounded-10 clip"
style={{background: '#ededed'}} style={{background: '#ededed'}}
/> />
<View className="ml-2 flex-1"> <View className="ml-1 flex-1">
<View className="text-row1 font-28">{data.name}</View> <View className="text-row1 font-28">{data.name}</View>
<View className='font-24 mt-1 text-dark'>{beforeTime(data.created_at)}·</View>
</View> </View>
</View> </View>
<View className="font-24 text-muted mb-4 text-row3" style={{lineHeight: 1.4}}>
<View>
{media}
</View>
<View className="font-24 text-muted mb-4 text-row3 mt-2" style={{lineHeight: 1.4}}>
{data.graphic_introduction} {data.graphic_introduction}
</View> </View>
<View className="flex gap20rpx font-24 text-muted"> <View className="flex gap20rpx font-24 text-muted">
<View>{formatDate(new Date(data.created_at), "YY-MM-dd hh:mm:ss")}</View>
<View className="flex-1"></View> <View className="flex-1"></View>
<View>{data.article_count || 0}</View> <View>{data.article_count || 0}</View>
<View>{(Math.random() * 100).toFixed(0)}</View> <View>{(Math.random() * 100).toFixed(0)}</View>
@ -111,7 +105,7 @@ const BrandList: FC = () => {
content = ( content = (
<> <>
{brands.map(d => <BrandItem data={d} key={d.id} onClick={() => jumpInfo(d.id)}/>)} {brands.map(d => <BrandItem data={d} key={d.id} onClick={() => jumpInfo(d.id)}/>)}
<View className='text-center font-24 text-dark mt-3'>{text}</View> <View style={{width: '710rpx', textAlign: 'center', color: '#999'}} className="font-28 mt-3">{text}</View>
</> </>
) )
} else { } else {

@ -55,7 +55,7 @@ const Health: FC = () => {
</View> </View>
</View>)} </View>)}
</View> </View>
<View className='text-center font-24 text-dark mt-2'></View> <View className="font-28 mt-3 text-center text-muted"></View>
</> </>
: <Empty name='暂无数据'/> : <Empty name='暂无数据'/>
} }

@ -1,4 +1,4 @@
.botmBox { .botmBox{
z-index: 99; z-index: 99;
position: fixed; position: fixed;
bottom: 0; bottom: 0;
@ -10,8 +10,7 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background: #F5F8F7; background: #F5F8F7;
view{
view {
width: 560rpx; width: 560rpx;
height: 76rpx; height: 76rpx;
background: #45D4A8; background: #45D4A8;
@ -23,37 +22,33 @@
line-height: 76rpx; line-height: 76rpx;
} }
} }
.fixedBox{
.fixedBox {
position: fixed; position: fixed;
z-index: 100; z-index: 100;
top: 0; top:0;
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1), rgba(255, 255, 255, 1)); background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1), rgba(255, 255, 255, 1));
&-inner{
&-inner {
position: absolute; position: absolute;
width: 100vw; width: 100vw;
top: 45vh; top:45vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
&-icon{
&-icon { image{
image {
width: 32rpx; width: 32rpx;
height: 32rpx; height: 32rpx;
} }
} }
&-box{
&-box {
margin-top: 24rpx; margin-top: 24rpx;
width: 680rpx; width: 680rpx;
left: 35rpx; left:35rpx;
height: 76rpx; height: 76rpx;
background-color: #45D4A8; background-color: #45D4A8;
color: #fff; color:#fff;
line-height: 76rpx; line-height: 76rpx;
text-align: center; text-align: center;
font-size: 32rpx; font-size: 32rpx;
@ -63,19 +58,3 @@
} }
} }
.article {
font-size: 30rpx;
display: flex;
margin-bottom: 40rpx;
}
.articleImag {
border-radius: 100rpx;
}
.articleTitle {
font-size: 40rpx;
margin-bottom: 50rpx;
}

@ -6,8 +6,7 @@ import styles from './article.module.scss'
import down from '@/static/img/doubleDown.png' import down from '@/static/img/doubleDown.png'
import {Profile} from "@/store"; import {Profile} from "@/store";
import {parse} from "@/utils/marked/marked"; import {parse} from "@/utils/marked/marked";
import {beforeTime} from "@/utils/time"; import {formatDate} from "@/utils/time";
import Img from "@/components/image/image";
const article: FC = () => { const article: FC = () => {
const {token} = Profile.useContainer() const {token} = Profile.useContainer()
@ -59,20 +58,9 @@ const article: FC = () => {
height: !token ? Taro.getWindowInfo().windowHeight - 60 + 'px' : 'auto', height: !token ? Taro.getWindowInfo().windowHeight - 60 + 'px' : 'auto',
overflow: !token ? 'hidden' : 'auto' overflow: !token ? 'hidden' : 'auto'
}}> }}>
<View> <View className='text-center'>
<View className={styles.articleTitle}>{articleInfo?.title}</View> <View className='font-50 font-weight '>{articleInfo?.title}</View>
{ <View className='mt-2'>{formatDate(new Date(articleInfo?.created_at || 0), "YY-mm-dd hh:mm:dd")}</View>
articleInfo?.brands.map(d => <View className={styles.article}>
<Img src={d.logo} width={80} height={80} className={styles.articleImag} errorType="avatar"/>
<View className='ml-2'>
<View>{d?.name}</View>
<View className='flex mt-1 text-muted font-24'>
<View className='mr-2'>{beforeTime(articleInfo?.created_at)} . </View>
<View> {articleInfo.page_view || 1}</View>
</View>
</View>
</View>)
}
</View> </View>
<View></View> <View></View>
{children} {children}
@ -105,9 +93,11 @@ const article: FC = () => {
} }
</View> </View>
</PageContainer> </PageContainer>
</> </>
) )
} }
return helloWorld() return helloWorld()
} }
export default article export default article

@ -50,16 +50,13 @@ const BrandList: FC = () => {
<Spin enable={enable} overlay/> <Spin enable={enable} overlay/>
{ {
articles.length > 0 ? articles.length > 0 ?
<> <View className='bg-white'>
<View className='bg-white'> {
{ articles.map((d, index) => <View key={d.id} className={styles.articles} onClick={() => jump(d.id)}>
articles.map((d, index) => <View key={d.id} className={styles.articles} onClick={() => jump(d.id)}> {index + 1} . {d.title}
{index + 1} . {d.title} </View>)
</View>) }
} </View>
</View>
<View className='text-center font-24 text-dark mt-3'></View>
</>
: <Empty name='暂无文章'/> : <Empty name='暂无文章'/>
} }
</View> </View>

@ -58,7 +58,6 @@
font-family: PingFang SC-Bold, PingFang SC; font-family: PingFang SC-Bold, PingFang SC;
font-weight: bold; font-weight: bold;
color: #323635; color: #323635;
position: relative;
} }
.list { .list {

@ -96,14 +96,14 @@ const Sort: FC = () => {
scrollY scrollY
className={styles.tree} className={styles.tree}
scrollWithAnimation> scrollWithAnimation>
<Spin enable={loading} block/>
{ {
list.length ? loading ? <Spin enable={loading}/> : <>
<> {
{list.map(d => <View className={styles.list} onClick={() => jump(d.id)}>{d.name}</View>)} list.length ?
<View className='text-center font-24 text-dark mt-3'></View> list.map(d => <View className={styles.list} onClick={() => jump(d.id)}>{d.name}</View>)
</> : <Empty name='暂无数据'/>
: <Empty name='暂无数据'/> }
</>
} }
</ScrollView> </ScrollView>
</View> </View>

@ -104,7 +104,6 @@ const Profession = () => {
</View> </View>
) )
} }
<View className='text-center font-24 text-dark mt-2'></View>
</ScrollView> </ScrollView>
) )
} }

@ -4,16 +4,17 @@ import styles from './list.module.scss'
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
import Img from "@/components/image/image"; import Img from "@/components/image/image";
import {SearchApi} from "@/api/search"; import { SearchApi } from "@/api/search";
import {AtLoadMore} from 'taro-ui' import { AtLoadMore } from 'taro-ui'
import {rfc33392time} from "@/utils/day"; import {rfc33392time} from "@/utils/day";
import play from "@/static/img/play.png"; import play from "@/static/img/play.png";
type Props = { type Props = {
name: string name:string
clear: boolean clear:boolean
} }
const SearchList: FC<Props> = ({name, clear}) => { const SearchList: FC<Props> = ({name,clear}) => {
console.log(name,'name')
const globalData = Taro.getApp().globalData const globalData = Taro.getApp().globalData
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
const [brands, setBrands] = useState<any[]>([]) const [brands, setBrands] = useState<any[]>([])
@ -21,21 +22,21 @@ const SearchList: FC<Props> = ({name, clear}) => {
const [text, setText] = useState('') const [text, setText] = useState('')
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
useEffect(() => { useEffect(()=>{
if (!clear) { if(!clear){
setBrands([]) setBrands([])
setLoading(true) setLoading(true)
} }
}, [clear]) },[clear])
useEffect(() => { useEffect(() => {
if (name && clear) { if(name && clear){
getData() getData()
} }
}, [page, name, clear]) }, [page,name,clear])
const getData = useCallback(async () => { const getData = useCallback(async () => {
try { try {
const data = await SearchApi.list(page, 10, name) const data = await SearchApi.list(page, 10,name)
if (page === 1) { if (page === 1) {
if (data.data.length < 10) { if (data.data.length < 10) {
setText('没有更多了~') setText('没有更多了~')
@ -45,7 +46,7 @@ const SearchList: FC<Props> = ({name, clear}) => {
setBrands([ setBrands([
...data.data ...data.data
]) ])
} else { }else{
setBrands([ setBrands([
...brands, ...brands,
...data.data ...data.data
@ -56,13 +57,13 @@ const SearchList: FC<Props> = ({name, clear}) => {
} catch (e) { } catch (e) {
} }
setLoading(false) setLoading(false)
}, [page, name]) }, [page,name])
function jumpInfo(id: number, type: string, health: any) { function jumpInfo(id: number,type:string,health:any) {
console.log(type, 'type') console.log(type,'type')
let url = '' let url = ''
switch (type) { switch (type){
case 'brand': case 'brand':
url = '/pages/preview/brand/info/info'; url = '/pages/preview/brand/info/info';
break; break;
@ -73,7 +74,7 @@ const SearchList: FC<Props> = ({name, clear}) => {
url = '/pages/preview/illness/article/article' url = '/pages/preview/illness/article/article'
break break
case 'video_records': case 'video_records':
return Taro.navigateTo({url: `/pages/preview/videoFull/videoFull?url=${health.resources.url}&poster=${health.url_path}&title=${health.title}`}) return Taro.navigateTo({url: `/pages/preview/videoFull/videoFull?url=${health.resources.url}&poster=${health.url_path}&title=${health.title}`})
case 'courses': case 'courses':
url = '/pages/business/videoInfo/videoInfo' url = '/pages/business/videoInfo/videoInfo'
break break
@ -82,13 +83,13 @@ const SearchList: FC<Props> = ({name, clear}) => {
} }
function onScrollToLower() { function onScrollToLower(){
if (brands?.length < total) { if (brands?.length < total) {
setPage(page + 1) setPage(page + 1)
getData().then() getData().then()
} else { } else {
setText('没有更多了~') setText('没有更多了~')
} }
} }
return ( return (
@ -96,71 +97,68 @@ const SearchList: FC<Props> = ({name, clear}) => {
className='scrollview' className='scrollview'
scrollY scrollY
scrollWithAnimation scrollWithAnimation
style={{height: `${globalData.pageHeight - 20}px`, backgroundColor: `#f5f5f5`}} style={{height:`${globalData.windowHeight-60}px`,backgroundColor:`#f5f5f5`}}
onScrollToLower={onScrollToLower} onScrollToLower={onScrollToLower}
> >
{loading && <AtLoadMore status={'loading'}/>} { loading && <AtLoadMore status={'loading'}/>}
{ {
brands.length >= 1 && !loading && brands.length >= 1 && !loading &&
<> <>
{brands.map((d) => {brands.map((d) =>
<View onClick={() => jumpInfo(d.data.id, d.data.table, d.data['@data'])} className={styles.box} <View onClick={() => jumpInfo(d.data.id,d.data.table,d.data['@data'])} className={styles.box} key={d.data.id}>
key={d.data.id}> {
{ d.data.table === 'brand' &&
d.data.table === 'brand' && <>
<> <Img width={128} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/>
<Img width={128} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/> <View className={styles.rightBox}>
<View className={styles.rightBox}> <View className='font-weight mb-2 font-28'>{d.data.title}</View>
<View className='font-weight mb-2 font-28'>{d.data.title}</View> <View className={styles.desc}>{d.data.content || '暂无品牌简介'}</View>
<View className={styles.desc}>{d.data.content || '暂无品牌简介'}</View> </View>
</View> </>
</> }
} {
{ d.data.table === 'article' &&
d.data.table === 'article' && <>
<> <View className={styles.articleLeftBox}>
<View className={styles.articleLeftBox}> <View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View> <View className={styles.desc}>{rfc33392time(d.data['@data'].created_at)} {d.data['@data'].page_view}</View>
<View </View>
className={styles.desc}>{rfc33392time(d.data['@data'].created_at)} {d.data['@data'].page_view}</View> <Img width={172} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/>
</View> </>
<Img width={172} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/> }
</> {
} d.data.table === 'video_records' &&
{ <>
d.data.table === 'video_records' && <Img width={192} height={192} src={d.data['@data'].url_path} mode='aspectFill' className={styles.image}/>
<> <Image src={play} className={styles.play} mode='aspectFit'/>
<Img width={192} height={192} src={d.data['@data'].url_path} mode='aspectFill' <View className={styles.videoRightBox}>
className={styles.image}/> <View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<Image src={play} className={styles.play} mode='aspectFit'/> <View className={styles.desc}>{d.data['@data'].introduction}</View>
<View className={styles.videoRightBox}> <View className={`${styles.desc} mt-2`}>: {d.data['@data'].video_view}</View>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View> </View>
<View className={styles.desc}>{d.data['@data'].introduction}</View> </>
<View className={`${styles.desc} mt-2`}>: {d.data['@data'].video_view}</View> }
</View> {
</> d.data.table === 'courses' &&
} <>
{ <Img width={192} height={138} src={d.data['@data'].thumb} mode='aspectFill' className={styles.image}/>
d.data.table === 'courses' && <View className={styles.articleLeftBox}>
<> <View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<Img width={192} height={138} src={d.data['@data'].thumb} mode='aspectFill' className={styles.image}/> <View className={styles.desc}>:{d.data['@data'].class_hour} {d.data['@data'].charge}</View>
<View className={styles.articleLeftBox}> </View>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View> </>
<View className={styles.desc}>:{d.data['@data'].class_hour} }
{d.data['@data'].charge}</View>
</View>
</>
}
</View> </View>
) )
} }
<View style={{width: '750rpx', textAlign: 'center', color: '#999'}} <View style={{width: '750rpx', textAlign: 'center', color: '#999'}} className="font-28 mt-3 mb-3">{text}</View>
className="font-28 mt-3 mb-3">{text}</View> </>
</>
} }
{!loading && brands.length === 0 && <Empty name='空空如也'/>} { !loading && brands.length === 0 && <Empty name='空空如也'/>}
</ScrollView> </ScrollView>
) )
} }

@ -1,6 +1,5 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: '搜索', navigationBarTitleText: '搜索',
navigationBarBackgroundColor: '#F2F8F6', navigationBarBackgroundColor:'#F2F8F6',
onReachBottomDistance: 50, onReachBottomDistance: 50
navigationStyle: 'custom',
}) })

@ -1,58 +1,42 @@
page { page{
background-color: #F2F8F6; background-color:#F2F8F6;
padding-left: 30rpx;
.searchHeader { .searchBox{
margin-top: 10px; width: 690rpx;
padding: 0 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
transition: all 200ms;
position: sticky;
z-index: 200 ;
overflow: hidden;
}
.searchBox {
flex: 1;
height: 68rpx; height: 68rpx;
background: #FFFFFF; background: #FFFFFF;
border-radius: 32rpx; border-radius: 32rpx 32rpx 32rpx 32rpx;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 24rpx; padding:0 24rpx;
.input{
.input {
font-size: 28rpx; font-size: 28rpx;
margin-left: 20rpx; font-weight: 500;
flex: 1; margin-left: 24rpx;
flex:1;
} }
} }
.titleBox{
.titleBox {
margin-top: 60rpx; margin-top: 60rpx;
width: 100%; width: 100%;
display: flex; display: flex;
box-sizing: border-box; box-sizing: border-box;
padding-right: 30rpx; padding-right: 30rpx;
justify-content: space-between; justify-content: space-between;
.title{
.title {
font-size: 28rpx; font-size: 28rpx;
font-weight: bold; font-weight: bold;
color: #323635; color: #323635;
} }
} }
.contentBox{
.contentBox {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
.items{
.items {
display: inline-block; display: inline-block;
background: #FFFFFF; background: #FFFFFF;
border-radius: 32rpx; border-radius:32rpx;
padding: 10rpx 24rpx; padding: 10rpx 24rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: 500; font-weight: 500;

@ -1,136 +1,116 @@
import {Input, View, Text, PageContainer, Image} from "@tarojs/components"; import {Input, View, Text, PageContainer} from "@tarojs/components";
import React, {FC, useEffect, useMemo, useState} from "react"; import {FC, useEffect, useState} from "react";
import { AtIcon } from 'taro-ui'
import styles from './index.module.scss' import styles from './index.module.scss'
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import {useDidShow} from '@tarojs/taro' import { useReady, useDidShow } from '@tarojs/taro'
import SearchList from './components/list' import SearchList from './components/list'
import search from '@/static/img/search.png'
import NavigationBar from "@/components/navigationBar/navigationBar";
import del from '@/static/img/del.png'
const Search: FC = () => { const Search:FC = () => {
const [value, setValue] = useState('') const [value, setValue] = useState('')
const [recentSearch, setRecentSearch] = useState<string[]>([]) const [recentSearch, setRecentSearch] = useState<string[]>([])
const [hotSearch] = useState<any[]>([]) const [hotSearch,setHotSearch] = useState<any[]>([])
const [show, setShow] = useState(false) const [show, setShow] = useState(false)
const [focus, setFocus] = useState(false)
useDidShow(getRecentSearch) useReady(()=>{
console.log('onReady')
})
useDidShow(()=>{
getRecentSearch()
})
useEffect(() => { useEffect(()=>{
if (!show) { if(!show){
getRecentSearch() getRecentSearch()
} }
}, [show]) },[show])
function inpFn(e) { function inpFn(e){
setValue(e.detail.value) setValue(e.detail.value)
} }
function clearSearch() { function clearSearch(){
Taro.removeStorageSync('recentSearch') Taro.removeStorageSync('recentSearch')
getRecentSearch() getRecentSearch()
} }
function getRecentSearch() { function getRecentSearch () {
setRecentSearch(Taro.getStorageSync('recentSearch')) setRecentSearch(Taro.getStorageSync('recentSearch'))
} }
function getSearchItem(value) { function getSearchItem(value) {
setValue(value) setValue(value)
// Taro.navigateTo({
// url:`/pages/preview/search/list/index?name=${value}`
// })
setShow(true) setShow(true)
} }
function searchInput() { function searchInput(){
if (value === "") return; if (value === "") return;
getSearchItem(value) getSearchItem(value)
//记录最近搜索 //记录最近搜索
let recentSearch = Taro.getStorageSync('recentSearch') || []; let recentSearch = Taro.getStorageSync('recentSearch') || [];
recentSearch.unshift(value); recentSearch.unshift(value);
Taro.setStorageSync('recentSearch', [...new Set(recentSearch)]) Taro.setStorageSync('recentSearch', [...new Set(recentSearch)])
} }
const searchStyles = useMemo((): React.CSSProperties | undefined => {
if (focus || show) {
return {
transform: "translateY(-43px)",
width: "70%",
}
}
}, [focus, show])
return ( return (
<> <View className="flex flex-column">
<NavigationBar text='搜索'/>
<View className={styles.searchHeader} style={searchStyles}>
<View className={styles.searchBox}> <View className={styles.searchBox}>
<Image src={search} style={{width: '32rpx', height: '32rpx'}} mode='widthFix'/> <AtIcon value='search' size='20' color='#ccc'></AtIcon>
<Input { show ?
onFocus={() => setFocus(true)} <Text className={styles.input} >{value}</Text>:
onBlur={() => setFocus(false)} <Input className={styles.input} placeholder="输入关键字搜索" type={'text'} confirmType={'search'} onInput={inpFn} onConfirm={searchInput} />
className={styles.input} }
placeholder={(focus || show) ? '' : "输入关键字搜索"}
type='text'
confirmType='search'
onInput={inpFn}
onConfirm={searchInput}/>
</View> </View>
{focus || show ? <View className='px-2 text-dark' onClick={() => setShow(false)}></View> : null}
</View>
<View className="flex flex-column px-2"> {
{ recentSearch.length >= 1 && !show &&
recentSearch.length >= 1 && !show && <>
<> <View className={styles.titleBox} >
<View className={styles.titleBox}> <Text className={styles.title}></Text>
<Text className={styles.title}></Text> <AtIcon onClick={clearSearch} value='trash' size='16' color='#909795'></AtIcon>
<Image src={del} mode='widthFix' style={{width: '16px'}} onClick={clearSearch}/> </View>
</View>
<View className={styles.contentBox}> <View className={styles.contentBox}>
{ {
recentSearch.length && recentSearch.length &&
recentSearch?.map(d => <View className={styles.items}> recentSearch?.map(d =>
<View onClick={() => getSearchItem(d)} className="font-28">{d}</View> <View className={styles.items}>
</View>) <View onClick={()=>{getSearchItem(d)}} className="font-28" >{d}</View>
</View>)
} }
</View> </View>
</> </>
} }
{ {
hotSearch.length >= 1 && !show && hotSearch.length >= 1 && !show &&
<> <>
<View className={`flex justify-between ${styles.titleBox}`}> <View className={`flex justify-between ${styles.titleBox}`} >
<Text className="font-32 fwb"></Text> <Text className="font-32 fwb"></Text>
</View> </View>
<View className="wid100 pt-3 pl-3 box-b"> <View className="wid100 pt-3 pl-3 box-b">
<View className="wid100 flex flex-wrap"> <View className="wid100 flex flex-wrap">
{ {
hotSearch.length && hotSearch.length &&
hotSearch.map(d => hotSearch.map(d =>
<View className="py-1 px-2 rounded-40 mr-2 mb-2 bg-warning text-white"> <View className="py-1 px-2 rounded-40 mr-2 mb-2 bg-warning text-white">
<View onClick={() => { <View onClick={()=>{getSearchItem(d)}} className="font-28" >{d}</View>
getSearchItem(d) </View>)
}} className="font-28">{d}</View> }
</View>)
}
</View>
</View> </View>
</> </View>
} </>
}
<PageContainer <PageContainer onClickOverlay={()=>{ setShow(false)}} show={show} round={true} overlay={true} overlayStyle={'background:rgba(0,0,0,0)'} >
onClickOverlay={() => setShow(false)} <SearchList name={value} clear={show} />
show={show} </PageContainer>
overlay
overlayStyle={'background:rgba(0,0,0,0)'}>
<SearchList name={value} clear={show}/>
</PageContainer>
</View>
</>
</View>
) )
} }
export default Search export default Search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

@ -147,21 +147,3 @@ export function everyDay(start_time: number, end_time: number, data: Record<numb
return [] return []
} }
} }
/** 时间前 */
export function beforeTime(time?: string): string {
const initiateTime = new Date(time || 0).getTime()
const today = Date.now()
const timeDifference = Math.floor((today - initiateTime) / 86400000)
if (timeDifference <= 0) {
return '今天'
} else if (timeDifference >= 365) {
return `${Math.floor(timeDifference / 365)}年前`
} else if (timeDifference >= 31) {
return `${Math.floor(timeDifference / 31)}月前`
} else if (timeDifference >= 7) {
return `${Math.floor(timeDifference / 7)}星期前`
} else {
return `${timeDifference}天前`
}
}

Loading…
Cancel
Save