index.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. <template>
  2. <layout-page>
  3. <view style="position: relative;">
  4. <!-- 日历 -->
  5. <Calendar
  6. :date="date"
  7. class="uni-calendar--hook"
  8. :selected="selected"
  9. :lunar="true"
  10. :range="false"
  11. :showMonth="true"
  12. @change="handleChange"
  13. @monthSwitch="handleMonthSwitch"
  14. />
  15. <button
  16. size="default"
  17. class="send-button"
  18. @click="handleClear"
  19. >
  20. 清除缓存
  21. </button>
  22. <!-- 手账 -->
  23. <view class="journal" v-if="calendarRecord && calendarRecord.length > 0">
  24. <view class="title">手账</view>
  25. <uni-card v-for="(val, index) in calendarRecord" :key="index" @tap="handleUpdateJournal(val)">
  26. <uni-section :title="val.date" type="line"></uni-section>
  27. <view class="description ss-m-t-15">{{ val.notes }}</view>
  28. </uni-card>
  29. </view>
  30. <!-- 添加手账 -->
  31. <view class="add-btn" @tap="handleAddJournal">
  32. <uni-icons type="plusempty" size="30" color="#fff"></uni-icons>
  33. </view>
  34. <!-- 黄历弹窗 -->
  35. <uni-popup ref="popupRef" type="dialog">
  36. <view class="popupContent">
  37. <view class="content-box">
  38. <view class="text-center ss-p-y-30">
  39. <view class="yangli">{{ calendarInfo.yangli }}</view>
  40. <view class="yinli">{{ calendarInfo.yinli }}</view>
  41. <view class="d-flex align-center justify-center">
  42. <span style="color: #7f7f7f;">幸运色</span>
  43. <span v-if="calendarInfo.color === '白'" class="ss-m-l-20" style="color: #7f7f7f;">白色</span>
  44. <view
  45. v-else
  46. class="luckyColor ss-m-l-20"
  47. :style="{ 'background-color': `${colorDict[calendarInfo.color] || '#2979ff'}` }"
  48. ></view>
  49. </view>
  50. </view>
  51. <view class="center-box ss-p-y-30 ss-p-x-30">
  52. <view class="d-flex">
  53. <view class="yi d-flex align-center justify-center">宜</view>
  54. <view class="font-size-15" style="flex: 1; color: #c6b393;">{{ calendarInfo.yi }}</view>
  55. </view>
  56. <view class="d-flex ss-m-t-30">
  57. <view class="ji d-flex align-center justify-center">忌</view>
  58. <view class="font-size-15" style="flex: 1; color: #7f7f7f;">{{ calendarInfo.ji }}</view>
  59. </view>
  60. </view>
  61. <view class="bottom-box">
  62. <view class="bottom-box-item d-flex flex-column align-center justify-center">
  63. <view class="padding">
  64. <view class="label">五行</view>
  65. <view class="value">{{ calendarInfo.wuxing }}</view>
  66. </view>
  67. <view class="border"></view>
  68. <view class="padding">
  69. <view class="label">吉神</view>
  70. <view class="value">{{ calendarInfo.jishen }}</view>
  71. </view>
  72. </view>
  73. <view class="bottom-box-item d-flex align-center justify-center">
  74. <view class="padding">
  75. <view class="label">彭祖</view>
  76. <view class="value">{{ calendarInfo.baiji }}</view>
  77. </view>
  78. </view>
  79. <view class="bottom-box-item d-flex flex-column align-center justify-center">
  80. <view class="padding">
  81. <view class="label">冲煞</view>
  82. <view class="value">{{ calendarInfo.chongsha }}</view>
  83. </view>
  84. <view class="border"></view>
  85. <view class="padding">
  86. <view class="label">凶神</view>
  87. <view class="value">{{ calendarInfo.xiongshen }}</view>
  88. </view>
  89. </view>
  90. </view>
  91. </view>
  92. </view>
  93. <view class="text-center ss-m-t-50">
  94. <uni-icons type="close" size="40" color="#fff" @click="handleClose"></uni-icons>
  95. </view>
  96. </uni-popup>
  97. </view>
  98. </layout-page>
  99. </template>
  100. <script setup>
  101. import { onLoad, onShow } from '@dcloudio/uni-app'
  102. import { ref } from 'vue'
  103. import Calendar from '@/components/uni-calendar/components/uni-calendar/uni-calendar.vue'
  104. import { getDrawLots } from '@/api/drawLots.js'
  105. import layoutPage from '@/layout'
  106. import { showAuthModal } from '@/hooks/useModal'
  107. import { getCalendarRecord } from '@/api/drawLots.js'
  108. const colorDict = {
  109. '白': '#FAFAFA',
  110. '黑': '#212121',
  111. '绿': '#43A047',
  112. '红': '#F44336',
  113. '黄': '#FDD835'
  114. }
  115. function getDate(date, AddDayCount = 0) {
  116. if (!date) {
  117. date = new Date()
  118. }
  119. if (typeof date !== 'object') {
  120. date = date.replace(/-/g, '/')
  121. }
  122. const dd = new Date(date)
  123. dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
  124. const y = dd.getFullYear()
  125. const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
  126. const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
  127. return {
  128. fullDate: y + '-' + m + '-' + d,
  129. year: y,
  130. month: m,
  131. date: d,
  132. day: dd.getDay()
  133. }
  134. }
  135. const date = ref(getDate(new Date()).fullDate)
  136. // 设置日期选中内容
  137. const selected = ref([])
  138. // 登录信息
  139. const userInfo = ref(uni.getStorageSync('wechat_user') || {})
  140. onLoad(() => {
  141. if (!userInfo.value || !userInfo.value?.openid) return showAuthModal()
  142. getCalendarData(date.value.slice(0, 7), 'onLoad')
  143. })
  144. onShow(() => {
  145. // 刷新一次本地登录信息,防止 onLoad 时未拿到最新登录态
  146. const latestUser = uni.getStorageSync('wechat_user')
  147. if (latestUser?.openid && latestUser?.openid !== userInfo.value?.openid) {
  148. userInfo.value = latestUser
  149. }
  150. if (userInfo.value?.openid) getCalendarData(date.value.slice(0, 7), 'onShow')
  151. })
  152. // 监听登录成功事件,立刻刷新数据
  153. uni.$off && uni.$off('auth:login')
  154. uni.$on && uni.$on('auth:login', (user) => {
  155. userInfo.value = user || uni.getStorageSync('wechat_user')
  156. if (userInfo.value?.openid) {
  157. getCalendarData(date.value.slice(0, 7), 'event:auth:login')
  158. }
  159. })
  160. const handleClear = () => {
  161. selected.value = []
  162. calendarRecord.value = []
  163. userInfo.value = {}
  164. uni.clearStorageSync()
  165. showAuthModal()
  166. }
  167. // 点击日期查看黄历信息
  168. const popupRef = ref()
  169. const calendarInfo = ref({})
  170. const handleChange = async (e) => {
  171. date.value = e.fulldate
  172. if (e.isBackToday) return // 点击左上角“今日”按钮不弹窗
  173. try {
  174. const { result } = await getDrawLots({ date: e.fulldate })
  175. if (!result) return uni.showToast({ title: '黄历信息获取失败', icon: 'none' })
  176. calendarInfo.value = result || {}
  177. popupRef.value.open()
  178. } catch (error) {
  179. console.log(error, '错误信息')
  180. }
  181. }
  182. // 获取手账记录
  183. const calendarRecord = ref([])
  184. const getCalendarData = async (month_key, type) => {
  185. console.log(type, '获取手账记录类型')
  186. try {
  187. const { result } = await getCalendarRecord({ month_key, openid: userInfo.value.openid })
  188. calendarRecord.value = result?.calendar_content || []
  189. selected.value = calendarRecord.value?.length ? calendarRecord.value.map((item) => {
  190. return { date: item.date, color: '#f8bbd0' }
  191. }) : []
  192. } catch {}
  193. }
  194. // 切换月份
  195. const handleMonthSwitch = (e) => {
  196. console.log(e, '切换月份')
  197. getCalendarData(`${e.year}-${e.month < 10 ? '0' + e.month : e.month}`, 'monthSwitch')
  198. }
  199. const handleClose = () => {
  200. popupRef.value.close()
  201. calendarInfo.value = {}
  202. }
  203. // 添加手账
  204. const handleAddJournal = () => {
  205. let url = `/pages/drawLots/journal?date=${date.value}`
  206. const index = calendarRecord.value.findIndex((item) => item.date === date.value)
  207. if (index > -1) {
  208. uni.showToast({ title: '手账已存在,可进行编辑', icon: 'none' })
  209. url += `&notes=${calendarRecord.value[index].notes}`
  210. }
  211. uni.navigateTo({
  212. url
  213. })
  214. }
  215. // 更新手账
  216. const handleUpdateJournal = (val) => {
  217. uni.navigateTo({
  218. url: `/pages/drawLots/journal?date=${val.date}&notes=${val.notes}`
  219. })
  220. }
  221. </script>
  222. <style lang="scss" scoped>
  223. $commonColor: #c2a08c;
  224. $size: 25px;
  225. :deep {
  226. .uni-card {
  227. border-radius: 10px !important;
  228. }
  229. }
  230. .journal {
  231. margin-top: 30rpx;
  232. padding-bottom: 100px;
  233. .title {
  234. color: #999;
  235. margin: 0 30px;
  236. }
  237. .description {
  238. display: -webkit-box;
  239. -webkit-box-orient: vertical;
  240. -webkit-line-clamp: 2;
  241. overflow: hidden;
  242. }
  243. }
  244. .add-btn {
  245. position: fixed;
  246. right: 20px;
  247. bottom: 50px;
  248. width: 60px;
  249. height: 60px;
  250. border-radius: 50%;
  251. background-color: #2979ff;
  252. display: flex;
  253. align-items: center;
  254. justify-content: center;
  255. }
  256. .popupContent {
  257. position: relative;
  258. background-color: #fff;
  259. width: 70vw;
  260. padding: 30rpx;
  261. .content-box {
  262. height: 100%;
  263. border: 1px solid $commonColor;
  264. border-radius: 6px;
  265. }
  266. .yangli {
  267. font-weight: bold;
  268. color: $commonColor;
  269. font-size: 30px;
  270. }
  271. .yinli {
  272. color: #7f7f7f;
  273. margin: 10px 0;
  274. }
  275. .center-box {
  276. border-top: 1px solid $commonColor;
  277. border-bottom: 1px solid $commonColor;
  278. .yi {
  279. width: $size;
  280. height: $size;
  281. background-color: #c39c87;
  282. border-radius: 50%;
  283. color: #fff;
  284. margin-right: 10px;
  285. font-size: 14px;
  286. }
  287. .ji {
  288. width: $size;
  289. height: $size;
  290. background-color: #bfbfbf;
  291. border-radius: 50%;
  292. color: #fff;
  293. margin-right: 10px;
  294. font-size: 14px;
  295. }
  296. }
  297. .bottom-box {
  298. display: flex;
  299. &-item {
  300. width: 33.3%;
  301. text-align: center;
  302. border-right: 1px solid $commonColor;
  303. &:nth-child(3n) {
  304. border-right: none;
  305. }
  306. .label {
  307. font-size: 17px;
  308. }
  309. .value {
  310. color: #7f7f7f;
  311. font-size: 14px;
  312. margin-top: 10px;
  313. }
  314. .padding {
  315. padding: 10px;
  316. }
  317. .border {
  318. border-top: 1px solid #c2a08c;
  319. height: 1px;
  320. width: 100%;
  321. }
  322. }
  323. }
  324. .luckyColor {
  325. width: 50rpx;
  326. height: 50rpx;
  327. border-radius: 50%;
  328. }
  329. }
  330. </style>