Browse Source

文章页

master
kola-web 3 months ago
parent
commit
d3cb343d9c
  1. 2
      .prettierrc
  2. 14
      project.private.config.json
  3. 4
      src/app.json
  4. BIN
      src/images/empty-1.png
  5. BIN
      src/images/fold-up.png
  6. BIN
      src/images/icon-collection1.png
  7. BIN
      src/images/icon-directory.png
  8. 3
      src/pages/article/index.json
  9. 175
      src/pages/article/index.scss
  10. 77
      src/pages/article/index.ts
  11. 66
      src/pages/article/index.wxml
  12. 26
      src/pages/home/index.wxml
  13. 69
      src/pages/login/index.ts
  14. 8
      src/pages/login/index.wxml
  15. 5
      src/pages/protocol/index.json
  16. 3
      src/pages/protocol/index.scss
  17. 8
      src/pages/protocol/index.ts
  18. 1
      src/pages/protocol/index.wxml
  19. 7
      src/pages/search/index.json
  20. 99
      src/pages/search/index.scss
  21. 45
      src/pages/search/index.ts
  22. 54
      src/pages/search/index.wxml

2
.prettierrc

@ -4,7 +4,7 @@
"tabWidth": 2, "tabWidth": 2,
"useTabs": false, "useTabs": false,
"semi": true, "semi": true,
"singleQuote": false, "singleQuote": true,
"bracketSpacing": true, "bracketSpacing": true,
"trailingComma": "all", "trailingComma": "all",
"arrowParens": "always", "arrowParens": "always",

14
project.private.config.json

@ -9,6 +9,20 @@
"miniprogram": { "miniprogram": {
"list": [ "list": [
{ {
"name": "隐私协议",
"pathName": "pages/protocol/index",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "搜索",
"pathName": "pages/search/index",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "文章详情", "name": "文章详情",
"pathName": "pages/article/index", "pathName": "pages/article/index",
"query": "", "query": "",

4
src/app.json

@ -7,7 +7,9 @@
"pages/topic/index", "pages/topic/index",
"pages/collection/index", "pages/collection/index",
"pages/classify/index", "pages/classify/index",
"pages/article/index" "pages/article/index",
"pages/search/index",
"pages/protocol/index"
], ],
"preloadRule": {}, "preloadRule": {},
"window": { "window": {

BIN
src/images/empty-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/images/fold-up.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

BIN
src/images/icon-collection1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/images/icon-directory.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

3
src/pages/article/index.json

@ -2,6 +2,7 @@
"navigationStyle": "default", "navigationStyle": "default",
"navigationBarTitleText": "详情", "navigationBarTitleText": "详情",
"usingComponents": { "usingComponents": {
"van-slider": "@vant/weapp/slider/index" "van-slider": "@vant/weapp/slider/index",
"van-popup": "@vant/weapp/popup/index"
} }
} }

175
src/pages/article/index.scss

@ -1,14 +1,185 @@
.page { .page {
padding: 48rpx 32rpx; padding: 48rpx 32rpx 200rpx;
.page-title { .page-title {
font-size: 44rpx; font-size: 44rpx;
color: #222222; color: #222222;
font-weight: bold; font-weight: bold;
line-height: 48rpx; line-height: 48rpx;
} }
.page-date{
.page-date {
margin-top: 24rpx; margin-top: 24rpx;
font-size: 28rpx; font-size: 28rpx;
color: #999999; color: #999999;
} }
.audio-bar {
margin-top: 32rpx;
padding: 32rpx;
--slider-disabled-opacity: 1;
background-color: #f9fafb;
border-radius: 24rpx;
.a-header {
display: flex;
align-items: center;
justify-content: space-between;
.wrap {
line-height: 1;
.name {
font-size: 32rpx;
color: #000000;
font-weight: bold;
}
.date {
margin-top: 12rpx;
font-size: 24rpx;
color: #65686c;
}
}
.icon {
width: 42rpx;
height: 42rpx;
}
}
.progress {
display: block;
margin-top: 30rpx;
}
}
.rich {
margin-top: 32rpx;
}
.quick-article {
margin-top: 24rpx;
padding: 26rpx 32rpx;
background: #f9fafb;
line-height: 48rpx;
border-radius: 16rpx 16rpx 16rpx 16rpx;
.label {
font-size: 32rpx;
color: #3795f7;
}
}
.type {
margin-top: 48rpx;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 24rpx;
.label {
font-size: 32rpx;
color: #999999;
}
.item {
padding: 6rpx 24rpx;
border-radius: 40rpx;
font-size: 32rpx;
color: #fff;
background-color: #3795f7;
}
}
.footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 30rpx 30rpx calc(30rpx + env(safe-area-inset-bottom));
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 -6rpx 32.8rpx rgba(0, 0, 0, 0.1);
background: #ffffff;
.item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
gap: 12rpx;
.icon {
width: 56rpx;
height: 56rpx;
}
}
}
}
.popup-directory {
.p-close-line {
padding: 36rpx 32rpx;
display: flex;
justify-content: flex-end;
.option {
font-size: 32rpx;
color: #999999;
.icon {
width: 24rpx;
height: 24rpx;
}
}
}
.p-title {
padding: 0 32rpx;
font-size: 44rpx;
color: #222222;
font-weight: bold;
}
.p-type {
padding: 32rpx;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 24rpx;
.label {
font-size: 32rpx;
color: #999999;
}
.item {
padding: 6rpx 24rpx;
border-radius: 40rpx;
font-size: 32rpx;
color: #fff;
background-color: #3795f7;
}
}
.p-scroll {
max-height: 50vh;
padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
.row {
padding: 32rpx;
position: relative;
&::after {
position: absolute;
bottom: 0;
left: 32rpx;
content: '';
width: calc(100% - 64rpx);
height: 1px;
background-color: #f0f0f0;
}
&:last-of-type::after {
display: none;
}
&.current {
background: rgba(55, 149, 247, 0.06);
}
}
}
} }

77
src/pages/article/index.ts

@ -1,8 +1,79 @@
const _app = getApp<IAppOption>(); const _app = getApp<IAppOption>();
Page({ Page({
data: {}, data: {
onLoad() {}, show: false,
progress: 0,
url: 'http://m10.music.126.net/20241126110303/3f2481d2d6d50acd2009359539eadda0/ymusic/5353/0f0f/0358/d99739615f8e5153d77042092f07fd77.mp3',
play: false,
time: '00:01/00:00',
},
innerAudioContext: null as WechatMiniprogram.InnerAudioContext | null,
onLoad() {
this.innerAudioContext = wx.createInnerAudioContext();
},
onUnload() {
if (this.innerAudioContext) {
this.innerAudioContext?.stop();
this.innerAudioContext.destroy();
}
},
handlePlay() {
const { url, play } = this.data;
if (this.innerAudioContext) {
if (play) {
this.innerAudioContext.stop();
return;
}
this.innerAudioContext.stop();
this.innerAudioContext.src = url;
this.innerAudioContext.play();
this.setData({
play: true,
});
const listener = () => {
if (this.innerAudioContext) {
const { currentTime, duration } = this.innerAudioContext;
const time = `${this.formatTime(currentTime)}/${this.formatTime(duration)}`;
const progress = (currentTime / duration) * 100;
this.setData({
time,
progress,
});
}
};
this.innerAudioContext.onTimeUpdate(listener);
this.innerAudioContext.onEnded(() => {
this.setData({
play: false,
});
});
this.innerAudioContext.onStop(() => {
this.setData({
play: false,
});
});
}
},
handlePause() {
if (this.innerAudioContext) {
this.innerAudioContext.pause();
this.setData({
play: false,
});
}
},
formatTime(time: number) {
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60);
return `${minutes < 10 ? `0${minutes}` : minutes}:${seconds < 10 ? `0${seconds}` : seconds}`;
},
onClose() {
this.setData({
show: false,
});
},
}); });
export {} export {};

66
src/pages/article/index.wxml

@ -5,11 +5,69 @@
<view class="a-header"> <view class="a-header">
<view class="wrap"> <view class="wrap">
<view class="name">概要解读</view> <view class="name">概要解读</view>
<view class="date">00:01/09:47</view> <view class="date">{{time}}</view>
</view> </view>
<image class="icon" src="/images/icon-play.png"></image> <image bind:tap="handlePause" wx:if="{{play}}" class="icon" src="/images/icon-stop.png"></image>
<!-- <image class="icon" src="/images/icon-stop.png"></image> --> <image bind:tap="handlePlay" wx:else class="icon" src="/images/icon-play.png"></image>
</view>
<van-slider
class="progress"
custom-class="progress"
disabled
step="0.001"
value="{{progress}}"
bar-height="12rpx"
active-color="#3795F7"
inactive-color="#FFFFFF"
use-button-slot
/>
</view>
<view class="rich"></view>
<view class="quick-article">
<text class="label">上一篇:</text>
身体活动引用的政策与文献
</view>
<view class="quick-article">
<text class="label">下一篇:</text>
身体活动引用的政策与文献
</view>
<view class="type">
<view class="label">分类</view>
<view class="item">健康生活方式</view>
</view>
<view class="footer">
<view class="item">
<image class="icon" src="/images/icon-directory.png"></image>
目录
</view>
<view class="item">
<image class="icon" src="/images/icon-collection1.png"></image>
目录
</view> </view>
<van-slider value="50" bind:change="onChange" />
</view> </view>
</view> </view>
<van-popup show="{{ show }}" round position="bottom" bind:close="onClose">
<view class="popup-directory">
<view class="p-close-line">
<view class="option">
收起
<image class="icon" src="/images/fold-up.png"></image>
</view>
</view>
<view class="p-title">身体活动引用的指南与专家共识</view>
<view class="p-type">
<view class="label">分类</view>
<view class="item">健康生活方式</view>
</view>
<view class="p-scroll">
<view class="row current">1.身体活动引用的政策与文献</view>
<view class="row">1.身体活动引用的政策与文献</view>
<view class="row">1.身体活动引用的政策与文献</view>
<view class="row">1.身体活动引用的政策与文献</view>
<view class="row">1.身体活动引用的政策与文献</view>
<view class="row">1.身体活动引用的政策与文献</view>
</view>
</view>
</van-popup>

26
src/pages/home/index.wxml

@ -1,4 +1,7 @@
<view class="page" style="background: url('/images/home-bg.png') no-repeat top center/100% 580rpx;padding-top:{{menuButtonInfo.top}}px;"> <view
class="page"
style="background: url('/images/home-bg.png') no-repeat top center/100% 580rpx;padding-top:{{menuButtonInfo.top}}px;"
>
<image class="logo" src="/images/home-logo.png"></image> <image class="logo" src="/images/home-logo.png"></image>
<image class="page-title" src="/images/home-title.png"></image> <image class="page-title" src="/images/home-title.png"></image>
<view class="page-slogan">人人都是家庭健康师,让生活更有质量</view> <view class="page-slogan">人人都是家庭健康师,让生活更有质量</view>
@ -13,12 +16,7 @@
placeholder="请输入要搜索的内容" placeholder="请输入要搜索的内容"
/> />
</view> </view>
<swiper <swiper class="swiper" indicator-dots indicator-color="rgba(255,255,255,0.62)" indicator-active-color="#FFFFFF">
class="swiper"
indicator-dots
indicator-color="rgba(255,255,255,0.62)"
indicator-active-color="#FFFFFF"
>
<swiper-item class="swiper-item"> <swiper-item class="swiper-item">
<image class="banner" src="/images/place.png"></image> <image class="banner" src="/images/place.png"></image>
</swiper-item> </swiper-item>
@ -32,18 +30,14 @@
bind:tap="handleDetail" bind:tap="handleDetail"
> >
<view class="title">公司综合信息</view> <view class="title">公司综合信息</view>
<view class="content">健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策</view> <view class="content">
健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策健康政策三医政策
</view>
</view> </view>
</view> </view>
<view class="remark"> <view class="remark">
<view class="r-header"> <view class="r-header">留言板</view>
留言板 <textarea class="r-content" placeholder-class="textarea-placeholder" placeholder="欢迎反馈您的问题"></textarea>
</view>
<textarea
class="r-content"
placeholder-class="textarea-placeholder"
placeholder="欢迎反馈您的问题"
></textarea>
<view class="submit">提交</view> <view class="submit">提交</view>
</view> </view>
</view> </view>

69
src/pages/login/index.ts

@ -6,10 +6,10 @@ Page({
show: true, show: true,
menuButtonInfo: {}, menuButtonInfo: {},
mobile: "", mobile: '',
code: "", code: '',
protool: false, protool: false,
codeText: "发送验证码", codeText: '发送验证码',
}, },
onLoad() {}, onLoad() {},
getCode() { getCode() {
@ -17,29 +17,29 @@ Page({
const mobile = this.data.mobile; const mobile = this.data.mobile;
if (!mobile) { if (!mobile) {
wx.showToast({ wx.showToast({
title: "手机号不能为空", title: '手机号不能为空',
icon: "none", icon: 'none',
}); });
return; return;
} }
// 验证手机号 // 验证手机号
if (!/^1[3-9,]\d{9}$/.test(mobile)) { if (!/^1[3-9,]\d{9}$/.test(mobile)) {
wx.showToast({ wx.showToast({
title: "手机号格式不正确", title: '手机号格式不正确',
icon: "none", icon: 'none',
}); });
return; return;
} }
wx.ajax({ wx.ajax({
method: "POST", method: 'POST',
url: "?r=takeda/login/send-verify-code", url: '?r=takeda/login/send-verify-code',
data: { data: {
mobile, mobile,
}, },
}).then(() => { }).then(() => {
wx.showToast({ wx.showToast({
icon: "none", icon: 'none',
title: "验证码已发送~", title: '验证码已发送~',
}); });
let time = 60; let time = 60;
timer = setInterval(() => { timer = setInterval(() => {
@ -51,7 +51,7 @@ Page({
clearInterval(timer as number); clearInterval(timer as number);
timer = null; timer = null;
this.setData({ this.setData({
codeText: "发送验证码", codeText: '发送验证码',
}); });
} }
}, 1000); }, 1000);
@ -60,26 +60,29 @@ Page({
handleSubmit() { handleSubmit() {
const { mobile, code, protool } = this.data; const { mobile, code, protool } = this.data;
if (!protool) { if (!protool) {
this.handleNavProtool(); wx.showToast({
icon: 'none',
title: '请先同意用户隐私协议',
});
return; return;
} }
if (!mobile) { if (!mobile) {
wx.showToast({ wx.showToast({
title: "请输入手机号", title: '请输入手机号',
icon: "none", icon: 'none',
}); });
return; return;
} }
if (!code) { if (!code) {
wx.showToast({ wx.showToast({
title: "请输入验证码", title: '请输入验证码',
icon: "none", icon: 'none',
}); });
return; return;
} }
wx.ajax({ wx.ajax({
method: "POST", method: 'POST',
url: "?r=takeda/login/reg-login", url: '?r=takeda/login/reg-login',
data: { data: {
mobile, mobile,
code, code,
@ -92,12 +95,16 @@ Page({
const { protool } = this.data; const { protool } = this.data;
const { iv, encryptedData } = e.detail; const { iv, encryptedData } = e.detail;
if (!protool) { if (!protool) {
wx.showToast({
icon: 'none',
title: '请先同意用户隐私协议',
});
return; return;
} }
if (iv && encryptedData) { if (iv && encryptedData) {
wx.ajax({ wx.ajax({
method: "POST", method: 'POST',
url: "?r=takeda/login/wx-reg-login", url: '?r=takeda/login/wx-reg-login',
data: { data: {
iv: encodeURIComponent(iv), iv: encodeURIComponent(iv),
encryptedData: encodeURIComponent(encryptedData), encryptedData: encodeURIComponent(encryptedData),
@ -112,25 +119,17 @@ Page({
app.globalData.doctorId = res.doctorId; app.globalData.doctorId = res.doctorId;
app.waitLogin().then(() => { app.waitLogin().then(() => {
wx.reLaunch({ wx.reLaunch({
url: "/pages/home/index", url: '/pages/home/index',
}); });
}); });
}, },
handleProtool() { handleProtool() {
if (this.data.protool) { this.setData({
this.setData({ protool: !this.data.protool,
protool: false, });
});
} else {
this.setData({
protool: false,
});
wx.navigateTo({ url: "/module1/pages/loginProtool/index" });
}
}, },
handleNavProtool(e) { handleNavProtool() {
const phone = e?.currentTarget?.dataset?.phone; wx.navigateTo({ url: `/pages/protocol/index` });
wx.navigateTo({ url: `/module1/pages/loginProtool/index?phone=${phone}` });
}, },
handleTopic() {}, handleTopic() {},

8
src/pages/login/index.wxml

@ -29,11 +29,7 @@
<text class="link" bind:tap="handleNavProtool">《用户隐私协议》</text> <text class="link" bind:tap="handleNavProtool">《用户隐私协议》</text>
</view> </view>
<view class="submit" bind:tap="handleSubmit">登录</view> <view class="submit" bind:tap="handleSubmit">登录</view>
<button wx:if="{{protool}}" class="tel-btn" open-type="getPhoneNumber" bindgetphonenumber="handleWxSubmit"> <button class="tel-btn" open-type="getPhoneNumber" bindgetphonenumber="handleWxSubmit">
<image class="icon" src="/images/icon-phone.png"></image>
手机号快捷登录
</button>
<button wx:else class="tel-btn" bind:tap="handleNavProtool" data-phone="1">
<image class="icon" src="/images/icon-phone.png"></image> <image class="icon" src="/images/icon-phone.png"></image>
手机号快捷登录 手机号快捷登录
</button> </button>
@ -44,7 +40,7 @@
</view> </view>
</view> </view>
<van-popup show="{{ show }}" bind:close="onClose" round style="--popup-background-color:transparent;"> <van-popup show="{{ show }}" bind:close="onClose" round style="--popup-background-color: transparent">
<view class="popup"> <view class="popup">
<view class="popup-container"> <view class="popup-container">
<image class="badge" src="/images/login-popup-badge.png"></image> <image class="badge" src="/images/login-popup-badge.png"></image>

5
src/pages/protocol/index.json

@ -0,0 +1,5 @@
{
"navigationBarTitleText": "用户隐私协议",
"navigationStyle": "default",
"usingComponents": {}
}

3
src/pages/protocol/index.scss

@ -0,0 +1,3 @@
.page {
padding: 32rpx;
}

8
src/pages/protocol/index.ts

@ -0,0 +1,8 @@
const _app = getApp<IAppOption>();
Page({
data: {},
onLoad() {},
});
export {}

1
src/pages/protocol/index.wxml

@ -0,0 +1 @@
<view class="page"></view>

7
src/pages/search/index.json

@ -0,0 +1,7 @@
{
"usingComponents": {
"van-nav-bar": "@vant/weapp/nav-bar/index",
"van-icon": "@vant/weapp/icon/index",
"pagination":"/components/pagination/index"
}
}

99
src/pages/search/index.scss

@ -0,0 +1,99 @@
page {
background-color: #f3f4f5;
}
.page {
padding-bottom: 80rpx;
.search {
margin: 34rpx 32rpx 0;
padding: 0 0 0 24rpx;
display: flex;
align-items: center;
background: linear-gradient(158deg, #ffffff 0%, #f2f9fe 100%);
border-radius: 106rpx 106rpx 106rpx 106rpx;
border: 1px solid #ffffff;
.icon {
width: 36rpx;
height: 36rpx;
}
.input {
flex: 1;
padding: 16rpx;
line-height: 40rpx;
font-size: 28rpx;
}
.place-input {
color: #c9cdd4;
}
}
.tip {
margin: 52rpx 32rpx 0;
font-size: 28rpx;
color: #222222;
font-weight: bold;
}
.card {
padding: 24rpx;
margin: 24rpx 32rpx 0;
display: flex;
gap: 24rpx;
background: linear-gradient(173deg, #ffffff 0%, #eff7ff 100%);
border-radius: 24rpx 24rpx 24rpx 24rpx;
border: 2rpx solid #ffffff;
.photo {
flex-shrink: 0;
width: 218rpx;
height: 218rpx;
border-radius: 16rpx;
}
.c-container {
flex: 1;
.title {
font-size: 32rpx;
color: #222222;
font-weight: bold;
line-height: 48rpx;
}
.type {
margin-top: 16rpx;
font-size: 28rpx;
color: #999999;
line-height: 28rpx;
}
.stat {
margin-top: 42rpx;
display: flex;
align-items: center;
gap: 40rpx;
.s-item {
display: flex;
align-items: center;
gap: 8rpx;
font-size: 28rpx;
color: #999999;
.icon {
width: 28rpx;
height: 28rpx;
}
&.active {
color: #3795f7;
}
}
}
}
}
.empty-search {
.e-icon {
margin: 186rpx auto 0;
display: block;
width: 217rpx;
height: 236rpx;
}
.content {
margin-top: 44rpx;
font-size: 32rpx;
line-height: 48rpx;
color: #999999;
text-align: center;
}
}
}

45
src/pages/search/index.ts

@ -0,0 +1,45 @@
const _app = getApp<IAppOption>();
Page({
data: {
background: "transparent",
pagination: {
page: 1,
pages: 1,
count: 1,
},
list: [],
},
onLoad() {},
getList(newPage = 1) {
// wx.ajax({
// method: "GET",
// url: `?r=takeda/case/get-list`,
// data: {
// page: newPage,
// },
// }).then((res) => {
// const list = res.page === 1 ? res.list : [...this.data.list, ...res.list];
// this.setData({
// list,
// pagination: {
// page: res.page,
// pages: res.pages,
// count: res.count,
// },
// });
// });
},
onReachBottom() {
const { page, pages } = this.data.pagination;
if (pages > page && this.data.list.length) {
this.getList(page + 1);
}
},
handleBack() {
wx.navigateBack();
},
});
export {};

54
src/pages/search/index.wxml

@ -0,0 +1,54 @@
<van-nav-bar
title="搜索"
border="{{false}}"
custom-style="background:{{background}}"
bind:click-left="handleBack"
fixed
>
<van-icon name="arrow-left" slot="left" color="#000" size="46rpx" />
</van-nav-bar>
<view class="page" style="padding-top:{{menuButtonInfo.bottom}}px;">
<view class="search">
<image class="icon" src="/images/icon-search.png"></image>
<input
type="text"
class="input"
placeholder-class="place-input"
confirm-type="search"
bindconfirm="handleSearch"
placeholder="请输入要搜索的内容"
/>
</view>
<view class="tip">以下为搜到的内容</view>
<view class="card">
<image class="photo" mode="aspectFill" src="/images/place.png"></image>
<view class="c-container">
<view class="title">骨密度是骨健康的关键指标,我们检查对吗?</view>
<view class="type">健康管理/口腔</view>
<view class="stat">
<view class="s-item">
<image class="icon" src="/images/icon-eye.png"></image>
123
</view>
<view class="s-item active">
<image class="icon" src="/images/icon-collection-active.png"></image>
取消收藏
</view>
<view class="s-item">
<image class="icon" src="/images/icon-collection.png"></image>
收藏
</view>
</view>
</view>
</view>
<view class="empty-search" wx:if="{{search && pagination.count===0}}">
<image class="e-icon" src="/images/empty-1.png"></image>
<view class="content">
抱歉,未搜到相关内容
<view></view>
换个词试试吧
</view>
</view>
<pagination wx:else pagination="{{pagination}}"></pagination>
</view>
Loading…
Cancel
Save