hookehuyr

初始化

Showing 111 changed files with 3101 additions and 0 deletions
dist/
deploy_versions/
.temp/
.rn_temp/
node_modules/
.DS_Store
.swc
.history
// babel-preset-taro 更多选项和默认值:
// https://github.com/NervJS/taro/blob/next/packages/babel-preset-taro/README.md
module.exports = {
presets: [
['taro', {
framework: 'vue3',
ts: false
}]
]
}
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
ActivityEditor: typeof import('./src/components/activity-editor.vue')['default']
BottomButton: typeof import('./src/components/bottom-button.vue')['default']
CalendarSelect: typeof import('./src/components/calendarSelect.vue')['default']
Counter: typeof import('./src/components/Counter.vue')['default']
NavBar: typeof import('./src/components/navBar.vue')['default']
NutCalendar: typeof import('@nutui/nutui-taro')['Calendar']
NutCol: typeof import('@nutui/nutui-taro')['Col']
NutRow: typeof import('@nutui/nutui-taro')['Row']
Picker: typeof import('./src/components/time-picker-data/picker.vue')['default']
PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default']
RoomCard: typeof import('./src/components/roomCard.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}
module.exports = {
env: {
NODE_ENV: '"development"'
},
defineConstants: {
},
mini: {},
h5: {}
}
import Components from 'unplugin-vue-components/webpack';
import NutUIResolver from '@nutui/nutui-taro/dist/resolver';
const path = require('path')
const fs = require('fs')
const config = {
projectName: 'meihuaApp',
date: '2023-12-14',
designWidth (input) {
if (input?.file?.replace(/\\+/g, '/').indexOf('@nutui') > -1) {
return 375
}
return 750
},
deviceRatio: {
640: 2.34 / 2,
750: 1,
828: 1.81 / 2,
375: 2 / 1
},
alias: { // 配置目录别名
"@/utils": path.resolve(__dirname, "../src/utils"),
"@/components": path.resolve(__dirname, "../src/components"),
"@/images": path.resolve(__dirname, "../src/assets/images"),
"@/assets": path.resolve(__dirname, "../src/assets"),
"@/composables": path.resolve(__dirname, "../src/composables"),
"@/api": path.resolve(__dirname, "../src/api"),
"@/stores": path.resolve(__dirname, "../src/stores"),
"@/hooks": path.resolve(__dirname, "../src/hooks"),
},
sourceRoot: 'src',
outputRoot: 'dist',
plugins: ['@tarojs/plugin-html', 'taro-plugin-pinia',],
defineConstants: {
},
copy: {
patterns: [
],
options: {
}
},
framework: 'vue3',
compiler: {
type: 'webpack5',
prebundle: { enable: false }
},
sass:{
data: `@import "@nutui/nutui-taro/dist/styles/variables.scss";`
},
mini: {
webpackChain(chain) {
chain.plugin('unplugin-vue-components').use(Components({
resolvers: [NutUIResolver({taro: true})]
}))
},
postcss: {
pxtransform: {
enable: true,
config: {
// selectorBlackList: ['nut-']
}
},
url: {
enable: true,
config: {
limit: 1024 // 设定转换尺寸上限
}
},
cssModules: {
enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
config: {
namingPattern: 'module', // 转换模式,取值为 global/module
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
}
},
h5: {
webpackChain(chain) {
chain.plugin('unplugin-vue-components').use(Components({
resolvers: [NutUIResolver({taro: true})]
}))
},
publicPath: '/',
staticDirectory: 'static',
esnextModules: ['nutui-taro', 'icons-vue-taro'],
postcss: {
autoprefixer: {
enable: true,
config: {
}
},
cssModules: {
enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
config: {
namingPattern: 'module', // 转换模式,取值为 global/module
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
}
}
}
module.exports = function (merge) {
if (process.env.NODE_ENV === 'development') {
return merge({}, config, require('./dev'))
}
return merge({}, config, require('./prod'))
}
module.exports = {
env: {
NODE_ENV: '"production"'
},
defineConstants: {
},
mini: {},
h5: {
/**
* WebpackChain 插件配置
* @docs https://github.com/neutrinojs/webpack-chain
*/
// webpackChain (chain) {
// /**
// * 如果 h5 端编译后体积过大,可以使用 webpack-bundle-analyzer 插件对打包体积进行分析。
// * @docs https://github.com/webpack-contrib/webpack-bundle-analyzer
// */
// chain.plugin('analyzer')
// .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [])
// /**
// * 如果 h5 端首屏加载时间过长,可以使用 prerender-spa-plugin 插件预加载首页。
// * @docs https://github.com/chrisvfritz/prerender-spa-plugin
// */
// const path = require('path')
// const Prerender = require('prerender-spa-plugin')
// const staticDir = path.join(__dirname, '..', 'dist')
// chain
// .plugin('prerender')
// .use(new Prerender({
// staticDir,
// routes: [ '/pages/index/index' ],
// postProcess: (context) => ({ ...context, outputPath: path.join(staticDir, 'index.html') })
// }))
// }
}
}
{
"name": "meihuaApp",
"version": "1.0.0",
"private": true,
"description": "梅花岛小程序",
"templateInfo": {
"name": "vue3-NutUI4",
"typescript": false,
"css": "less"
},
"scripts": {
"build:weapp": "taro build --type weapp",
"build:swan": "taro build --type swan",
"build:alipay": "taro build --type alipay",
"build:tt": "taro build --type tt",
"build:h5": "taro build --type h5",
"build:rn": "taro build --type rn",
"build:qq": "taro build --type qq",
"build:jd": "taro build --type jd",
"build:quickapp": "taro build --type quickapp",
"dev:weapp": "npm run build:weapp -- --watch",
"dev:swan": "npm run build:swan -- --watch",
"dev:alipay": "npm run build:alipay -- --watch",
"dev:tt": "npm run build:tt -- --watch",
"dev:h5": "npm run build:h5 -- --watch",
"dev:rn": "npm run build:rn -- --watch",
"dev:qq": "npm run build:qq -- --watch",
"dev:jd": "npm run build:jd -- --watch",
"dev:quickapp": "npm run build:quickapp -- --watch"
},
"browserslist": [
"last 3 versions",
"Android >= 4.1",
"ios >= 8"
],
"author": "",
"dependencies": {
"@babel/runtime": "^7.7.7",
"@nutui/icons-vue-taro": "^0.0.9",
"@nutui/nutui-taro": "^4.0.4",
"@tarojs/components": "3.6.5",
"@tarojs/extend": "^3.6.20",
"@tarojs/helper": "3.6.5",
"@tarojs/plugin-framework-react": "^3.6.20",
"@tarojs/plugin-framework-vue3": "3.6.5",
"@tarojs/plugin-html": "3.6.5",
"@tarojs/plugin-platform-alipay": "3.6.5",
"@tarojs/plugin-platform-h5": "3.6.5",
"@tarojs/plugin-platform-jd": "3.6.5",
"@tarojs/plugin-platform-qq": "3.6.5",
"@tarojs/plugin-platform-swan": "3.6.5",
"@tarojs/plugin-platform-tt": "3.6.5",
"@tarojs/plugin-platform-weapp": "3.6.5",
"@tarojs/runtime": "3.6.5",
"@tarojs/shared": "3.6.5",
"@tarojs/taro": "3.6.5",
"axios-miniprogram": "^2.7.0",
"pinia": "^2.1.7",
"qs": "^6.11.2",
"taro-plugin-pinia": "^1.0.0",
"vue": "^3.2.40"
},
"devDependencies": {
"@babel/core": "^7.8.0",
"@tarojs/cli": "3.6.5",
"@tarojs/taro-loader": "3.6.5",
"@tarojs/webpack5-runner": "3.6.5",
"@types/node": "^18.15.11",
"@types/webpack-env": "^1.13.6",
"@vue/babel-plugin-jsx": "^1.0.6",
"@vue/compiler-sfc": "^3.2.40",
"babel-preset-taro": "3.6.5",
"css-loader": "3.4.2",
"eslint": "^8.12.0",
"eslint-config-taro": "3.6.5",
"eslint-plugin-vue": "^8.0.0",
"style-loader": "1.3.0",
"stylelint": "9.3.0",
"ts-node": "^10.9.1",
"typescript": "^4.1.0",
"unplugin-vue-components": "^0.23.0",
"vue-loader": "^17.0.0",
"webpack": "^5.78.0"
}
}
{
"miniprogramRoot": "./dist",
"projectname": "meihuaApp",
"description": "梅花岛小程序",
"appid": "touristappid",
"setting": {
"urlCheck": true,
"es6": false,
"enhance": false,
"compileHotReLoad": false,
"postcss": false,
"minified": false
},
"compileType": "miniprogram"
}
{
"miniprogramRoot": "./",
"projectname": "meihuaApp",
"description": "梅花岛小程序",
"appid": "touristappid",
"setting": {
"urlCheck": true,
"es6": false,
"postcss": false,
"minified": false
},
"compileType": "miniprogram"
}
/*
* @Date: 2022-10-20 13:15:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-10-28 17:34:06
* @FilePath: /swx/src/api/Activity/index.js
* @Description: 活动信息
*/
import { fn, fetch } from '../fn';
const Api = {
ACTIVITY_JOIN_LIST: '/srv/?a=activity_join_list',
ACTIVITY_ADD_LIST: '/srv/?a=activity_add_list',
ACTIVITY_COPY: '/srv/?a=activity_copy',
ACTIVITY_END: '/srv/?a=activity_end',
ACTIVITY_DEL: '/srv/?a=activity_del',
ACTIVITY_QRCODE: '/srv/?a=activity_info_qrcode',
}
/**
* @description: 我加入的活动列表
* @returns
*/
export const joinListAPI = (params) => fn(fetch.get(Api.ACTIVITY_JOIN_LIST, params));
/**
* @description: 我创建的活动列表
* @returns
*/
export const addListAPI = (params) => fn(fetch.get(Api.ACTIVITY_ADD_LIST, params));
/**
* @description: 复制活动
* @returns
*/
export const copyActivityAPI = (params) => fn(fetch.get(Api.ACTIVITY_COPY, params));
/**
* @description: 结束活动
* @returns
*/
export const endActivityAPI = (params) => fn(fetch.get(Api.ACTIVITY_END, params));
/**
* @description: 删除活动
* @returns
*/
export const delActivityAPI = (params) => fn(fetch.get(Api.ACTIVITY_DEL, params));
/**
* @description: 生成小程序码
* @returns
*/
export const qrCodeActivityAPI = (params) => fn(fetch.get(Api.ACTIVITY_QRCODE, params));
/*
* @Date: 2022-10-14 17:26:56
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-10-22 00:24:38
* @FilePath: /swx/src/api/Host/index.js
* @Description: 活动相关接口
*/
import { fn, fetch } from '../fn';
const Api = {
HOST_LIST: '/srv/?a=host_list',
HOST_INFO: '/srv/?a=host_info',
HOST_ADD: '/srv/?a=host_add',
HOST_EDIT: '/srv/?a=host_edit',
HOST_DELETE: '/srv/?a=host_del',
ACTIVITY_ADD: '/srv/?a=activity_add',
ACTIVITY_EDIT: '/srv/?a=activity_edit',
ACTIVITY_HOMEPAGE: '/srv/?a=activity_app_homepage',
ACTIVITY_INFO: '/srv/?a=activity_info',
}
/**
* @description: 主办方列表
* @returns
*/
export const hostListAPI = (params) => fn(fetch.get(Api.HOST_LIST, params));
/**
* @description: 主办方详情
* @returns
*/
export const hostInfoAPI = (params) => fn(fetch.get(Api.HOST_INFO, params));
/**
* @description: 新增主办方
* @returns
*/
export const addHostAPI = (params) => fn(fetch.post(Api.HOST_ADD, params));
/**
* @description: 修改主办方
* @returns
*/
export const editHostAPI = (params) => fn(fetch.post(Api.HOST_EDIT, params));
/**
* @description: 删除主办方
* @returns
*/
export const deleteHostAPI = (params) => fn(fetch.post(Api.HOST_DELETE, params));
/**
* @description: 新增活动
* @returns
*/
export const addActivityAPI = (params) => fn(fetch.post(Api.ACTIVITY_ADD, params));
/**
* @description: 修改活动
* @returns
*/
export const editActivityAPI = (params) => fn(fetch.post(Api.ACTIVITY_EDIT, params));
/**
* @description: 首页活动和轮播
* @returns
*/
export const activityHomeAPI = (params) => fn(fetch.get(Api.ACTIVITY_HOMEPAGE, params));
/**
* @description: 活动详情
* @returns
*/
export const activityInfoAPI = (params) => fn(fetch.get(Api.ACTIVITY_INFO, params));
/*
* @Date: 2022-10-20 13:15:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-10-25 10:33:03
* @FilePath: /swx/src/api/Member/index.js
* @Description: 主办方用户
*/
import { fn, fetch } from '../fn';
const Api = {
MEMBER_INFO: '/srv/?a=member_info',
MEMBER_LIST: '/srv/?a=member_list',
MEMBER_TRACE_LIST: '/srv/?a=member_my_trace_list',
MEMBER_EDIT: '/srv/?a=member_edit',
MEMBER_SET_ROLE: '/srv/?a=member_set_role',
}
/**
* @description: 用户详情
* @returns
*/
export const infoMemberAPI = (params) => fn(fetch.get(Api.MEMBER_INFO, params));
/**
* @description: 主办方用户列表
* @returns
*/
export const listMemberAPI = (params) => fn(fetch.get(Api.MEMBER_LIST, params));
/**
* @description: 我陪伴的用户列表
* @returns
*/
export const traceMemberAPI = (params) => fn(fetch.get(Api.MEMBER_TRACE_LIST, params));
/**
* @description: 修改用户资料
* @returns
*/
export const editMemberAPI = (params) => fn(fetch.post(Api.MEMBER_EDIT, params));
/**
* @description: 添加/删除成员
* @returns
*/
export const setRoleMemberAPI = (params) => fn(fetch.post(Api.MEMBER_SET_ROLE, params));
/*
* @Date: 2022-10-20 13:15:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-10-24 11:00:14
* @FilePath: /swx/src/api/Partner/index.js
* @Description: 陪伴用户
*/
import { fn, fetch } from '../fn';
const Api = {
ADD_PARTNER: '/srv/?a=partner_add',
}
/**
* @description: 新增陪伴记录
* @returns
*/
export const addPartnerAPI = (params) => fn(fetch.post(Api.ADD_PARTNER, params));
/*
* @Date: 2022-10-20 13:15:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-11-11 16:31:20
* @FilePath: /swx/src/api/Reg/index.js
* @Description: 报名信息
*/
import { fn, fetch } from '../fn';
const Api = {
MY_INFO: '/srv/?a=reg_my_info',
REG_ADD: '/srv/?a=reg_add',
REG_EDIT: '/srv/?a=reg_edit',
REG_CANCEL: '/srv/?a=reg_cancel',
REG_LIST: '/srv/?a=reg_list',
REG_STATUS: '/srv/?a=reg_set_status',
REG_CONFIRM_NOTICE: '/srv/?a=reg_confirm_notice',
}
/**
* @description: 我的报名详情
* @returns
*/
export const myInfoAPI = (params) => fn(fetch.post(Api.MY_INFO, params));
/**
* @description: 活动报名
* @returns
*/
export const addRegAPI = (params) => fn(fetch.post(Api.REG_ADD, params));
/**
* @description: 修改活动报名
* @returns
*/
export const editRegAPI = (params) => fn(fetch.post(Api.REG_EDIT, params));
/**
* @description: 取消活动报名
* @returns
*/
export const cancelRegAPI = (params) => fn(fetch.post(Api.REG_CANCEL, params));
/**
* @description: 活动报名列表
* @returns
*/
export const listRegAPI = (params) => fn(fetch.post(Api.REG_LIST, params));
/**
* @description: 修改活动状态
* @returns
*/
export const statusRegAPI = (params) => fn(fetch.post(Api.REG_STATUS, params));
/**
* @description: 确认已收到审核失败提醒
* @returns
*/
export const noticeRegAPI = (params) => fn(fetch.post(Api.REG_CONFIRM_NOTICE, params));
/*
* @Date: 2022-10-20 13:15:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-10-21 17:12:41
* @FilePath: /swx/src/api/User/index.js
* @Description: 用户信息
*/
import { fn, fetch } from '../fn';
const Api = {
USER_INFO: '/srv/?a=user_info',
USER_EDIT: '/srv/?a=user_edit',
}
/**
* @description: 我的信息
* @returns
*/
export const infoUserAPI = (params) => fn(fetch.get(Api.USER_INFO, params));
/**
* @description: 修改我的信息
* @returns
*/
export const editUserAPI = (params) => fn(fetch.post(Api.USER_EDIT, params));
/*
* @Date: 2022-06-17 14:54:29
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-18 22:18:46
* @FilePath: /tswj/src/api/common.js
* @Description: 通用接口
*/
import { fn, fetch, uploadFn } from '@/api/fn';
const Api = {
SMS: '/srv/?a=sms',
TOKEN: '/srv/?a=upload',
SAVE_FILE: '/srv/?a=upload&t=save_file',
}
/**
* @description: 发送验证码
* @param {*} phone 手机号码
* @returns
*/
export const smsAPI = (params) => fn(fetch.post(Api.SMS, params));
/**
* @description: 获取七牛token
* @param {*} filename 文件名
* @param {*} file 图片base64
* @returns
*/
export const qiniuTokenAPI = (params) => fn(fetch.stringifyPost(Api.TOKEN, params));
/**
* @description: 上传七牛
* @param {*}
* @returns
*/
export const qiniuUploadAPI = (url, data, config) => uploadFn(fetch.basePost(url, data, config));
/**
* @description: 保存图片
* @param {*} format
* @param {*} hash
* @param {*} height
* @param {*} width
* @param {*} filekey
* @returns
*/
export const saveFileAPI = (params) => fn(fetch.stringifyPost(Api.SAVE_FILE, params));
/*
* @Date: 2022-05-18 22:56:08
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-10-22 00:12:46
* @FilePath: /swx/src/api/fn.js
* @Description: 文件描述
*/
import axios from '@/utils/request';
import Taro from '@tarojs/taro'
import qs from 'Qs'
/**
* 网络请求功能函数
* @param {*} api 请求axios接口
* @returns 请求成功后,获取数据
*/
export const fn = (api) => {
return api
.then(res => {
if (res.data.code === 1) {
return res.data || true;
} else {
// tslint:disable-next-line: no-console
console.warn(res);
Taro.showToast({
title: res.data.msg,
icon: 'none',
duration: 2000
});
return false;
}
})
.catch(err => {
// tslint:disable-next-line: no-console
console.error(err);
return false;
})
.finally(() => { // 最终执行
})
}
/**
* 七牛返回格式
* @param {*} api
* @returns
*/
export const uploadFn = (api) => {
return api
.then(res => {
if (res.statusText === 'OK') {
return res.data || true;
} else {
// tslint:disable-next-line: no-console
console.warn(res);
Taro.showToast({
title: res.data.msg,
icon: 'none',
duration: 2000
});
return false;
}
})
.catch(err => {
// tslint:disable-next-line: no-console
console.error(err);
return false;
})
}
/**
* 统一 GET/POST 不同传参形式
*/
export const fetch = {
get: function (api, params) {
return axios.get(api, params)
},
post: function (api, params) {
return axios.post(api, params)
},
stringifyPost: function (api, params) {
return axios.post(api, qs.stringify(params))
},
basePost: function (url, data, config) {
return axios.post(url, data, config)
}
}
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-06-09 13:32:44
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-14 14:47:01
* @FilePath: /tswj/src/api/wx/config.js
* @Description:
*/
import { fn, fetch } from '@/api/fn';
const Api = {
WX_JSAPI: '/srv/?a=wx_share',
}
/**
* @description 获取微信CONFIG配置文件
* @param {*} url
* @returns {*} cfg
*/
export const wxJsAPI = (params) => fn(fetch.get(Api.WX_JSAPI, params));
/*
* @Date: 2022-06-13 14:18:57
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-13 14:27:21
* @FilePath: /tswj/src/api/wx/jsApiList.js
* @Description: 文件描述
*/
export const apiList = [
"updateAppMessageShareData",
"updateTimelineShareData",
"onMenuShareTimeline",
"onMenuShareAppMessage",
"onMenuShareQQ",
"onMenuShareWeibo",
"onMenuShareQZone",
"startRecord",
"stopRecord",
"onVoiceRecordEnd",
"playVoice",
"pauseVoice",
"stopVoice",
"onVoicePlayEnd",
"uploadVoice",
"downloadVoice",
"chooseImage",
"previewImage",
"uploadImage",
"downloadImage",
"translateVoice",
"getNetworkType",
"openLocation",
"getLocation",
"hideOptionMenu",
"showOptionMenu",
"hideMenuItems",
"showMenuItems",
"hideAllNonBaseMenuItem",
"showAllNonBaseMenuItem",
"closeWindow",
"scanQRCode",
"chooseWXPay",
"openProductSpecificView",
"addCard",
"chooseCard",
"openCard"
]
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-06-09 13:32:44
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-09 13:42:06
* @FilePath: /tswj/src/api/wx/config.js
* @Description:
*/
import { fn, fetch } from '@/api/fn';
const Api = {
WX_PAY: 'c/bill_paymentForBill.do',
}
/**
* @description 微信支付接口
* @param {*}
* @returns {*}
*/
export const wxPayAPI = (params) => fn(fetch.get(Api.WX_PAY, params));
/*
* @Date: 2023-12-14 17:45:15
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 17:51:09
* @FilePath: /meihuaApp/src/app.config.js
* @Description: 文件描述
*/
export default defineAppConfig({
pages: [
'pages/index/index',
'pages/book/index',
'pages/my/index',
],
subpackages: [ // 配置在tabBar中的页面不能分包写到subpackages中去
{
root: 'pages/demo',
pages: ['index'],
},
],
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#fff',
navigationBarTitleText: 'WeChat',
navigationBarTextStyle: 'black'
},
})
/*
* @Date: 2023-12-14 17:45:15
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 17:59:42
* @FilePath: /meihuaApp/src/app.js
* @Description: 文件描述
*/
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import './app.less'
const App = createApp({
onShow (options) {},
// 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
})
App.use(createPinia())
export default App
File mode changed
@namespace: 'meihua';
/* ============ 颜色 ============ */
// 主色调
@base-color: #199A74;
// 文字颜色
@base-font-color: #333333;
@sub-font-color: #999999;
// 定义一个映射
#colors() {
base-color: @base-color;
base-font-color: @base-font-color;
}
// 混合
.width100 {
width: 100%;
}
<template>
<view>
<text class="title">{{ counter.count }}</text>
<view class="button" @tap="onAdd">ADD</view>
</view>
</template>
<script>
import { useCounterStore } from '../stores/counter'
export default {
setup() {
const counter = useCounterStore()
const onAdd = () => {
counter.count++
// with autocompletion ✨
// counter.$patch({count: counter.count + 1})
// or using an action instead
// counter.increment()
}
return {
counter,
onAdd
}
}
}
</script>
<style>
.title {
font-size: 32px;
}
.button {
border: 1px solid lightgray;
padding: 5px 10px;
}
</style>
<template>
<canvas
type="2d"
:id="canvasId"
:style="`height: ${height}rpx; width:${width}rpx;
position: absolute;
${debug ? '' : 'transform:translate3d(-9999rpx, 0, 0)'}`"
/>
</template>
<script lang="ts">
import Taro from "@tarojs/taro"
import { defineComponent, onMounted, PropType, ref } from "vue"
import { Image, DrawConfig } from "./types"
import { drawImage, drawText, drawBlock, drawLine } from "./utils/draw"
import {
toPx,
toRpx,
getRandomId,
getImageInfo,
getLinearColor,
} from "./utils/tools"
export default defineComponent({
name: "PosterBuilder",
props: {
showLoading: {
type: Boolean,
default: false,
},
config: {
type: Object as PropType<DrawConfig>,
default: () => ({}),
},
},
emits: ["success", "fail"],
setup(props, context) {
const count = ref(1)
const {
width,
height,
backgroundColor,
texts = [],
blocks = [],
lines = [],
debug = false,
} = props.config || {}
const canvasId = getRandomId()
/**
* step1: 初始化图片资源
* @param {Array} images = imgTask
* @return {Promise} downloadImagePromise
*/
const initImages = (images: Image[]) => {
const imagesTemp = images.filter((item) => item.url)
const drawList = imagesTemp.map((item, index) =>
getImageInfo(item, index)
)
return Promise.all(drawList)
}
/**
* step2: 初始化 canvas && 获取其 dom 节点和实例
* @return {Promise} resolve 里返回其 dom 和实例
*/
const initCanvas = () =>
new Promise<any>((resolve) => {
setTimeout(() => {
const pageInstance = Taro.getCurrentInstance()?.page || {} // 拿到当前页面实例
const query = Taro.createSelectorQuery().in(pageInstance) // 确定在当前页面内匹配子元素
query
.select(`#${canvasId}`)
.fields({ node: true, size: true, context: true }, (res) => {
const canvas = res.node
const ctx = canvas.getContext("2d")
resolve({ ctx, canvas })
})
.exec()
}, 300)
})
/**
* @description 保存绘制的图片
* @param { object } config
*/
const getTempFile = (canvas) => {
Taro.canvasToTempFilePath(
{
canvas,
success: (result) => {
Taro.hideLoading()
context.emit("success", result)
},
fail: (error) => {
const { errMsg } = error
if (errMsg === "canvasToTempFilePath:fail:create bitmap failed") {
count.value += 1
if (count.value <= 3) {
getTempFile(canvas)
} else {
Taro.hideLoading()
Taro.showToast({
icon: "none",
title: errMsg || "绘制海报失败",
})
context.emit("fail", errMsg)
}
}
},
},
context
)
}
/**
* step2: 开始绘制任务
* @param { Array } drawTasks 待绘制任务
*/
const startDrawing = async (drawTasks) => {
// TODO: check
// const configHeight = getHeight(config)
const { ctx, canvas } = await initCanvas()
canvas.width = width
canvas.height = height
// 设置画布底色
if (backgroundColor) {
ctx.save() // 保存绘图上下文
const grd = getLinearColor(ctx, backgroundColor, 0, 0, width, height)
ctx.fillStyle = grd // 设置填充颜色
ctx.fillRect(0, 0, width, height) // 填充一个矩形
ctx.restore() // 恢复之前保存的绘图上下文
}
// 将要画的方块、文字、线条放进队列数组
const queue = drawTasks
.concat(
texts.map((item) => {
item.type = "text"
item.zIndex = item.zIndex || 0
return item
})
)
.concat(
blocks.map((item) => {
item.type = "block"
item.zIndex = item.zIndex || 0
return item
})
)
.concat(
lines.map((item) => {
item.type = "line"
item.zIndex = item.zIndex || 0
return item
})
)
queue.sort((a, b) => a.zIndex - b.zIndex) // 按照层叠顺序由低至高排序, 先画低的,再画高的
for (let i = 0; i < queue.length; i++) {
const drawOptions = {
canvas,
ctx,
toPx,
toRpx,
}
if (queue[i].type === "image") {
await drawImage(queue[i], drawOptions)
} else if (queue[i].type === "text") {
drawText(queue[i], drawOptions)
} else if (queue[i].type === "block") {
drawBlock(queue[i], drawOptions)
} else if (queue[i].type === "line") {
drawLine(queue[i], drawOptions)
}
}
setTimeout(() => {
getTempFile(canvas) // 需要做延时才能能正常加载图片
}, 300)
}
// start: 初始化 canvas 实例 && 下载图片资源
const init = () => {
if (props.showLoading)
Taro.showLoading({ mask: true, title: "生成中..." })
if (props.config?.images?.length) {
initImages(props.config.images)
.then((result) => {
// 1. 下载图片资源
startDrawing(result)
})
.catch((err) => {
Taro.hideLoading()
Taro.showToast({
icon: "none",
title: err.errMsg || "下载图片失败",
})
context.emit("fail", err)
})
} else {
startDrawing([])
}
}
onMounted(() => {
init()
})
return {
canvasId,
debug,
width,
height,
}
},
})
</script>
export type DrawType = 'text' | 'image' | 'block' | 'line';
export interface Block {
type?: DrawType;
x: number;
y: number;
width?: number;
height: number;
paddingLeft?: number;
paddingRight?: number;
borderWidth?: number;
borderColor?: string;
backgroundColor?: string;
borderRadius?: number;
borderRadiusGroup?: number[];
text?: Text;
opacity?: number;
zIndex?: number;
}
export interface Text {
type?: DrawType;
x?: number;
y?: number;
text: string | Text[];
fontSize?: number;
color?: string;
opacity?: 1 | 0;
lineHeight?: number;
lineNum?: number;
width?: number;
marginTop?: number;
marginLeft?: number;
marginRight?: number;
textDecoration?: 'line-through' | 'none';
baseLine?: 'top' | 'middle' | 'bottom';
textAlign?: 'left' | 'center' | 'right';
fontFamily?: string;
fontWeight?: string;
fontStyle?: string;
zIndex?: number;
}
export interface Image {
type?: DrawType;
x: number;
y: number;
url: string;
width: number;
height: number;
borderRadius?: number;
borderRadiusGroup?: number[];
borderWidth?: number;
borderColor?: string;
zIndex?: number;
}
export interface Line {
type?: DrawType;
startX: number;
startY: number;
endX: number;
endY: number;
width: number;
color?: string;
zIndex?: number;
}
export type DrawConfig = {
width: number;
height: number;
backgroundColor?: string;
debug?: boolean;
blocks?: Block[];
texts?: Text[];
images?: Image[];
lines?: Line[];
};
This diff is collapsed. Click to expand it.
/* eslint-disable prefer-destructuring */
import Taro, { CanvasContext, CanvasGradient } from '@tarojs/taro';
declare const wx: any;
/**
* @description 生成随机字符串
* @param { number } length - 字符串长度
* @returns { string }
*/
export function randomString(length) {
let str = Math.random().toString(36).substr(2);
if (str.length >= length) {
return str.substr(0, length);
}
str += randomString(length - str.length);
return str;
}
/**
* 随机创造一个id
* @param { number } length - 字符串长度
* @returns { string }
*/
export function getRandomId(prefix = 'canvas', length = 10) {
return prefix + randomString(length);
}
/**
* @description 获取最大高度
* @param {} config
* @returns { number }
*/
// export function getHeight (config) {
// const getTextHeight = text => {
// const fontHeight = text.lineHeight || text.fontSize
// let height = 0
// if (text.baseLine === 'top') {
// height = fontHeight
// } else if (text.baseLine === 'middle') {
// height = fontHeight / 2
// } else {
// height = 0
// }
// return height
// }
// const heightArr: number[] = [];
// (config.blocks || []).forEach(item => {
// heightArr.push(item.y + item.height)
// });
// (config.texts || []).forEach(item => {
// let height
// if (Object.prototype.toString.call(item.text) === '[object Array]') {
// item.text.forEach(i => {
// height = getTextHeight({ ...i, baseLine: item.baseLine })
// heightArr.push(item.y + height)
// })
// } else {
// height = getTextHeight(item)
// heightArr.push(item.y + height)
// }
// });
// (config.images || []).forEach(item => {
// heightArr.push(item.y + item.height)
// });
// (config.lines || []).forEach(item => {
// heightArr.push(item.startY)
// heightArr.push(item.endY)
// })
// const sortRes = heightArr.sort((a, b) => b - a)
// let canvasHeight = 0
// if (sortRes.length > 0) {
// canvasHeight = sortRes[0]
// }
// if (config.height < canvasHeight || !config.height) {
// return canvasHeight
// }
// return config.height
// }
/**
* 将http转为https
* @param {String}} rawUrl 图片资源url
* @returns { string }
*/
export function mapHttpToHttps(rawUrl) {
if (rawUrl.indexOf(':') < 0 || rawUrl.startsWith('http://tmp')) {
return rawUrl;
}
const urlComponent = rawUrl.split(':');
if (urlComponent.length === 2) {
if (urlComponent[0] === 'http') {
urlComponent[0] = 'https';
return `${urlComponent[0]}:${urlComponent[1]}`;
}
}
return rawUrl;
}
/**
* 获取 rpx => px 的转换系数
* @returns { number } factor 单位转换系数 1rpx = factor * px
*/
export const getFactor = () => {
const sysInfo = Taro.getSystemInfoSync();
const { screenWidth } = sysInfo;
return screenWidth / 750;
};
/**
* rpx => px 单位转换
* @param { number } rpx - 需要转换的数值
* @param { number } factor - 转化因子
* @returns { number }
*/
export const toPx = (rpx, factor = getFactor()) =>
parseInt(String(rpx * factor), 10);
/**
* px => rpx 单位转换
* @param { number } px - 需要转换的数值
* @param { number } factor - 转化因子
* @returns { number }
*/
export const toRpx = (px, factor = getFactor()) =>
parseInt(String(px / factor), 10);
/**
* 下载图片资源
* @param { string } url
* @returns { Promise }
*/
export function downImage(url) {
return new Promise<string>((resolve, reject) => {
// eslint-disable-next-line no-undef
if (/^http/.test(url) && !new RegExp(wx.env.USER_DATA_PATH).test(url)) {
// wx.env.USER_DATA_PATH 文件系统中的用户目录路径
Taro.downloadFile({
url: mapHttpToHttps(url),
success: (res) => {
if (res.statusCode === 200) {
resolve(res.tempFilePath);
} else {
console.log('下载失败', res);
reject(res);
}
},
fail(err) {
console.log('下载失败了', err);
reject(err);
}
});
} else {
resolve(url); // 支持本地地址
}
});
}
/**
* 下载图片并获取图片信息
* @param {} item 图片参数信息
* @param {} index 图片下标
* @returns { Promise } result 整理后的图片信息
*/
export const getImageInfo = (item, index) =>
new Promise((resolve, reject) => {
const { x, y, width, height, url, zIndex } = item;
downImage(url).then((imgPath) =>
Taro.getImageInfo({ src: imgPath })
.then((imgInfo) => {
// 获取图片信息
// 根据画布的宽高计算出图片绘制的大小,这里会保证图片绘制不变形, 即宽高比不变,截取再拉伸
let sx; // 截图的起点 x 坐标
let sy; // 截图的起点 y 坐标
const borderRadius = item.borderRadius || 0;
const imgWidth = toRpx(imgInfo.width); // 图片真实宽度 单位 px
const imgHeight = toRpx(imgInfo.height); // 图片真实高度 单位 px
// 根据宽高比截取图片
if (imgWidth / imgHeight <= width / height) {
sx = 0;
sy = (imgHeight - (imgWidth / width) * height) / 2;
} else {
sy = 0;
sx = (imgWidth - (imgHeight / height) * width) / 2;
}
// 给 canvas 画图准备参数,详见 ./draw.ts-drawImage
const result = {
type: 'image',
borderRadius,
borderWidth: item.borderWidth,
borderColor: item.borderColor,
borderRadiusGroup: item.borderRadiusGroup,
zIndex: typeof zIndex !== 'undefined' ? zIndex : index,
imgPath: url,
sx,
sy,
sw: imgWidth - sx * 2,
sh: imgHeight - sy * 2,
x,
y,
w: width,
h: height
};
resolve(result);
})
.catch((err) => {
console.log('读取图片信息失败', err);
reject(err);
})
);
});
/**
* 获取线性渐变色
* @param {CanvasContext} ctx canvas 实例对象
* @param {String} color 线性渐变色,如 'linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #fff 100%)'
* @param {Number} startX 起点 x 坐标
* @param {Number} startY 起点 y 坐标
* @param {Number} w 宽度
* @param {Number} h 高度
* @returns {}
*/
// TODO: 待优化, 支持所有角度,多个颜色的线性渐变
export function getLinearColor(
ctx: CanvasContext,
color,
startX,
startY,
w,
h
) {
if (
typeof startX !== 'number' ||
typeof startY !== 'number' ||
typeof w !== 'number' ||
typeof h !== 'number'
) {
console.warn('坐标或者宽高只支持数字');
return color;
}
let grd: CanvasGradient | string = color;
if (color.includes('linear-gradient')) {
// fillStyle 不支持线性渐变色
const colorList = color.match(/\((\d+)deg,\s(.+)\s\d+%,\s(.+)\s\d+%/);
const radian = colorList[1]; // 渐变弧度(角度)
const color1 = colorList[2];
const color2 = colorList[3];
const L = Math.sqrt(w * w + h * h);
const x = Math.ceil(Math.sin(180 - radian) * L);
const y = Math.ceil(Math.cos(180 - radian) * L);
// 根据弧度和宽高确定渐变色的两个点的坐标
if (Number(radian) === 180 || Number(radian) === 0) {
if (Number(radian) === 180) {
grd = ctx.createLinearGradient(startX, startY, startX, startY + h);
}
if (Number(radian) === 0) {
grd = ctx.createLinearGradient(startX, startY + h, startX, startY);
}
} else if (radian > 0 && radian < 180) {
grd = ctx.createLinearGradient(startX, startY, x + startX, y + startY);
} else {
throw new Error('只支持0 <= 颜色弧度 <= 180');
}
(grd as CanvasGradient).addColorStop(0, color1);
(grd as CanvasGradient).addColorStop(1, color2);
}
return grd;
}
/**
* 根据文字对齐方式设置坐标
* @param {*} imgPath
* @param {*} index
* @returns { Promise }
*/
export function getTextX(textAlign, x, width) {
let newX = x;
if (textAlign === 'center') {
newX = width / 2 + x;
} else if (textAlign === 'right') {
newX = width + x;
}
return newX;
}
<!--
* @Date: 2023-12-12 11:48:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 10:04:36
* @FilePath: /meihua-island-book/src/components/activity-editor.vue
* @Description: 文件描述
-->
<!--
* @Date: 2022-09-26 21:52:25
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-10-28 17:24:17
* @FilePath: /swx/src/components/activity-editor.vue
* @Description: 文件描述
-->
<template>
<view class="editor-box">
<view class="editor-box-header" v-if="showTabBar">
<view class="operate-box" @tap="_addImage">
<text class="iconfont icon-image"></text>
</view>
<view class="operate-box" @tap="_addItalic">
<text class="iconfont icon-italic"></text>
</view>
<view class="operate-box" @tap="_addBold">
<text class="iconfont icon-bold"></text>
</view>
<view class="operate-box" data-header="h1" @tap="_addHeader">
<text class="iconfont icon-h1"></text>
</view>
<view class="operate-box" data-header="h2" @tap="_addHeader">
<text class="iconfont icon-h2"></text>
</view>
<!-- <view class="operate-box" data-header="h3" @tap="_addHeader">
<text class="iconfont icon-h3"></text>
</view> -->
<view class="operate-box" data-align="left" @tap="_addAlign">
<text class="iconfont icon-alignLeft"></text>
</view>
<view class="operate-box" data-align="center" @tap="_addAlign">
<text class="iconfont icon-juzhong"></text>
</view>
<view class="operate-box" data-align="right" @tap="_addAlign">
<text class="iconfont icon-alignRight"></text>
</view>
<view class="operate-box" data-list="ordered" @tap="_addList">
<text class="iconfont icon-orderedList"></text>
</view>
<view class="operate-box" data-list="bullet" @tap="_addList">
<text class="iconfont icon-unorderedList"></text>
</view>
<view class="operate-box" @tap="_undo">
<text class="iconfont icon-undo"></text>
</view>
</view>
<view class="editor-box-content">
<editor id="editor" :name="name" :placeholder="placeholder" @ready="_onEditorReady" @input="_onInputting"
:show-img-resize="true"></editor>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
</script>
<script>
import Taro from '@tarojs/taro'
import BASE_URL from '@/utils/config';
import { activityInfoAPI } from '@/api/Host/index';
import { getCurrentPageParam } from "@/utils/weapp";
export default {
props: ['showTabBar', 'placeholder', 'name', 'htmlContent'],
data() {
return {
editorCtx: '',
html_content: ''
}
},
watch: {
async htmlContent (val) {
// 如果有传值,还原重新编辑
if (val) {
const { code, data } = await activityInfoAPI({ i: getCurrentPageParam().id });
if (code) {
// 更新活动信息
this.html_content = data.activity.note
this._onEditorReady()
}
}
}
},
methods: {
_onEditorReady: function () {
const that = this;
setTimeout(() => {
wx.createSelectorQuery().select('#editor').context(function (res) {
that.editorCtx = res.context;
that.editorCtx.setContents({
html: that.html_content //将数据写入编辑器内
})
}).exec();
}, 500);
},
//插入图片
_addImage: function (event) {
let _this = this;
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album'],
success: function (res) {
wx.showLoading({
title: '上传中',
mask: true
});
// _this._uploadImage(res.tempFilePaths[0], event.currentTarget.dataset.uploadimageurl);
_this._uploadImage(res.tempFilePaths[0], BASE_URL + '/admin/?m=srv&a=upload');
}
});
},
_uploadImage: function (tempFilePath, uploadImageURL) {
let _this = this;
wx.uploadFile({
url: uploadImageURL,
filePath: tempFilePath,
name: 'file',
header: {
'content-type': 'multipart/form-data',
},
success: function (res) {
let upload_data = JSON.parse(res.data);
wx.hideLoading({
success: () => {
if (res.statusCode === 200) {
_this.editorCtx.insertImage({
src: upload_data.data.src
});
} else {
wx.showToast({
icon: 'error',
title: '服务器错误,稍后重试!',
mask: true
})
}
},
});
}
});
},
//设置斜体
_addItalic: function () {
this.editorCtx.format("italic")
},
//添加粗体样式
_addBold: function () {
this.editorCtx.format("bold")
},
//设置标题
_addHeader: function (e) {
let headerType = e.currentTarget.dataset.header;
this.editorCtx.format("header", headerType)
},
//设置文字的排列方式
_addAlign: function (e) {
let alignType = e.currentTarget.dataset.align;
this.editorCtx.format("align", alignType);
},
//设置列表
_addList: function (e) {
let listType = e.currentTarget.dataset.list;
this.editorCtx.format("list", listType);
},
//撤销
_undo: function () {
this.editorCtx.undo();
},
//监控输入
_onInputting: function (e) {
this.$emit('on-input', e.detail)
// let html = e.detail.html;
// let text = e.detail.text;
// this.triggerEvent("input", { html: html, text: text }, {});
// console.warn(html);
// console.warn(text);
},
_rewrite (val) {
// 如果有传值,还原重新编辑
this.editorCtx.setContents({
html: val
})
}
}
}
</script>
<style lang="less">
/* components/hg-editor/hg-editor.wxss */
@import "./iconfont.less";
@import "./iconfont1.less";
.editor-box {
width: 100%;
padding: 0;
box-sizing: border-box;
background-color: #fff;
border: 2px solid #f6f6f6;
}
.editor-box-header,
.editor-box-content {
width: 100%;
}
.editor-box-header {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: flex-start;
padding: 20rpx 20rpx;
box-sizing: border-box;
border-bottom: 2rpx solid #f6f6f6;
background-color: #f6f6f6;
}
.editor-box-header>.operate-box {
margin-right: 20rpx;
width: 40rpx;
height: 40rpx;
overflow: hidden;
color: gray;
}
.editor-box-content {
padding: 20rpx;
box-sizing: border-box;
}
</style>
<!--
* @Date: 2022-09-28 10:43:53
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-28 11:07:39
* @FilePath: /swx/src/components/bottom-button.vue
* @Description: 文件描述
-->
<template>
<view class="confirm-wrapper-page">
<view class="box">
<view @tap="onSubmit" class="button"><slot></slot></view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const emit = defineEmits(['on-submit'])
const onSubmit = () => {
emit('on-submit', true)
}
</script>
<style lang="less">
.confirm-wrapper-page {
background-color: #FFFFFF;
box-shadow: 0rem -0.17rem 0.67rem 0rem rgba(0,0,0,0.05);
position: fixed;
bottom: 0;
width: 100%;
.box {
padding: 1rem 0;
margin: 1rem;
padding-bottom: 2rem;
margin-top: 0;
text-align: center;
.button {
color: #FFFFFF;
background-color: #199A74;
padding: 0.65rem 1rem;
border-radius: 1.5rem;
}
}
}
</style>
<!--
* @Date: 2023-12-14 10:04:23
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 18:25:51
* @FilePath: /meihuaApp/src/components/calendarSelect.vue
* @Description: 文件描述
-->
<template>
<view class="calendar-select-page" @tap="openCalendar">
<nut-row gutter="10">
<nut-col span="10">
<view style="color: #7D7C7C; font-size: 0.8rem;">入住日期</view>
<view style="color: #6A4925; font-size: 0.95rem; font-weight: bold;">2023.12.07 星期四</view>
</nut-col>
<nut-col span="4">
<view style="color: #6A4925; margin-top: 15%; font-size: 0.8rem; text-align: center; background-color: #fff; padding: 0.25rem 0; border-radius: 0.5rem;">
共1晚
</view>
</nut-col>
<nut-col span="10">
<view style="color: #7D7C7C; font-size: 0.8rem;">退房日期</view>
<view style="color: #6A4925; font-size: 0.95rem; font-weight: bold;">2023.12.08 星期五</view>
</nut-col>
</nut-row>
</view>
<nut-calendar
v-model:visible="state.isVisible"
:default-value="state.date"
type="range"
:start-date="`2019-12-22`"
:end-date="`2021-01-08`"
@close="closeSwitch('isVisible')"
@choose="setChooseValue"
@select="select"
>
</nut-calendar>
</template>
<script setup>
import { ref, reactive } from 'vue'
const state = reactive({
date: ['2019-12-23', '2019-12-26'],
isVisible: false
});
const openSwitch = (param) => {
state[`${param}`] = true;
};
const closeSwitch = (param) => {
state[`${param}`] = false;
};
const setChooseValue = (param) => {
// state.date = [...[param[0][3], param[1][3]]];
console.warn(param);
};
const select = (param) => {
console.warn(param);
};
const show = ref(false);
const openCalendar = () => {
show.value = true;
state.isVisible = true;
}
const onClose = () => {
show.value = false
}
const onConfirm = (event) => {
console.warn(event);
}
</script>
<style lang="less">
.calendar-select-page {
background-color: #F6ECE1;
border-radius: 0.5rem;
padding: 1rem;
}
</style>
@font-face {
font-family: 'iconfont'; /* Project id 2549449 */
src: url('//at.alicdn.com/t/font_2549449_hxmflg4qsr6.woff2?t=1621002720450') format('woff2'),
url('//at.alicdn.com/t/font_2549449_hxmflg4qsr6.woff?t=1621002720450') format('woff'),
url('//at.alicdn.com/t/font_2549449_hxmflg4qsr6.ttf?t=1621002720450') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 38rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-undo:before {
content: "\e609";
}
.icon-hr:before {
content: "\e60a";
}
.icon-h3:before {
content: "\e60b";
}
.icon-quote:before {
content: "\e60c";
}
.icon-bold:before {
content: "\e60e";
}
.icon-orderedList:before {
content: "\e612";
}
.icon-h2:before {
content: "\e61a";
}
.icon-italic:before {
content: "\e61c";
}
.icon-unorderedList:before {
content: "\e620";
}
.icon-alignLeft:before {
content: "\e621";
}
.icon-alignRight:before {
content: "\e622";
}
.icon-alignCenter:before {
content: "\e623";
}
.icon-h1:before {
content: "\e623";
}
.icon-image:before {
content: "\e629";
}
No preview for this file type
@font-face {
font-family: "iconfont"; /* Project id */
src: url('iconfont.ttf?t=1666948927665') format('truetype');
}
// .iconfont {
// font-family: "iconfont" !important;
// font-size: 16px;
// font-style: normal;
// -webkit-font-smoothing: antialiased;
// -moz-osx-font-smoothing: grayscale;
// }
.icon-juzhong:before {
content: "\e7db";
}
1. 列表组件
2. 列表内容展示组件
2. 日期选择组件
<!--
* @Date: 2022-09-21 11:59:20
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 18:15:06
* @FilePath: /meihuaApp/src/components/navBar.vue
* @Description: 底部导航栏
-->
<template>
<view id="navbar-page" class="navbar-page">
<view @tap="goTo('index')" class="home">
<view style="height: 2rem;">
<IconFont :name="icon_home" size="2rem" color="" />
</view>
<view><text :style="homeStyle">首页</text></view>
</view>
<view @tap="goTo('book')" class="book">
<view style="height: 2rem;">
<IconFont :name="icon_add" size="2rem" color="" />
</view>
<view><text :style="bookStyle">订房</text></view>
</view>
<view @tap="goTo('my')" class="my">
<view style="height: 2rem;">
<IconFont :name="icon_my" size="2rem" color="" />
</view>
<view><text :style="myStyle">我的</text></view>
</view>
</view>
</template>
<script setup>
import Taro from '@tarojs/taro'
import { ref, defineProps, computed, onMounted } from 'vue'
import icon_home1 from '@/images/icon/home01@2x.png'
import icon_home2 from '@/images/icon/home02@2x.png'
import icon_my1 from '@/images/icon/my01@2x.png'
import icon_my2 from '@/images/icon/my02@2x.png'
import icon_add from '@/images/icon/new@2x.png'
import { hostListAPI } from '@/api/Host/index'
import { IconFont } from '@nutui/icons-vue-taro';
const goTo = (page) => {
if (props.activated === page) {
return;
}
wx.redirectTo({
url: `../${page}/index`
});
}
// const createActivity = async () => {
// // 获取主办方列表信息
// const { code, data } = await hostListAPI();
// if (code) {
// if (!data.my_hosts.length) { // 主办方为空
// Taro.showModal({
// title: '温馨提示',
// content: '请先创建主办方后新建活动',
// success: function (res) {
// if (res.confirm) {
// Taro.navigateTo({
// url: '../createProject/index'
// });
// }
// }
// });
// } else {
// Taro.navigateTo({
// url: '../createActivity/index'
// })
// }
// }
// }
const currentPage = ref('');
onMounted(() => {
let pages = getCurrentPages();
let current_page = pages[pages.length - 1];
let url = current_page.route;
if (url == 'pages/index/index') {
currentPage.value = 'index'
} else {
currentPage.value = 'my'
}
})
const props = defineProps({
activated: String,
})
const homeStyle = ref({})
const myStyle = ref({})
const bookStyle = ref({})
const icon_home = computed(() => {
if (props.activated === 'index') {
return icon_home1
} else {
return icon_home2
}
})
const icon_my = computed(() => {
if (props.activated === 'index') {
return icon_my2
} else {
return icon_my1
}
})
if (props.activated === 'index') {
homeStyle.value = {
color: '#2A5F45',
fontSize: '0.9rem'
}
myStyle.value = {
color: '#999999',
fontSize: '0.9rem'
}
bookStyle.value = {
color: '#999999',
fontSize: '0.9rem'
}
} else {
homeStyle.value = {
color: '#999999',
fontSize: '0.9rem'
}
myStyle.value = {
color: '#2A5F45',
fontSize: '0.9rem'
}
bookStyle.value = {
color: '#2A5F45',
fontSize: '0.9rem'
}
}
</script>
<style lang="less">
.navbar-page {
position: fixed;
bottom: 0;
background-color: #FFFFFF;
padding-top: 0.5rem;
height: 5rem;
width: 100%;
.home {
position: absolute;
left: 15%;
transform: translateX(-15%);
text-align: center;
}
.book {
position: absolute;
left: 50%;
transform: translateX(-50%);
text-align: center;
}
.my {
position: absolute;
left: 85%;
transform: translateX(-85%);
text-align: center;
}
}
</style>
<!--
* @Date: 2023-12-13 13:42:23
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 18:23:08
* @FilePath: /meihuaApp/src/components/roomCard.vue
* @Description: 文件描述
-->
<template>
<div class="room-card-component">
<image style="width: 100%; height: 10rem;" mode="aspectFill" src="https://img.yzcdn.cn/vant/cat.jpeg" />
<view style="padding: 0.5rem;">
<nut-row>
<nut-col span="18">
<view style="color: #0B0B0B; font-weight: bold;">非凡魅力豪华总统套房</view>
<view style="color: #7D7C7C; font-size: 0.8rem;">两室 宜住3人</view>
</nut-col>
<nut-col span="6">
<view style="float: right; color: #EB2E2E; font-weight: bold; font-size: 1.1rem;">¥980</view>
<view style="float: right; color: #7D7C7C; font-size: 0.8rem; text-decoration: line-through;">¥1280</view>
</nut-col>
</nut-row>
</view>
</div>
</template>
<script setup>
import { ref } from 'vue'
import Taro from '@tarojs/taro'
</script>
<style lang="less">
.room-card-component {
margin: 1rem;
background-color: white;
box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.1);
border: 1px solid #f9f9f9;
border-radius: 0.5rem;
overflow: hidden;
}
.room-card-component img {
}
.room-card-component.nut-row {
// padding: 0.5rem;
}
</style>
var getDaysInOneMonth = function (year, month) {
let _month = parseInt(month, 10);
let d = new Date(year, _month, 0);
return d.getDate();
}
var dateDate = function (date) {
let year = date && date.getFullYear();
let month = date && date.getMonth() + 1;
let day = date && date.getDate();
let hours = date && date.getHours();
let minutes = date && date.getMinutes();
return {
year, month, day, hours, minutes
}
}
var dateTimePicker = function (startyear, endyear) {
// 获取date time 年份,月份,天数,小时,分钟推后30分
const years = [];
const months = [];
const hours = [];
const minutes = [];
for (let i = startyear; i <= endyear; i++) {
years.push({
name: i + '年',
id: i
});
}
//获取月份
for (let i = 1; i <= 12; i++) {
if (i < 10) {
i = "0" + i;
}
months.push({
name: i + '月',
id: i
});
}
//获取小时
for (let i = 0; i < 24; i++) {
if (i < 10) {
i = "0" + i;
}
hours.push({
name: i + '时',
id: i
});
}
//获取分钟
for (let i = 0; i < 60; i++) {
if (i < 10) {
i = "0" + i;
}
minutes.push({
name: i + '分',
id: i
});
}
return function (_year, _month) {
const days = [];
_year = parseInt(_year);
_month = parseInt(_month);
//获取日期
for (let i = 1; i <= getDaysInOneMonth(_year, _month); i++) {
if (i < 10) {
i = "0" + i;
}
days.push({
name: i + '日',
id: i
});
}
return [years, months, days, hours, minutes];
}
}
export {
dateTimePicker,
getDaysInOneMonth,
dateDate
}
<template>
<picker mode="multiSelector" :range-key="'name'" :value="timeIndex" :range="activityArray" :disabled="disabled"
@change="bindMultiPickerChange" @columnChange="bindMultiPickerColumnChange">
<slot />
</picker>
</template>
<script>
import { dateTimePicker, dateDate } from "./dateTimePicker.js";
export default {
props: {
startTime: {
type: [Object, Date],
default: new Date(),
},
endTime: {
type: [Object, Date],
default: new Date(),
},
defaultTime: {
type: [Object, Date],
default: new Date(),
},
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {
timeIndex: [0, 0, 0, 0, 0],
activityArray: [],
year: 0,
month: 1,
day: 1,
hour: 0,
minute: 0,
datePicker: "",
defaultIndex: [0, 0, 0, 0, 0],
startIndex: [0, 0, 0, 0, 0],
endIndex: [0, 0, 0, 0, 0],
};
},
computed: {
timeDate() {
const { startTime, endTime } = this;
return { startTime, endTime };
},
},
watch: {
timeDate() {
this.initData();
},
defaultTime () {
this.initData();
}
},
created() {
this.initData();
},
methods: {
initData() {
let startTime = this.startTime;
let endTime = this.endTime;
this.datePicker = dateTimePicker(
startTime.getFullYear(),
endTime.getFullYear()
);
this.setDateData(this.defaultTime);
this.getKeyIndex(this.startTime, "startIndex");
// 截止时间索引
this.getKeyIndex(this.endTime, "endIndex");
// 默认索引
this.getKeyIndex(this.defaultTime, "defaultIndex");
this.timeIndex = this.defaultIndex;
// 初始时间
this.initTime();
},
getKeyIndex(time, key) {
let Arr = dateDate(time);
let _index = this.getIndex(Arr);
this[key] = _index;
},
getIndex(arr) {
let timeIndex = [];
let indexKey = ["year", "month", "day", "hours", "minutes"];
this.activityArray.forEach((element, index) => {
let _index = element.findIndex(
(item) => parseInt(item.id) === parseInt(arr[indexKey[index]])
);
timeIndex[index] = _index >= 0 ? _index : 0;
});
return timeIndex;
},
initTime() {
let _index = this.timeIndex;
this.year = this.activityArray[0][_index[0]].id;
this.month = this.activityArray[1].length && this.activityArray[1][_index[1]].id;
this.day = this.activityArray[2].length && this.activityArray[2][_index[2]].id;
this.hour = this.activityArray[3].length && this.activityArray[3][_index[3]].id;
this.minute = this.activityArray[4].length && this.activityArray[4][_index[4]].id;
},
setDateData(_date) {
let _data = dateDate(_date);
this.activityArray = this.datePicker(_data.year, _data.month);
},
bindMultiPickerChange(e) {
console.log("picker发送选择改变,携带值为", e.detail.value);
let activityArray = JSON.parse(JSON.stringify(this.activityArray)),
{ value } = e.detail,
_result = [];
for (let i = 0; i < value.length; i++) {
_result[i] = activityArray[i][value[i]].id;
}
this.$emit("result", _result);
},
bindMultiPickerColumnChange(e) {
console.log("修改的列为", e.detail.column, ",值为", e.detail.value);
let _data = JSON.parse(JSON.stringify(this.activityArray)),
timeIndex = JSON.parse(JSON.stringify(this.timeIndex)),
{ startIndex, endIndex } = this,
{ column, value } = e.detail,
_value = _data[column][value].id,
_start = dateDate(this.startTime),
_end = dateDate(this.endTime);
switch (e.detail.column) {
case 0:
if (_value <= _start.year) {
timeIndex = startIndex;
this.year = _start.year;
this.setDateData(this.startTime);
} else if (_value >= _end.year) {
this.year = _end.year;
timeIndex = [endIndex[0], 0, 0, 0, 0];
this.setDateData(this.endTime);
} else {
this.year = _value;
timeIndex = [value, 0, 0, 0, 0];
this.activityArray = this.datePicker(_value, 1);
}
timeIndex = this.timeIndex = JSON.parse(JSON.stringify(timeIndex));
this.timeIndex = timeIndex;
break;
case 1:
if (this.year == _start.year && value <= startIndex[1]) {
timeIndex = startIndex;
this.month = _start.month;
this.setDateData(this.startTime);
} else if (this.year == _end.year && value >= endIndex[1]) {
timeIndex = endIndex;
this.month = _end.month;
this.setDateData(this.endTime);
} else {
this.month = _value;
_data[2] = this.datePicker(this.year, this.month)[2];
timeIndex = [timeIndex[0], value, 0, 0, 0];
this.activityArray = _data;
}
this.timeIndex = JSON.parse(JSON.stringify(timeIndex));
break;
case 2:
if (
this.year == _start.year &&
this.month == _start.month &&
value <= startIndex[2]
) {
this.day = _start.day;
timeIndex = startIndex;
} else if (
this.year == _end.year &&
this.month == _end.month &&
value >= endIndex[2]
) {
this.day = _end.day;
timeIndex = endIndex;
} else {
this.day = _value;
timeIndex = [timeIndex[0], timeIndex[1], value, 0, 0];
}
this.timeIndex = JSON.parse(JSON.stringify(timeIndex));
break;
case 3:
if (
this.year == _start.year &&
this.month == _start.month &&
this.day == _start.day &&
value <= startIndex[3]
) {
this.hour = _start.hours;
timeIndex = startIndex;
} else if (
this.year == _end.year &&
this.month == _end.month &&
this.day == _end.day &&
value >= endIndex[3]
) {
this.hour = _end.hours;
timeIndex = endIndex;
} else {
this.hour = _value;
timeIndex[3] = value;
timeIndex[4] = 0;
}
this.timeIndex = JSON.parse(JSON.stringify(timeIndex));
break;
case 4:
timeIndex[4] = value;
if (
this.year == _start.year &&
this.month == _start.month &&
this.day == _start.day &&
this.hour == _start.hours &&
value <= startIndex[4]
) {
timeIndex = startIndex;
} else if (
this.year == _end.year &&
this.month == _end.month &&
this.day == _end.day &&
this.hour == _end.hours &&
value >= endIndex[4]
) {
timeIndex = endIndex;
}
this.timeIndex = JSON.parse(JSON.stringify(timeIndex));
break;
}
},
},
};
</script>
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-touch-fullscreen" content="yes">
<meta name="format-detection" content="telephone=no,address=no">
<meta name="apple-mobile-web-app-status-bar-style" content="white">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" >
<title>meihuaApp</title>
<script><%= htmlWebpackPlugin.options.script %></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
export default {
navigationBarTitleText: '授权页',
usingComponents: {
},
}
.red {
color: red;
}
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-11-15 16:45:25
* @FilePath: /swx/src/pages/auth/index.vue
* @Description: 文件描述
-->
<template>
<div>
<!-- <button wx:if="{{canIUse}}" open-type="getUserInfo" @getuserinfo="bindGetUserInfo">授权登录</button>
<view @tap="auth">授权登陆</view> -->
</div>
</template>
<script setup>
import Taro from '@tarojs/taro'
import { ref } from "vue";
import request from '@/utils/request';
</script>
<script>
import "./index.less";
import { getCurrentPageParam } from "@/utils/weapp";
export default {
name: "authPage",
mounted () {
// 授权登陆
Taro.login({
success: function (res) {
if (res.code) {
//发起网络请求
Taro.showLoading({
title: '授权中',
})
request.post('/srv/?a=openid', {
code: res.code
// openid: '0002'
// openid: 'o5NFZ5cFQtLRy3aVHaZMLkjHFusI'
// openid: 'o5NFZ5TpgG4FwYursGCLjcUJH2ak'
// openid: 'o5NFZ5cqroPYwawCp8FEOxewtgnw'
})
.then(res => {
if (res.data.code) {
var cookie = res.cookies[0];
if (cookie != null) {
wx.setStorageSync("sessionid", res.cookies[0]);//服务器返回的 Set-Cookie,保存到本地
//TAG 小程序绑定cookie
// 修改请求头
request.defaults.headers.cookie = res.cookies[0];
if (res.data.data.avatar) {
Taro.reLaunch({
url: '../../' + getCurrentPageParam().url
})
} else { // 头像没有设置跳转完善信息页面
Taro.redirectTo({
url: '../apxUserInfo/index'
})
}
Taro.hideLoading();
}
} else {
console.warn(res.data.msg);
Taro.hideLoading();
}
})
.catch(err => {
console.error(err);
Taro.hideLoading();
});
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
},
data () {
return {
canIUse: wx.canIUse('button.open-type.getUserInfo')
}
},
onLoad: function() {
// 查看是否授权
// wx.getSetting({
// success (res){
// if (res.authSetting['scope.userInfo']) {
// // 已经授权,可以直接调用 getUserInfo 获取头像昵称
// wx.getUserInfo({
// success: function(res) {
// console.warn(res.userInfo)
// }
// })
// }
// }
// })
},
methods: {
bindGetUserInfo (e) {
console.warn(e.detail.userInfo)
},
// auth () {
// Taro.getSetting({
// success: function (res) {
// if (!res.authSetting['scope.userInfo']) {
// console.warn(0);
// Taro.authorize({
// scope: 'scope.userInfo',
// success: function () {
// Taro.getUserInfo({
// success: function(res) {
// var userInfo = res.userInfo
// console.warn(userInfo);
// }
// })
// },
// fail: function (error) {
// console.error(error)
// }
// })
// }
// }
// })
// }
auth () {
// wx.getSetting({
// success (res){
// if (res.authSetting['scope.userInfo']) {
// // 已经授权,可以直接调用 getUserInfo 获取头像昵称
// wx.getUserInfo({
// success: function(res) {
// console.warn(res.userInfo)
// }
// })
// }
// }
// })
wx.getSetting({
success(res) {
if (!res.authSetting['scope.userInfo']) {
wx.authorize({
scope: 'scope.userInfo',
success () {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success: function(res) {
console.warn(res.userInfo)
}
})
}
})
}
}
})
}
}
};
</script>
/*
* @Date: 2023-12-13 11:07:26
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-13 11:07:51
* @FilePath: /meihua-island-book/src/pages/book/index.config.js
* @Description: 文件描述
*/
export default {
navigationBarTitleText: '订房',
usingComponents: {
},
}
.book-page {
position: relative;
.cover-header {
background-image: url(https://img.yzcdn.cn/vant/cat.jpeg);
width: 100%;
height: 10rem;
background-size: cover;
background-position: center;
position: relative;
overflow: hidden;
z-index: 1;
}
.book-content {
z-index: 9;
position: absolute;
top: 9rem;
left: 0;
right: 0;
bottom: 0;
background-color: #FFF;
border-top-left-radius: 0.5rem;
border-top-right-radius: 0.5rem;
overflow: auto;
height: 100%;
padding: 1rem 0.75rem;
.book-calc {}
.book-type {}
.book-list {}
}
}
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 18:23:40
* @FilePath: /meihuaApp/src/pages/book/index.vue
* @Description: 文件描述
-->
<template>
<view class="book-page">
<view class="cover-header"></view>
<view class="book-content">
<view class="book-calc">
<calendar-select></calendar-select>
</view>
<view class="book-type">类型选择</view>
<view class="book-list">scroll-view</view>
</view>
<nav-bar activated="book" />
</view>
</template>
<script setup>
import Taro from '@tarojs/taro'
import { ref } from "vue";
import calendarSelect from '@/components/calendarSelect.vue'
import navBar from '@/components/navBar.vue'
</script>
<script>
import "./index.less";
export default {
name: "bookPage",
};
</script>
export default {
navigationBarTitleText: 'demo',
usingComponents: {
},
}
.red {
color: red;
}
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-30 10:00:57
* @FilePath: /swx/src/pages/demo/index.vue
* @Description: 文件描述
-->
<template>
<div class="red">{{ str }}</div>
</template>
<script setup>
import Taro from '@tarojs/taro'
import { ref } from "vue";
</script>
<script>
import "./index.less";
export default {
name: "demoPage",
};
</script>
export default {
navigationBarTitleText: 'demo',
usingComponents: {
},
}
.red {
color: red;
}
<!--
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-06-06 14:45:50
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-06 14:51:51
* @FilePath: /taro-vant-weapp/src/pages/foo/index.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div class="red">{{ str }}</div>
</template>
<script setup>
import { ref } from "vue";
const str = ref('foo')
</script>
<script>
import "./index.less";
export default {
name: "fooPage",
};
</script>
/*
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 17:20:42
* @FilePath: /meihua-island-book/src/pages/index/index.config.js
* @Description: 文件描述
*/
export default {
navigationBarTitleText: '梅花岛',
usingComponents: {
},
enableShareAppMessage: true
}
.slide-box {
height: 15rem;
.slide-image {
width: 100%;
height: 100%;
}
}
.bg-gradient {
background: linear-gradient(#B3DDC9, #B3DDC9) no-repeat;
/*调整下划线的宽度占百分之百 高度是3px */
background-size: 100% 1vw;
/* 调整下划线的起始位置 左侧是0 上边是1.15em */
background-position: 0 1rem;
}
.underline {
position: relative;
z-index: 2;
&::before {
position: absolute;
z-index: 1;
content: "";
color: white;
left: 0;
width: 100%;
height: 1.1rem;
border-bottom: 4rpx solid #B3DDC9;
}
}
@-webkit-keyframes arrow-down {
from {
bottom: 0%;
opacity: 0.5;
}
to {
bottom: 1%;
opacity: 1;
}
}
.arrow-down {
-webkit-animation: arrow-down 2s infinite;
-webkit-animation-fill-mode: both;
position: absolute;
right: 0;
left: calc(50% - 1rem);
margin-bottom: 1rem;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 18:22:45
* @FilePath: /meihuaApp/src/pages/index/index.vue
* @Description: 首页
-->
<template>
<div>
<scroll-view :style="scrollStyle" :scroll-y="true" :scroll-top="scrollTop" :scroll-with-animation="true" @scroll="onScroll" @scrolltoupper="onScrollToUpper" @scrolltolower="onScrollToLower">
<view style="position: relative;">
<image :style="coverStyle" mode="aspectFill" src="https://img.yzcdn.cn/vant/cat.jpeg" />
<div class="arrow-down" @tap="onArrowDown">
<image style="width: 2rem; height: 2rem;" :src="arrowDownImg"/>
</div>
</view>
<view style="text-align: center; font-weight: bold; font-size: 1.25rem; margin-top: 1rem;">热门推荐</view>
<view style="background-color: #f9f9f9; overflow: auto;">
<room-card v-for="(item, index) in 20" :key="index"></room-card>
</view>
</scroll-view>
<view style="height: 6rem;"></view>
<nav-bar activated="index" />
</div>
</template>
<script setup>
import Taro from '@tarojs/taro'
import { ref } from 'vue';
import roomCard from '@/components/roomCard.vue'
import arrowDownImg from '@/assets/images/arrow-down.png'
// import icon_no_join_recommend from '@/images/icon/no-tuijian@2x.png'
// import icon_banner from '@/images/icon/banner@2x.png'
import navBar from '@/components/navBar.vue'
// import { useDidShow } from '@/hooks/life'
import { useDidShow } from '@tarojs/taro'
// TAG: 模拟onShow事件
useDidShow(() => {
// console.warn(AUTHOR)
})
// const goTo = (id) => {
// Taro.navigateTo({
// url: '../activityDetail/index?id=' + id
// })
// }
// 分享功能
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
</script>
<script>
import "./index.less";
// import { activityHomeAPI } from '@/api/Host/index'
import { $ } from '@tarojs/extend'
import mixin from '@/utils/mixin';
export default {
name: "indexPage",
mixins: [mixin.init],
onReady() {
if (!Taro.canIUse("getUpdateManager")) {
Taro.showModal({
title: "提示",
content: "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试",
showCancel: false,
});
return;
}
// https://developers.weixin.qq.com/miniprogram/dev/api/base/update/UpdateManager.html
const updateManager = Taro.getUpdateManager();
updateManager.onCheckForUpdate((res) => {
// 请求完新版本信息的回调
if (res.hasUpdate) {
updateManager.onUpdateReady(function () {
Taro.showModal({
title: "更新提示",
content: "新版本已经准备好,是否重启应用?",
success: function (res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
},
});
});
updateManager.onUpdateFailed(function () {
// 新版本下载失败
Taro.showModal({
title: "更新提示",
content: "新版本已上线,请删除当前小程序,重新搜索打开",
});
});
}
});
},
async onShow () {
},
onHide () { // 离开当前页面
},
computed: {
scrollStyle() {
return {
height: this.indexCoverHeight + 'px',
};
},
coverStyle () {
return {
width: '100%',
height: this.indexCoverHeight + 'px',
};
},
},
mounted () {
// 设置首页封面高度
const windowHeight = wx.getSystemInfoSync().windowHeight;
setTimeout(async () => {
const navHeight = await $('#navbar-page').height();
this.indexCoverHeight = windowHeight - navHeight;
}, 500);
},
data() {
return {
indexCoverHeight: 0,
scrollTop: 0,
};
},
methods: {
onScroll(event) {
},
async onScrollToUpper (event) {
this.scrollTop = 0; // 重置scrollTop,让按钮能再往下滚动
},
onScrollToLower () {
// if(!this.flag){
// return
// }
// this.flag = false;
// this.getList();
console.warn('onScrollToLower');
},
async onArrowDown () {
Taro.pageScrollTo({
scrollTop: this.indexCoverHeight, // 滚动到的位置
duration: 300 // 滚动动画的时长
});
this.scrollTop = this.indexCoverHeight; // 调整滚动控件高度
}
},
onPageScroll ({ scrollTop }) {
},
onShareAppMessage(options) {
// 设置菜单中的转发按钮触发转发事件时的转发内容
var shareObj = {
title: "梅花岛订房小程序", // 默认是小程序的名称(可以写slogan等)
path: 'pages/index/index', // 默认是当前页面,必须是以‘/'开头的完整路径
imageUrl: '', //自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径,支持PNG及JPG,不传入 imageUrl 则使用默认截图。显示图片长宽比是 5:4
success: function (res) {
// 转发成功之后的回调
if (res.errMsg == 'shareAppMessage:ok') {
//
}
},
fail: function () {
// 转发失败之后的回调
if (res.errMsg == 'shareAppMessage:fail cancel') {
// 用户取消转发
} else if (res.errMsg == 'shareAppMessage:fail') {
// 转发失败,其中 detail message 为详细失败信息
}
},
complete: function () {
// 转发结束之后的回调(转发成不成功都会执行)
}
}
// 来自页面内的按钮的转发
// if (options.from == 'button') {
// var eData = options.target.dataset;
// // 此处可以修改 shareObj 中的内容
// shareObj.path = '/pages/goods/goods?goodId=' + eData.id;
// }
// 返回shareObj
return shareObj;
}
};
</script>
export default {
navigationBarTitleText: '我的',
usingComponents: {
},
}
.red {
color: red;
}
<!--
* @Date: 2023-12-13 11:13:13
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-14 18:24:03
* @FilePath: /meihuaApp/src/pages/my/index.vue
* @Description: 文件描述
-->
<template>
<div>
<nav-bar activated="my" />
</div>
</template>
<script setup>
import Taro from '@tarojs/taro'
import { ref } from "vue";
import navBar from '@/components/navBar.vue'
</script>
<script>
import "./index.less";
export default {
name: "myPage",
};
</script>
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.