first
This commit is contained in:
31
.eslintrc.js
Normal file
31
.eslintrc.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Eslint config file
|
||||
* Documentation: https://eslint.org/docs/user-guide/configuring/
|
||||
* Install the Eslint extension before using this feature.
|
||||
*/
|
||||
module.exports = {
|
||||
env: {
|
||||
es6: true,
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
ecmaFeatures: {
|
||||
modules: true,
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
},
|
||||
globals: {
|
||||
wx: true,
|
||||
App: true,
|
||||
Page: true,
|
||||
getCurrentPages: true,
|
||||
getApp: true,
|
||||
Component: true,
|
||||
requirePlugin: true,
|
||||
requireMiniProgram: true,
|
||||
},
|
||||
// extends: 'eslint:recommended',
|
||||
rules: {},
|
||||
}
|
||||
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Windows
|
||||
[Dd]esktop.ini
|
||||
Thumbs.db
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
|
||||
# Node.js
|
||||
node_modules/
|
||||
57
app.json
Normal file
57
app.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/index",
|
||||
"pages/index2/index2",
|
||||
"pages/record/record",
|
||||
"pages/detail/detail",
|
||||
"pages/history/history"
|
||||
],
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#4a6fa5",
|
||||
"navigationBarTitleText": "梦境日记",
|
||||
"navigationBarTextStyle": "white"
|
||||
},
|
||||
"tabBar": {
|
||||
"color": "#7A7E83",
|
||||
"selectedColor": "#4a6fa5",
|
||||
"borderStyle": "black",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/index/index",
|
||||
"text": "首页",
|
||||
"iconPath": "images/home.png",
|
||||
"selectedIconPath": "images/home-active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/index2/index2",
|
||||
"text": "首页2",
|
||||
"iconPath": "images/home.png",
|
||||
"selectedIconPath": "images/home-active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/record/record",
|
||||
"text": "记录",
|
||||
"iconPath": "images/add.png",
|
||||
"selectedIconPath": "images/add-active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/history/history",
|
||||
"text": "历史",
|
||||
"iconPath": "images/history.png",
|
||||
"selectedIconPath": "images/history-active.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
"style": "v2",
|
||||
"sitemapLocation": "sitemap.json",
|
||||
"permission": {
|
||||
"scope.userLocation": {
|
||||
"desc": "用于加载本地视频资源"
|
||||
}
|
||||
},
|
||||
"networkTimeout": {
|
||||
"downloadFile": 10000
|
||||
},
|
||||
"lazyCodeLoading": "requiredComponents"
|
||||
}
|
||||
10
app.wxss
Normal file
10
app.wxss
Normal file
@@ -0,0 +1,10 @@
|
||||
/**app.wxss**/
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 200rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
102
components/navigation-bar/navigation-bar.js
Normal file
102
components/navigation-bar/navigation-bar.js
Normal file
@@ -0,0 +1,102 @@
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true // 在组件定义时的选项中启用多slot支持
|
||||
},
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
extClass: {
|
||||
type: String,
|
||||
value: ''
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
value: ''
|
||||
},
|
||||
background: {
|
||||
type: String,
|
||||
value: ''
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
value: ''
|
||||
},
|
||||
back: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
homeButton: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
animated: {
|
||||
// 显示隐藏的时候opacity动画效果
|
||||
type: Boolean,
|
||||
value: true
|
||||
},
|
||||
show: {
|
||||
// 显示隐藏导航,隐藏的时候navigation-bar的高度占位还在
|
||||
type: Boolean,
|
||||
value: true,
|
||||
observer: '_showChange'
|
||||
},
|
||||
// back为true的时候,返回的页面深度
|
||||
delta: {
|
||||
type: Number,
|
||||
value: 1
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
displayStyle: ''
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
const rect = wx.getMenuButtonBoundingClientRect()
|
||||
const platform = (wx.getDeviceInfo() || wx.getSystemInfoSync()).platform
|
||||
const isAndroid = platform === 'android'
|
||||
const isDevtools = platform === 'devtools'
|
||||
const { windowWidth, safeArea: { top = 0, bottom = 0 } = {} } = wx.getWindowInfo() || wx.getSystemInfoSync()
|
||||
this.setData({
|
||||
ios: !isAndroid,
|
||||
innerPaddingRight: `padding-right: ${windowWidth - rect.left}px`,
|
||||
leftWidth: `width: ${windowWidth - rect.left}px`,
|
||||
safeAreaTop: isDevtools || isAndroid ? `height: calc(var(--height) + ${top}px); padding-top: ${top}px` : ``
|
||||
})
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
_showChange(show) {
|
||||
const animated = this.data.animated
|
||||
let displayStyle = ''
|
||||
if (animated) {
|
||||
displayStyle = `opacity: ${show ? '1' : '0'
|
||||
};transition:opacity 0.5s;`
|
||||
} else {
|
||||
displayStyle = `display: ${show ? '' : 'none'}`
|
||||
}
|
||||
this.setData({
|
||||
displayStyle
|
||||
})
|
||||
},
|
||||
back() {
|
||||
const data = this.data
|
||||
if (data.delta) {
|
||||
wx.navigateBack({
|
||||
delta: data.delta
|
||||
})
|
||||
}
|
||||
this.triggerEvent('back', { delta: data.delta }, {})
|
||||
}
|
||||
},
|
||||
})
|
||||
5
components/navigation-bar/navigation-bar.json
Normal file
5
components/navigation-bar/navigation-bar.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"component": true,
|
||||
"styleIsolation": "apply-shared",
|
||||
"usingComponents": {}
|
||||
}
|
||||
64
components/navigation-bar/navigation-bar.wxml
Normal file
64
components/navigation-bar/navigation-bar.wxml
Normal file
@@ -0,0 +1,64 @@
|
||||
<view class="weui-navigation-bar {{extClass}}">
|
||||
<view class="weui-navigation-bar__inner {{ios ? 'ios' : 'android'}}" style="color: {{color}}; background: {{background}}; {{displayStyle}}; {{innerPaddingRight}}; {{safeAreaTop}};">
|
||||
|
||||
<!-- 左侧按钮 -->
|
||||
<view class='weui-navigation-bar__left' style="{{leftWidth}};">
|
||||
<block wx:if="{{back || homeButton}}">
|
||||
<!-- 返回上一页 -->
|
||||
<block wx:if="{{back}}">
|
||||
<view class="weui-navigation-bar__buttons weui-navigation-bar__buttons_goback">
|
||||
<view
|
||||
bindtap="back"
|
||||
class="weui-navigation-bar__btn_goback_wrapper"
|
||||
hover-class="weui-active"
|
||||
hover-stay-time="100"
|
||||
aria-role="button"
|
||||
aria-label="返回"
|
||||
>
|
||||
<view class="weui-navigation-bar__button weui-navigation-bar__btn_goback"></view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 返回首页 -->
|
||||
<block wx:if="{{homeButton}}">
|
||||
<view class="weui-navigation-bar__buttons weui-navigation-bar__buttons_home">
|
||||
<view
|
||||
bindtap="home"
|
||||
class="weui-navigation-bar__btn_home_wrapper"
|
||||
hover-class="weui-active"
|
||||
aria-role="button"
|
||||
aria-label="首页"
|
||||
>
|
||||
<view class="weui-navigation-bar__button weui-navigation-bar__btn_home"></view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<slot name="left"></slot>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!-- 标题 -->
|
||||
<view class='weui-navigation-bar__center'>
|
||||
<view wx:if="{{loading}}" class="weui-navigation-bar__loading" aria-role="alert">
|
||||
<view
|
||||
class="weui-loading"
|
||||
aria-role="img"
|
||||
aria-label="加载中"
|
||||
></view>
|
||||
</view>
|
||||
<block wx:if="{{title}}">
|
||||
<text>{{title}}</text>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<slot name="center"></slot>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!-- 右侧留空 -->
|
||||
<view class='weui-navigation-bar__right'>
|
||||
<slot name="right"></slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
96
components/navigation-bar/navigation-bar.wxss
Normal file
96
components/navigation-bar/navigation-bar.wxss
Normal file
@@ -0,0 +1,96 @@
|
||||
.weui-navigation-bar {
|
||||
--weui-FG-0:rgba(0,0,0,.9);
|
||||
--height: 44px;
|
||||
--left: 16px;
|
||||
}
|
||||
.weui-navigation-bar .android {
|
||||
--height: 48px;
|
||||
}
|
||||
|
||||
.weui-navigation-bar {
|
||||
overflow: hidden;
|
||||
color: var(--weui-FG-0);
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__inner {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: calc(var(--height) + env(safe-area-inset-top));
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: env(safe-area-inset-top);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__left {
|
||||
position: relative;
|
||||
padding-left: var(--left);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__btn_goback_wrapper {
|
||||
padding: 11px 18px 11px 16px;
|
||||
margin: -11px -18px -11px -16px;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__btn_goback_wrapper.weui-active {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__btn_goback {
|
||||
font-size: 12px;
|
||||
width: 12px;
|
||||
height: 24px;
|
||||
-webkit-mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
-webkit-mask-size: cover;
|
||||
mask-size: cover;
|
||||
background-color: var(--weui-FG-0);
|
||||
}
|
||||
|
||||
.weui-navigation-bar__center {
|
||||
font-size: 17px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__loading {
|
||||
margin-right: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.weui-loading {
|
||||
font-size: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
background: transparent url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='80px' height='80px' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23606060' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23606060' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23606060' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A") no-repeat;
|
||||
background-size: 100%;
|
||||
margin-left: 0;
|
||||
animation: loading linear infinite 1s;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
from {
|
||||
transform: rotate(0);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
BIN
images/add-active.png
Normal file
BIN
images/add-active.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
images/add.png
Normal file
BIN
images/add.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
images/history-active.png
Normal file
BIN
images/history-active.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
images/history.png
Normal file
BIN
images/history.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
BIN
images/home-active.png
Normal file
BIN
images/home-active.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
images/home.png
Normal file
BIN
images/home.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
107
pages/detail/detail.js
Normal file
107
pages/detail/detail.js
Normal file
@@ -0,0 +1,107 @@
|
||||
Page({
|
||||
data: {
|
||||
dream: {},
|
||||
dreamId: '',
|
||||
emotions: [
|
||||
{ name: '开心', value: 'happy', icon: 'smile' },
|
||||
{ name: '害怕', value: 'scared', icon: 'warn' },
|
||||
{ name: '治愈', value: 'healing', icon: 'like' },
|
||||
{ name: '怪异', value: 'strange', icon: 'question' },
|
||||
{ name: '悲伤', value: 'sad', icon: 'cry' },
|
||||
{ name: '愤怒', value: 'angry', icon: 'no' },
|
||||
{ name: '紧张', value: 'nervous', icon: 'waiting' },
|
||||
{ name: '平静', value: 'calm', icon: 'sleep' }
|
||||
]
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
const id = options.id;
|
||||
this.setData({
|
||||
dreamId: id
|
||||
});
|
||||
this.loadDreamDetail(id);
|
||||
},
|
||||
|
||||
// 加载梦境详情
|
||||
loadDreamDetail(id) {
|
||||
wx.getStorage({
|
||||
key: 'dreamRecords',
|
||||
success: (res) => {
|
||||
const records = res.data || [];
|
||||
const dream = records.find(record => record.id === id);
|
||||
|
||||
if (dream) {
|
||||
this.setData({
|
||||
dream
|
||||
});
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: '未找到记录',
|
||||
icon: 'none'
|
||||
});
|
||||
setTimeout(() => {
|
||||
wx.navigateBack();
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 获取情绪图标
|
||||
getEmotionIcon(emotion) {
|
||||
const emotionObj = this.data.emotions.find(item => item.value === emotion);
|
||||
return emotionObj ? emotionObj.icon : 'info';
|
||||
},
|
||||
|
||||
// 获取情绪名称
|
||||
getEmotionName(emotion) {
|
||||
const emotionObj = this.data.emotions.find(item => item.value === emotion);
|
||||
return emotionObj ? emotionObj.name : '';
|
||||
},
|
||||
|
||||
// 删除记录
|
||||
deleteRecord() {
|
||||
const that = this;
|
||||
wx.showModal({
|
||||
title: '确认删除',
|
||||
content: '确定要删除这条梦境记录吗?',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
wx.getStorage({
|
||||
key: 'dreamRecords',
|
||||
success: (res) => {
|
||||
let records = res.data || [];
|
||||
records = records.filter(record => record.id !== that.data.dreamId);
|
||||
|
||||
wx.setStorage({
|
||||
key: 'dreamRecords',
|
||||
data: records,
|
||||
success: () => {
|
||||
wx.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
wx.navigateBack();
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 编辑记录
|
||||
editRecord() {
|
||||
// 在实际应用中,这里应该跳转到编辑页面
|
||||
// 并传递当前记录的数据
|
||||
wx.showToast({
|
||||
title: '编辑功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
3
pages/detail/detail.json
Normal file
3
pages/detail/detail.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
82
pages/detail/detail.wxml
Normal file
82
pages/detail/detail.wxml
Normal file
@@ -0,0 +1,82 @@
|
||||
<view class="container">
|
||||
<view class="detail-header">
|
||||
<text class="dream-title">{{dream.title}}</text>
|
||||
<text class="dream-date">{{dream.date}}</text>
|
||||
|
||||
<!-- 情绪指示器 -->
|
||||
<view class="emotion-indicator" wx:if="{{dream.emotion}}">
|
||||
<icon
|
||||
type="{{getEmotionIcon(dream.emotion)}}"
|
||||
size="20"
|
||||
color="#4a6fa5"
|
||||
/>
|
||||
<text class="emotion-text">{{getEmotionName(dream.emotion)}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 标签区域 -->
|
||||
<view class="tags-container" wx:if="{{dream.tags.length > 0}}">
|
||||
<view
|
||||
wx:for="{{dream.tags}}"
|
||||
wx:key="index"
|
||||
class="tag"
|
||||
>
|
||||
{{item}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 详情内容 -->
|
||||
<view class="detail-content">
|
||||
<!-- 场景 -->
|
||||
<view class="content-section" wx:if="{{dream.scene}}">
|
||||
<view class="section-header">
|
||||
<icon type="location" size="18" color="#4a6fa5" />
|
||||
<text class="section-title">场景</text>
|
||||
</view>
|
||||
<text class="section-content">{{dream.scene}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 人物 -->
|
||||
<view class="content-section" wx:if="{{dream.characters}}">
|
||||
<view class="section-header">
|
||||
<icon type="user" size="18" color="#4a6fa5" />
|
||||
<text class="section-title">人物</text>
|
||||
</view>
|
||||
<text class="section-content">{{dream.characters}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 情节 -->
|
||||
<view class="content-section" wx:if="{{dream.plot}}">
|
||||
<view class="section-header">
|
||||
<icon type="list" size="18" color="#4a6fa5" />
|
||||
<text class="section-title">情节</text>
|
||||
</view>
|
||||
<text class="section-content">{{dream.plot}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 其他细节 -->
|
||||
<view class="content-section" wx:if="{{dream.details}}">
|
||||
<view class="section-header">
|
||||
<icon type="info" size="18" color="#4a6fa5" />
|
||||
<text class="section-title">其他细节</text>
|
||||
</view>
|
||||
<text class="section-content">{{dream.details}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="action-buttons">
|
||||
<button
|
||||
class="delete-btn"
|
||||
bindtap="deleteRecord"
|
||||
>
|
||||
删除记录
|
||||
</button>
|
||||
<button
|
||||
class="edit-btn"
|
||||
bindtap="editRecord"
|
||||
>
|
||||
编辑记录
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
1
pages/detail/detail.wxss
Normal file
1
pages/detail/detail.wxss
Normal file
@@ -0,0 +1 @@
|
||||
/* pages/detail/detail.wxss */
|
||||
129
pages/history/history.js
Normal file
129
pages/history/history.js
Normal file
@@ -0,0 +1,129 @@
|
||||
Page({
|
||||
data: {
|
||||
records: [],
|
||||
filteredRecords: [],
|
||||
allTags: [],
|
||||
selectedFilterTag: '',
|
||||
searchKeyword: ''
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.loadDreamRecords();
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 每次页面显示时重新加载数据
|
||||
this.loadDreamRecords();
|
||||
},
|
||||
|
||||
// 加载梦境记录
|
||||
loadDreamRecords() {
|
||||
wx.getStorage({
|
||||
key: 'dreamRecords',
|
||||
success: (res) => {
|
||||
const records = res.data || [];
|
||||
const allTags = this.extractAllTags(records);
|
||||
|
||||
this.setData({
|
||||
records,
|
||||
filteredRecords: records,
|
||||
allTags
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 提取所有标签
|
||||
extractAllTags(records) {
|
||||
const tagSet = new Set();
|
||||
|
||||
records.forEach(record => {
|
||||
record.tags.forEach(tag => {
|
||||
tagSet.add(tag);
|
||||
});
|
||||
});
|
||||
|
||||
return Array.from(tagSet);
|
||||
},
|
||||
|
||||
// 搜索功能
|
||||
onSearchChange(e) {
|
||||
const keyword = e.detail.value.trim().toLowerCase();
|
||||
this.setData({
|
||||
searchKeyword: keyword
|
||||
});
|
||||
this.filterRecords(keyword, this.data.selectedFilterTag);
|
||||
},
|
||||
|
||||
// 选择筛选标签
|
||||
selectFilterTag(e) {
|
||||
const tag = e.currentTarget.dataset.tag;
|
||||
this.setData({
|
||||
selectedFilterTag: tag
|
||||
});
|
||||
this.filterRecords(this.data.searchKeyword, tag);
|
||||
},
|
||||
|
||||
// 筛选记录
|
||||
filterRecords(keyword, tag) {
|
||||
let filtered = [...this.data.records];
|
||||
|
||||
// 按标签筛选
|
||||
if (tag) {
|
||||
filtered = filtered.filter(record =>
|
||||
record.tags.includes(tag)
|
||||
);
|
||||
}
|
||||
|
||||
// 按关键词搜索
|
||||
if (keyword) {
|
||||
filtered = filtered.filter(record => {
|
||||
const textToSearch = [
|
||||
record.title,
|
||||
record.scene,
|
||||
record.characters,
|
||||
record.plot,
|
||||
record.details,
|
||||
...record.tags
|
||||
].join(' ').toLowerCase();
|
||||
|
||||
return textToSearch.includes(keyword);
|
||||
});
|
||||
}
|
||||
|
||||
this.setData({
|
||||
filteredRecords: filtered
|
||||
});
|
||||
},
|
||||
|
||||
// 获取情绪对应的图标
|
||||
getEmotionIcon(emotion) {
|
||||
const emotionMap = {
|
||||
'happy': 'smile',
|
||||
'scared': 'warn',
|
||||
'healing': 'like',
|
||||
'strange': 'question',
|
||||
'sad': 'cry',
|
||||
'angry': 'no',
|
||||
'nervous': 'waiting',
|
||||
'calm': 'sleep'
|
||||
};
|
||||
|
||||
return emotionMap[emotion] || 'info';
|
||||
},
|
||||
|
||||
// 跳转到记录页面
|
||||
navigateToRecord() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/record/record'
|
||||
});
|
||||
},
|
||||
|
||||
// 跳转到详情页面
|
||||
navigateToDetail(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/detail/detail?id=${id}`
|
||||
});
|
||||
}
|
||||
});
|
||||
3
pages/history/history.json
Normal file
3
pages/history/history.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
90
pages/history/history.wxml
Normal file
90
pages/history/history.wxml
Normal file
@@ -0,0 +1,90 @@
|
||||
<view class="container">
|
||||
<view class="header">
|
||||
<text class="title">我的梦境记录</text>
|
||||
<text class="count">{{records.length}} 条记录</text>
|
||||
</view>
|
||||
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-box">
|
||||
<icon type="search" size="16" color="#999" class="search-icon" />
|
||||
<input
|
||||
class="search-input"
|
||||
placeholder="搜索标签或内容..."
|
||||
bindinput="onSearchChange"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 标签筛选 -->
|
||||
<view class="filter-tags" wx:if="{{allTags.length > 0}}">
|
||||
<scroll-view scroll-x="true" class="tags-scroll">
|
||||
<view
|
||||
class="filter-tag {{selectedFilterTag === '' ? 'active' : ''}}"
|
||||
bindtap="selectFilterTag"
|
||||
data-tag=""
|
||||
>
|
||||
全部
|
||||
</view>
|
||||
<view
|
||||
wx:for="{{allTags}}"
|
||||
wx:key="index"
|
||||
class="filter-tag {{selectedFilterTag === item ? 'active' : ''}}"
|
||||
bindtap="selectFilterTag"
|
||||
data-tag="{{item}}"
|
||||
>
|
||||
{{item}}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 记录列表 -->
|
||||
<view class="records-list">
|
||||
<view wx:if="{{filteredRecords.length === 0}}" class="empty-state">
|
||||
<icon type="sleep" size="60" color="#ccc" />
|
||||
<text class="empty-text">还没有记录呢</text>
|
||||
<text class="empty-desc">快去记录你的第一个梦境吧</text>
|
||||
<button
|
||||
class="add-btn"
|
||||
bindtap="navigateToRecord"
|
||||
>
|
||||
+ 记录新梦境
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<view
|
||||
wx:for="{{filteredRecords}}"
|
||||
wx:key="id"
|
||||
class="record-item"
|
||||
bindtap="navigateToDetail"
|
||||
data-id="{{item.id}}"
|
||||
>
|
||||
<view class="record-header">
|
||||
<text class="record-title">{{item.title}}</text>
|
||||
<text class="record-date">{{item.date}}</text>
|
||||
</view>
|
||||
|
||||
<view class="record-preview">
|
||||
<text class="preview-text">
|
||||
{{item.plot.length > 50 ? item.plot.substring(0, 50) + '...' : item.plot || '点击查看详情'}}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="record-tags">
|
||||
<view
|
||||
wx:for="{{item.tags}}"
|
||||
wx:key="index"
|
||||
class="record-tag"
|
||||
>
|
||||
{{item}}
|
||||
</view>
|
||||
|
||||
<view class="emotion-indicator" wx:if="{{item.emotion}}">
|
||||
<icon
|
||||
type="{{getEmotionIcon(item.emotion)}}"
|
||||
size="16"
|
||||
color="#4a6fa5"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
1
pages/history/history.wxss
Normal file
1
pages/history/history.wxss
Normal file
@@ -0,0 +1 @@
|
||||
/* pages/history/history.wxss */
|
||||
82
pages/index/index.js
Normal file
82
pages/index/index.js
Normal file
@@ -0,0 +1,82 @@
|
||||
Page({
|
||||
data: {
|
||||
animationFrame: null // 用于保存定时器ID
|
||||
},
|
||||
|
||||
onReady() {
|
||||
// 获取Canvas上下文
|
||||
const query = wx.createSelectorQuery()
|
||||
|
||||
// 获取Canvas宽高
|
||||
query.select('.starry-canvas')
|
||||
.fields({ node: true, size: true })
|
||||
.exec((res) => {
|
||||
const canvas = res[0].node
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
const dpr = wx.getSystemInfoSync().pixelRatio
|
||||
canvas.width = res[0].width * dpr
|
||||
canvas.height = res[0].height * dpr
|
||||
ctx.scale(dpr, dpr)
|
||||
|
||||
// 绘制星空
|
||||
this.drawStars(canvas, ctx)
|
||||
})
|
||||
},
|
||||
|
||||
// 绘制动态星空
|
||||
drawStars(canvas, ctx) {
|
||||
const width = canvas.width / wx.getSystemInfoSync().pixelRatio
|
||||
const height = canvas.height / wx.getSystemInfoSync().pixelRatio
|
||||
|
||||
// 创建星星数组
|
||||
const stars = []
|
||||
const starCount = 200 // 星星数量
|
||||
|
||||
// 初始化星星
|
||||
for (let i = 0; i < starCount; i++) {
|
||||
stars.push({
|
||||
x: Math.random() * width,
|
||||
y: Math.random() * height,
|
||||
radius: Math.random() * 1.5 + 0.5, // 星星大小
|
||||
opacity: Math.random(), // 透明度
|
||||
speed: Math.random() * 0.5 + 0.1 // 移动速度
|
||||
})
|
||||
}
|
||||
|
||||
// 动画循环 - 使用setInterval替代requestAnimationFrame
|
||||
const animate = () => {
|
||||
// 清空画布
|
||||
ctx.clearRect(0, 0, width, height)
|
||||
|
||||
// 绘制每颗星星
|
||||
stars.forEach(star => {
|
||||
// 更新星星位置(向上移动)
|
||||
star.y -= star.speed
|
||||
if (star.y < 0) {
|
||||
star.y = height // 星星移出屏幕后重新从底部出现
|
||||
}
|
||||
|
||||
// 随机闪烁效果
|
||||
star.opacity += (Math.random() - 0.5) * 0.02
|
||||
star.opacity = Math.max(0.1, Math.min(1, star.opacity))
|
||||
|
||||
// 绘制星星
|
||||
ctx.beginPath()
|
||||
ctx.arc(star.x, star.y, star.radius, 0, Math.PI * 2)
|
||||
ctx.fillStyle = `rgba(255, 255, 255, ${star.opacity})`
|
||||
ctx.fill()
|
||||
})
|
||||
}
|
||||
|
||||
// 开始动画,每30ms更新一次(约33fps)
|
||||
this.data.animationFrame = setInterval(animate, 30)
|
||||
},
|
||||
|
||||
// 页面卸载时清除定时器,避免内存泄漏
|
||||
onUnload() {
|
||||
if (this.data.animationFrame) {
|
||||
clearInterval(this.data.animationFrame)
|
||||
}
|
||||
}
|
||||
})
|
||||
5
pages/index/index.json
Normal file
5
pages/index/index.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"navigation-bar": "/components/navigation-bar/navigation-bar"
|
||||
}
|
||||
}
|
||||
12
pages/index/index.wxml
Normal file
12
pages/index/index.wxml
Normal file
@@ -0,0 +1,12 @@
|
||||
<!-- 动态星空背景 -->
|
||||
<canvas
|
||||
class="starry-canvas"
|
||||
type="2d"
|
||||
canvas-id="starrySky"
|
||||
></canvas>
|
||||
|
||||
<!-- 前景内容 -->
|
||||
<view class="content">
|
||||
<text class="title">梦之笺</text>
|
||||
<text class="subtitle">记录你的梦</text>
|
||||
</view>
|
||||
34
pages/index/index.wxss
Normal file
34
pages/index/index.wxss
Normal file
@@ -0,0 +1,34 @@
|
||||
.starry-canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #0a0a1a; /* 深蓝色夜空 */
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #ffffff;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 60rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20rpx;
|
||||
text-shadow: 0 0 10rpx rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 32rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
83
pages/index2/index2.js
Normal file
83
pages/index2/index2.js
Normal file
@@ -0,0 +1,83 @@
|
||||
Page({
|
||||
data: {
|
||||
playbackRate: 5.0, // 默认1倍速
|
||||
animationFrame: null // 用于保存定时器ID
|
||||
},
|
||||
|
||||
onReady() {
|
||||
// 获取Canvas上下文
|
||||
const query = wx.createSelectorQuery()
|
||||
|
||||
// 获取Canvas宽高
|
||||
query.select('.starry-canvas')
|
||||
.fields({ node: true, size: true })
|
||||
.exec((res) => {
|
||||
const canvas = res[0].node
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
const dpr = wx.getSystemInfoSync().pixelRatio
|
||||
canvas.width = res[0].width * dpr
|
||||
canvas.height = res[0].height * dpr
|
||||
ctx.scale(dpr, dpr)
|
||||
|
||||
// 绘制星空
|
||||
this.drawStars(canvas, ctx)
|
||||
})
|
||||
},
|
||||
|
||||
// 绘制动态星空
|
||||
drawStars(canvas, ctx) {
|
||||
const width = canvas.width / wx.getSystemInfoSync().pixelRatio
|
||||
const height = canvas.height / wx.getSystemInfoSync().pixelRatio
|
||||
|
||||
// 创建星星数组
|
||||
const stars = []
|
||||
const starCount = 200 // 星星数量
|
||||
|
||||
// 初始化星星
|
||||
for (let i = 0; i < starCount; i++) {
|
||||
stars.push({
|
||||
x: Math.random() * width,
|
||||
y: Math.random() * height,
|
||||
radius: Math.random() * 1.5 + 0.5, // 星星大小
|
||||
opacity: Math.random(), // 透明度
|
||||
speed: Math.random() * 0.5 + 0.1 // 移动速度
|
||||
})
|
||||
}
|
||||
|
||||
// 动画循环 - 使用setInterval替代requestAnimationFrame
|
||||
const animate = () => {
|
||||
// 清空画布
|
||||
ctx.clearRect(0, 0, width, height)
|
||||
|
||||
// 绘制每颗星星
|
||||
stars.forEach(star => {
|
||||
// 更新星星位置(向上移动)
|
||||
star.y -= star.speed
|
||||
if (star.y < 0) {
|
||||
star.y = height // 星星移出屏幕后重新从底部出现
|
||||
}
|
||||
|
||||
// 随机闪烁效果
|
||||
star.opacity += (Math.random() - 0.5) * 0.02
|
||||
star.opacity = Math.max(0.1, Math.min(1, star.opacity))
|
||||
|
||||
// 绘制星星
|
||||
ctx.beginPath()
|
||||
ctx.arc(star.x, star.y, star.radius, 0, Math.PI * 2)
|
||||
ctx.fillStyle = `rgba(255, 255, 255, ${star.opacity})`
|
||||
ctx.fill()
|
||||
})
|
||||
}
|
||||
|
||||
// 开始动画,每30ms更新一次(约33fps)
|
||||
this.data.animationFrame = setInterval(animate, 30)
|
||||
},
|
||||
|
||||
// 页面卸载时清除定时器,避免内存泄漏
|
||||
onUnload() {
|
||||
if (this.data.animationFrame) {
|
||||
clearInterval(this.data.animationFrame)
|
||||
}
|
||||
}
|
||||
})
|
||||
5
pages/index2/index2.json
Normal file
5
pages/index2/index2.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"navigation-bar": "/components/navigation-bar/navigation-bar"
|
||||
}
|
||||
}
|
||||
15
pages/index2/index2.wxml
Normal file
15
pages/index2/index2.wxml
Normal file
@@ -0,0 +1,15 @@
|
||||
<view class="page-container">
|
||||
<video id="bg-video"
|
||||
src="http://exam.yinyue.click/sky.mp4"
|
||||
loop
|
||||
muted
|
||||
autoplay
|
||||
object-fit="cover"
|
||||
controls="{{false}}">
|
||||
playback-rate="{{playbackRate}}">
|
||||
</video>
|
||||
<!-- 这里可以添加首页其他内容,比如标题、按钮等 -->
|
||||
<view class="content">
|
||||
<text class="title">欢迎来到我的梦境</text>
|
||||
</view>
|
||||
</view>
|
||||
31
pages/index2/index2.wxss
Normal file
31
pages/index2/index2.wxss
Normal file
@@ -0,0 +1,31 @@
|
||||
.page-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#bg-video {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 64rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
172
pages/record/record.js
Normal file
172
pages/record/record.js
Normal file
@@ -0,0 +1,172 @@
|
||||
Page({
|
||||
data: {
|
||||
// 梦境内容
|
||||
title: '',
|
||||
scene: '',
|
||||
characters: '',
|
||||
plot: '',
|
||||
details: '',
|
||||
|
||||
// 标签数据
|
||||
dreamTags: [
|
||||
'飞行', '追逐', '考试', '重逢', '坠落',
|
||||
'迷路', '被追逐', '飞翔', '裸奔', '牙齿脱落',
|
||||
'死亡', '结婚', '学校', '怪物', '亲人',
|
||||
'朋友', '陌生人', '水', '火', '天空',
|
||||
'未来', '过去', '重复的梦', '清明梦', '噩梦'
|
||||
],
|
||||
selectedTags: [],
|
||||
|
||||
// 情绪数据
|
||||
emotions: [
|
||||
{ name: '开心', value: 'happy', icon: 'smile' },
|
||||
{ name: '害怕', value: 'scared', icon: 'warn' },
|
||||
{ name: '治愈', value: 'healing', icon: 'like' },
|
||||
{ name: '怪异', value: 'strange', icon: 'question' },
|
||||
{ name: '悲伤', value: 'sad', icon: 'cry' },
|
||||
{ name: '愤怒', value: 'angry', icon: 'no' },
|
||||
{ name: '紧张', value: 'nervous', icon: 'waiting' },
|
||||
{ name: '平静', value: 'calm', icon: 'sleep' }
|
||||
],
|
||||
selectedEmotion: ''
|
||||
},
|
||||
|
||||
// 标题输入
|
||||
onTitleChange(e) {
|
||||
this.setData({
|
||||
title: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 场景输入
|
||||
onSceneChange(e) {
|
||||
this.setData({
|
||||
scene: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 人物输入
|
||||
onCharactersChange(e) {
|
||||
this.setData({
|
||||
characters: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 情节输入
|
||||
onPlotChange(e) {
|
||||
this.setData({
|
||||
plot: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 细节输入
|
||||
onDetailsChange(e) {
|
||||
this.setData({
|
||||
details: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 切换标签选择状态
|
||||
toggleTag(e) {
|
||||
const tag = e.currentTarget.dataset.tag;
|
||||
const { selectedTags } = this.data;
|
||||
|
||||
let newSelectedTags;
|
||||
if (selectedTags.includes(tag)) {
|
||||
// 移除标签
|
||||
newSelectedTags = selectedTags.filter(t => t !== tag);
|
||||
} else {
|
||||
// 添加标签
|
||||
newSelectedTags = [...selectedTags, tag];
|
||||
}
|
||||
|
||||
this.setData({
|
||||
selectedTags: newSelectedTags
|
||||
});
|
||||
},
|
||||
|
||||
// 选择情绪
|
||||
selectEmotion(e) {
|
||||
const emotion = e.currentTarget.dataset.emotion;
|
||||
this.setData({
|
||||
selectedEmotion: emotion
|
||||
});
|
||||
},
|
||||
|
||||
// 保存梦境记录
|
||||
saveDreamRecord() {
|
||||
// 简单验证
|
||||
if (!this.data.title && !this.data.scene && !this.data.plot) {
|
||||
wx.showToast({
|
||||
title: '请至少填写一些内容',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建记录对象
|
||||
const dreamRecord = {
|
||||
id: Date.now().toString(), // 使用时间戳作为唯一ID
|
||||
title: this.data.title || '无标题梦境',
|
||||
scene: this.data.scene,
|
||||
characters: this.data.characters,
|
||||
plot: this.data.plot,
|
||||
details: this.data.details,
|
||||
tags: this.data.selectedTags,
|
||||
emotion: this.data.selectedEmotion,
|
||||
date: new Date().toLocaleDateString(),
|
||||
timestamp: Date.now()
|
||||
};
|
||||
|
||||
// 从本地存储获取已有记录
|
||||
wx.getStorage({
|
||||
key: 'dreamRecords',
|
||||
success: (res) => {
|
||||
const records = res.data || [];
|
||||
records.unshift(dreamRecord); // 添加到数组开头
|
||||
|
||||
// 保存回本地存储
|
||||
wx.setStorage({
|
||||
key: 'dreamRecords',
|
||||
data: records,
|
||||
success: () => {
|
||||
wx.showToast({
|
||||
title: '记录保存成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
// 返回首页
|
||||
setTimeout(() => {
|
||||
wx.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: () => {
|
||||
// 如果没有已有记录,创建新数组
|
||||
wx.setStorage({
|
||||
key: 'dreamRecords',
|
||||
data: [dreamRecord],
|
||||
success: () => {
|
||||
wx.showToast({
|
||||
title: '记录保存成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
// 返回首页
|
||||
setTimeout(() => {
|
||||
wx.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
3
pages/record/record.json
Normal file
3
pages/record/record.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
114
pages/record/record.wxml
Normal file
114
pages/record/record.wxml
Normal file
@@ -0,0 +1,114 @@
|
||||
<view class="container">
|
||||
<!-- 记录标题 -->
|
||||
<view class="input-section">
|
||||
<text class="section-title">梦境标题</text>
|
||||
<input
|
||||
class="dream-title"
|
||||
placeholder="给你的梦境起个名字吧..."
|
||||
bindinput="onTitleChange"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 分段记录区域 -->
|
||||
<view class="section">
|
||||
<text class="section-title">梦境内容</text>
|
||||
<text class="section-desc">可以分场景、人物、情绪等方面记录</text>
|
||||
|
||||
<!-- 场景描述 -->
|
||||
<view class="segment">
|
||||
<view class="segment-header">
|
||||
<icon type="location" size="18" color="#4a6fa5" />
|
||||
<text class="segment-title">场景</text>
|
||||
</view>
|
||||
<textarea
|
||||
class="segment-content"
|
||||
placeholder="描述一下梦中的场景环境..."
|
||||
bindinput="onSceneChange"
|
||||
></textarea>
|
||||
</view>
|
||||
|
||||
<!-- 人物描述 -->
|
||||
<view class="segment">
|
||||
<view class="segment-header">
|
||||
<icon type="user" size="18" color="#4a6fa5" />
|
||||
<text class="segment-title">人物</text>
|
||||
</view>
|
||||
<textarea
|
||||
class="segment-content"
|
||||
placeholder="梦中出现了哪些人物?他们做了什么?"
|
||||
bindinput="onCharactersChange"
|
||||
></textarea>
|
||||
</view>
|
||||
|
||||
<!-- 情节描述 -->
|
||||
<view class="segment">
|
||||
<view class="segment-header">
|
||||
<icon type="list" size="18" color="#4a6fa5" />
|
||||
<text class="segment-title">情节</text>
|
||||
</view>
|
||||
<textarea
|
||||
class="segment-content"
|
||||
placeholder="描述梦境中的主要情节和发展..."
|
||||
bindinput="onPlotChange"
|
||||
></textarea>
|
||||
</view>
|
||||
|
||||
<!-- 其他细节 -->
|
||||
<view class="segment">
|
||||
<view class="segment-header">
|
||||
<icon type="info" size="18" color="#4a6fa5" />
|
||||
<text class="segment-title">其他细节</text>
|
||||
</view>
|
||||
<textarea
|
||||
class="segment-content"
|
||||
placeholder="还有什么想记录的细节?"
|
||||
bindinput="onDetailsChange"
|
||||
></textarea>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 标签选择 -->
|
||||
<view class="section">
|
||||
<text class="section-title">梦境标签</text>
|
||||
<text class="section-desc">选择与你的梦境相关的标签</text>
|
||||
|
||||
<view class="tags-container">
|
||||
<view
|
||||
wx:for="{{dreamTags}}"
|
||||
wx:key="index"
|
||||
class="tag {{selectedTags.includes(item) ? 'tag-selected' : ''}}"
|
||||
bindtap="toggleTag"
|
||||
data-tag="{{item}}"
|
||||
>
|
||||
{{item}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 情绪标记 -->
|
||||
<view class="section">
|
||||
<text class="section-title">情绪标记</text>
|
||||
<text class="section-desc">这个梦境带给你什么感受?</text>
|
||||
|
||||
<view class="emotions-container">
|
||||
<view
|
||||
wx:for="{{emotions}}"
|
||||
wx:key="index"
|
||||
class="emotion {{selectedEmotion === item.value ? 'emotion-selected' : ''}}"
|
||||
bindtap="selectEmotion"
|
||||
data-emotion="{{item.value}}"
|
||||
>
|
||||
<icon type="{{item.icon}}" size="24" />
|
||||
<text>{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<button
|
||||
class="save-btn"
|
||||
bindtap="saveDreamRecord"
|
||||
>
|
||||
保存梦境记录
|
||||
</button>
|
||||
</view>
|
||||
148
pages/record/record.wxss
Normal file
148
pages/record/record.wxss
Normal file
@@ -0,0 +1,148 @@
|
||||
.container {
|
||||
padding: 16px;
|
||||
background-color: #f5f7fa;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 24px;
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.input-section {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.section-desc {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dream-title {
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
background-color: white;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.segment {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.segment:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.segment-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.segment-title {
|
||||
font-size: 16px;
|
||||
color: #4a6fa5;
|
||||
margin-left: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.segment-content {
|
||||
width: 100%;
|
||||
min-height: 80px;
|
||||
padding: 12px 16px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.tags-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.tag {
|
||||
padding: 6px 14px;
|
||||
background-color: #f1f5f9;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
color: #475569;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.tag-selected {
|
||||
background-color: #4a6fa5;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.emotions-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.emotion {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background-color: #f1f5f9;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.emotion text {
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
.emotion-selected {
|
||||
background-color: #4a6fa5;
|
||||
}
|
||||
|
||||
.emotion-selected text {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.emotion-selected icon {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
width: 100%;
|
||||
padding: 14px 0;
|
||||
background-color: #4a6fa5;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
border-radius: 8px;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.save-btn::after {
|
||||
border: none;
|
||||
}
|
||||
29
project.config.json
Normal file
29
project.config.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"appid": "wxb902b6272b3d647c",
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "3.10.1",
|
||||
"packOptions": {
|
||||
"ignore": [],
|
||||
"include": []
|
||||
},
|
||||
"setting": {
|
||||
"coverView": true,
|
||||
"es6": true,
|
||||
"postcss": true,
|
||||
"minified": true,
|
||||
"enhance": true,
|
||||
"showShadowRootInWxmlPanel": true,
|
||||
"packNpmRelationList": [],
|
||||
"babelSetting": {
|
||||
"ignore": [],
|
||||
"disablePlugins": [],
|
||||
"outputPath": ""
|
||||
},
|
||||
"condition": false
|
||||
},
|
||||
"condition": {},
|
||||
"editorSetting": {
|
||||
"tabIndent": "insertSpaces",
|
||||
"tabSize": 2
|
||||
}
|
||||
}
|
||||
7
project.private.config.json
Normal file
7
project.private.config.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
|
||||
"projectname": "meng",
|
||||
"setting": {
|
||||
"compileHotReLoad": true
|
||||
}
|
||||
}
|
||||
7
sitemap.json
Normal file
7
sitemap.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
||||
Reference in New Issue
Block a user