hookehuyr

初始化

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