diff --git a/app.js b/app.js index a9de1b9..c5f4706 100644 --- a/app.js +++ b/app.js @@ -20,6 +20,6 @@ App({ }) }, globalData: { - userInfo: null + city: null, // 当前选择的城市 } }) diff --git a/app.json b/app.json index 0f8e064..1cbf8c4 100644 --- a/app.json +++ b/app.json @@ -1,8 +1,8 @@ { "pages": [ - "pages/index/index", - "pages/explore/index", - "pages/my/index" + "pages/home/index", + "pages/my/index", + "pages/city-picker/index" ], "window": { "backgroundTextStyle": "light", @@ -12,24 +12,17 @@ }, "tabBar": { "custom": true, - "color": "#000000", - "selectedColor": "#000000", - "backgroundColor": "#000000", "list": [ { - "pagePath": "pages/index/index", + "pagePath": "pages/home/index", "text": "首页" }, - { - "pagePath": "pages/explore/index", - "text": "发现" - }, { "pagePath": "pages/my/index", "text": "我的" } ] }, - "style": "v2", - "sitemapLocation": "sitemap.json" + "sitemapLocation": "sitemap.json", + "lazyCodeLoading": "requiredComponents" } \ No newline at end of file diff --git a/app.less b/app.less index 06c6fc9..4ead247 100644 --- a/app.less +++ b/app.less @@ -1,10 +1,7 @@ /**app.wxss**/ -.container { - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-between; - padding: 200rpx 0; - box-sizing: border-box; -} +@import '/style/global.less'; + +page { + color: @main-text-color; + font-family: "PingFang SC", sans-serif; +} diff --git a/custom-tab-bar/index.js b/custom-tab-bar/index.js index 21207df..247e4af 100644 --- a/custom-tab-bar/index.js +++ b/custom-tab-bar/index.js @@ -1,45 +1,31 @@ - +// custom-tab-bar/index.js Component({ + + /** 组件的初始数据 */ data: { - value: 'index', - list: [{ - icon: 'home', - value: 'index', - label: '首页', - },{ - icon: 'control-platform', - value: 'explore', - label: '发现', - }, { - icon: 'user', - value: 'my', - label: '我的' - }] + value: '', + list: [ + { value: 'home', label: '首页', icon: 'home' }, + { value: 'my', label: '我的', icon: 'user' }, + ], }, lifetimes: { ready() { const pages = getCurrentPages(); const curPage = pages[pages.length - 1]; - if (curPage) { const nameRe = /pages\/(\w+)\/index/.exec(curPage.route); - - if (nameRe[1]) { - this.setData({ - value: nameRe[1] - }) - } + if (nameRe && nameRe[1]) + this.setData({ value: nameRe[1] }) } } }, - methods: { - handleChange(e) { - const { value } = e.detail; - // this.setData({ value }); - wx.switchTab({ - url: `/pages/${value}/index`, - }) - } + /** 组件的方法列表 */ + methods: { + onChange(event) { + const { value } = event.detail + wx.switchTab({ url: `/pages/${value}/index` }) + }, } }) diff --git a/custom-tab-bar/index.json b/custom-tab-bar/index.json index df5bd1d..31f8169 100644 --- a/custom-tab-bar/index.json +++ b/custom-tab-bar/index.json @@ -2,6 +2,6 @@ "component": true, "usingComponents": { "t-tab-bar": "tdesign-miniprogram/tab-bar/tab-bar", - "t-tab-bar-item": "tdesign-miniprogram/tab-bar/tab-bar-item" + "t-tab-bar-item": "tdesign-miniprogram/tab-bar-item/tab-bar-item" } } \ No newline at end of file diff --git a/custom-tab-bar/index.wxml b/custom-tab-bar/index.wxml index 69a9b7b..6a08b55 100644 --- a/custom-tab-bar/index.wxml +++ b/custom-tab-bar/index.wxml @@ -1,5 +1,4 @@ - - - {{item.label}} - + + + {{ item.label }} \ No newline at end of file diff --git a/images/head-bg.png b/images/head-bg.png new file mode 100644 index 0000000..0732c88 Binary files /dev/null and b/images/head-bg.png differ diff --git a/images/mock/activity/activity-1.png b/images/mock/activity/activity-1.png new file mode 100644 index 0000000..340166a Binary files /dev/null and b/images/mock/activity/activity-1.png differ diff --git a/images/mock/activity/activity-2.png b/images/mock/activity/activity-2.png new file mode 100644 index 0000000..abe8f76 Binary files /dev/null and b/images/mock/activity/activity-2.png differ diff --git a/images/mock/activity/activity-3.png b/images/mock/activity/activity-3.png new file mode 100644 index 0000000..d90e55c Binary files /dev/null and b/images/mock/activity/activity-3.png differ diff --git a/images/mock/activity/activity-4.png b/images/mock/activity/activity-4.png new file mode 100644 index 0000000..07256a4 Binary files /dev/null and b/images/mock/activity/activity-4.png differ diff --git a/images/mock/activity/hot-activity.png b/images/mock/activity/hot-activity.png new file mode 100644 index 0000000..f29fc14 Binary files /dev/null and b/images/mock/activity/hot-activity.png differ diff --git a/package-lock.json b/package-lock.json index b0dbc76..5ffad29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,17 @@ { - "name": "miniprogram-starter", + "name": "tdesign-miniprogram-starter-apply", + "version": "0.0.2", "lockfileVersion": 2, "requires": true, "packages": { "": { + "name": "tdesign-miniprogram-starter-apply", + "version": "0.0.2", + "license": "MIT", "dependencies": { - "tdesign-miniprogram": "^0.12.1" - } + "tdesign-miniprogram": "^1.1.15" + }, + "devDependencies": {} }, "node_modules/dayjs": { "version": "1.11.2", @@ -14,9 +19,9 @@ "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==" }, "node_modules/tdesign-miniprogram": { - "version": "0.12.1", - "resolved": "https://registry.npmmirror.com/tdesign-miniprogram/-/tdesign-miniprogram-0.12.1.tgz", - "integrity": "sha512-nRQu3us411XbFz7AFa1o/ZffZtc+jxRLYhLCALzivsqFDQt0YaxBQbtRNxg7fwKtaKezg/wl+IFSymm4OfgiCQ==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/tdesign-miniprogram/-/tdesign-miniprogram-1.1.15.tgz", + "integrity": "sha512-dFGA5fQnObN6bjer3CIcRhNOsjz9VwV2oBC+EEz2bFMYMQQZ0A754TWQzHr/UkW/q+qEMakfxGxlKTa19YSwzw==", "dependencies": { "dayjs": "^1.10.7" } @@ -29,9 +34,9 @@ "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==" }, "tdesign-miniprogram": { - "version": "0.12.1", - "resolved": "https://registry.npmmirror.com/tdesign-miniprogram/-/tdesign-miniprogram-0.12.1.tgz", - "integrity": "sha512-nRQu3us411XbFz7AFa1o/ZffZtc+jxRLYhLCALzivsqFDQt0YaxBQbtRNxg7fwKtaKezg/wl+IFSymm4OfgiCQ==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/tdesign-miniprogram/-/tdesign-miniprogram-1.1.15.tgz", + "integrity": "sha512-dFGA5fQnObN6bjer3CIcRhNOsjz9VwV2oBC+EEz2bFMYMQQZ0A754TWQzHr/UkW/q+qEMakfxGxlKTa19YSwzw==", "requires": { "dayjs": "^1.10.7" } diff --git a/package.json b/package.json index fa434e8..348f43a 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "miniprogram-starter", + "name": "tdesign-miniprogram-starter-apply", "version": "0.0.2", "main": "index.js", "scripts": { @@ -10,7 +10,7 @@ "license": "MIT", "description": "a start-kit for wechat miniprogram powerby TDesign miniprogram", "dependencies": { - "tdesign-miniprogram": "^0.12.1" + "tdesign-miniprogram": "^1.1.15" }, "devDependencies": {} -} +} \ No newline at end of file diff --git a/pages/city-picker/index.js b/pages/city-picker/index.js new file mode 100644 index 0000000..9593772 --- /dev/null +++ b/pages/city-picker/index.js @@ -0,0 +1,70 @@ +// pages/city-picker/index.js +import { fetchCurrentCity } from '../../services/location' +const app = getApp() + +const cities = [ + { index: '热门城市', children: ['北京', '上海', '广州', '深圳', '成都'] }, + { index: 'A', children: ['阿克苏', '安康', '安宁', '安庆', '鞍山', '安顺', '安阳', '阿拉善左旗', '阿拉善右旗', '阿拉尔', '阿勒泰', '阿里', '阿坝', '阿尔山'] }, + { index: 'B', children: ['北京', '保定', '包头', '巴彦淖尔', '本溪', '白城', '白山', '蚌埠', '亳州', '滨州', '北海', '百色', '巴中', '毕节', '保山', '宝鸡', '白银', '博尔塔拉', '巴音郭楞'] }, + { index: 'C', children: ['重庆', '成都', '长沙', '长春', '常州', '沧州', '承德', '赤峰', '朝阳', '长治', '常德', '郴州', '潮州', '池州', '滁州', '巢湖', '昌吉'] }, + { index: 'D', children: ['大连','大庆','大同','丹东','东莞','东营','德阳','德州','定西','达州','大理','德宏','迪庆','儋州'] }, + { index: 'E', children: ['鄂尔多斯', '鄂州', '恩施'] }, + { index: 'F', children: ['福州', '佛山', '抚顺', '阜新', '阜阳', '抚州', '防城港', '富阳'] }, + { index: 'G', children: ['广州', '贵阳', '桂林', '赣州', '广元', '广安', '甘孜', '甘南', '固原', '果洛'] }, + { index: 'H', children: ['杭州', '哈尔滨', '合肥', '呼和浩特', '海口', '邯郸', '衡水', '呼伦贝尔', '葫芦岛', '鹤岗', '黑河', '淮安', '杭州湾新区', '湖州', '淮南', '淮北','黄山','菏泽','鹤壁','黄石','黄冈','衡阳','怀化','惠州','河源','汉中','海东','海北','黄南','海南藏族自治州','海西','哈密'] }, + { index: 'J', children: ['济南','济宁','嘉兴','金华','九江','吉林','锦州','晋中','晋城','焦作','荆门','荆州','揭阳','江门','佳木斯', '鸡西','吉安','景德镇','济源'] }, + { index: 'K', children: ['昆明','开封','克拉玛依','喀什地区'] }, + { index: 'L', children: ['兰州','洛阳','廊坊','临沂','连云港','柳州','泸州','乐山', '凉山彝族自治州'] }, + { index: 'M', children: ['绵阳','马鞍山','牡丹江','茂名','梅州','眉山','绵竹'] }, + { index: 'N', children: ['南京','南昌','宁波','南宁','南通','南充','南阳','内江', '宁德','怒江傈僳族自治州'] }, + { index: 'P', children: ['平顶山','莆田','萍乡','攀枝花','盘锦','平凉'] }, + { index: 'Q', children: ['青岛','泉州','秦皇岛','齐齐哈尔','衢州','清远', '钦州','黔西南布依族苗族自治州','黔东南苗族侗族自治州', '黔南布依族苗族自治州'] }, + { index: 'R', children: ['日照'] }, + { index: 'S', children: ['上海','深圳','沈阳','石家庄','苏州','三亚', '绍兴','汕头','汕尾','商丘','十堰','随州', '邵阳', '三明', '松原', '四平', '朔州', '双鸭山', '韶关', '石嘴山', '石河子', '石柱土家族自治县'] }, + { index: 'T', children: ['天津', '太原', '唐山', '台州', '泰安', '泰州', '铜陵', '铜仁', '通辽', '通化', '天水', '铁岭', '吐鲁番'] }, + { index: 'W', children: ['武汉', '无锡', '温州', '芜湖', '潍坊', '威海', '乌鲁木齐', '乌海', '乌兰察布', '武威'] }, + { index: 'X', children: ['西安', '厦门', '徐州', '西宁', '新乡', '许昌', '信阳', '襄阳', '孝感', '咸宁', '湘潭', '邢台', '忻州', '兴安盟', '锡林郭勒盟'] }, + { index: 'Y', children: ['烟台', '扬州', '盐城', '宜春', '宜昌', '银川', '运城', '延边朝鲜族自治州', '延安', '营口', '玉林', '玉溪', '岳阳', '永州', '榆林', '阳江', '云浮', '伊春'] }, + { index: 'Z', children: ['郑州', '珠海', '中山', '淄博', '株洲', '漳州', '镇江', '湛江', '肇庆', '遵义', '张家口', '周口', '驻马店', '张家界', '自贡', '资阳'] } +] + +Page({ + /** 页面的初始数据 */ + data: { + cities: [], // 城市列表 + indexList: [], // 城市索引(拼音首字母) + selectedCity: null, // 当前选择的城市 + currentCity: null, // 当前所在的城市 + loading: true, // 是否正在获取当前所在城市 + }, + + /** 生命周期函数--监听页面加载 */ + onLoad(options) { + this.getCurrentCity() + this.setData({ + cities, + indexList: cities.filter((item, index) => index !== 0).map(item => item.index), + selectedCity: app.globalData.city + }) + }, + + /** 获取当前所在城市 */ + getCurrentCity() { + this.setData({ loading: true }) + fetchCurrentCity().then(({ data }) => { + this.setData({ currentCity: data }) + }).finally(() => { + this.setData({ loading: false }) + }) + }, + + /** 选择城市 */ + selectCity(event) { + const city = event.currentTarget.dataset.city + if (!city) + return + const eventChannel = this.getOpenerEventChannel() + eventChannel.emit('selectCity', city) + wx.navigateBack() + } +}) \ No newline at end of file diff --git a/pages/city-picker/index.json b/pages/city-picker/index.json new file mode 100644 index 0000000..11a7b36 --- /dev/null +++ b/pages/city-picker/index.json @@ -0,0 +1,12 @@ +{ + "navigationStyle": "custom", + "usingComponents": { + "t-navbar": "tdesign-miniprogram/navbar/navbar", + "t-icon": "tdesign-miniprogram/icon/icon", + "t-button": "tdesign-miniprogram/button/button", + "t-indexes": "tdesign-miniprogram/indexes/indexes", + "t-indexes-anchor": "tdesign-miniprogram/indexes-anchor/indexes-anchor", + "t-cell-group": "tdesign-miniprogram/cell-group/cell-group", + "t-cell": "tdesign-miniprogram/cell/cell" + } +} \ No newline at end of file diff --git a/pages/city-picker/index.less b/pages/city-picker/index.less new file mode 100644 index 0000000..7338950 --- /dev/null +++ b/pages/city-picker/index.less @@ -0,0 +1,29 @@ +/* pages/city-picker/index.wxss */ +@import '/style/global.less'; + +.page { + font-size: 32rpx; +} + +.current { + display: flex; + align-items: center; + gap: 8rpx; + padding: 32rpx; + font-size: 32rpx; +} + +.relocation { + margin: 0 0 0 auto; + --td-button-extra-small-font-size: 28rpx !important; + font-weight: normal; +} + +.selected { + margin-right: 48rpx; +} + +.selected .t-icon-base { + color: @brand-color; + font-weight: bold; +} \ No newline at end of file diff --git a/pages/city-picker/index.wxml b/pages/city-picker/index.wxml new file mode 100644 index 0000000..bf94be7 --- /dev/null +++ b/pages/city-picker/index.wxml @@ -0,0 +1,18 @@ + + + + + {{ loading ? '正在定位...' : currentCity || '定位失败' }} + 更新定位 + + + + + + + + + + + + diff --git a/pages/explore/index.js b/pages/explore/index.js deleted file mode 100644 index 5961137..0000000 --- a/pages/explore/index.js +++ /dev/null @@ -1,66 +0,0 @@ -// pages/explore/index.js -Page({ - - /** - * 页面的初始数据 - */ - data: { - - }, - - /** - * 生命周期函数--监听页面加载 - */ - onLoad(options) { - - }, - - /** - * 生命周期函数--监听页面初次渲染完成 - */ - onReady() { - - }, - - /** - * 生命周期函数--监听页面显示 - */ - onShow() { - - }, - - /** - * 生命周期函数--监听页面隐藏 - */ - onHide() { - - }, - - /** - * 生命周期函数--监听页面卸载 - */ - onUnload() { - - }, - - /** - * 页面相关事件处理函数--监听用户下拉动作 - */ - onPullDownRefresh() { - - }, - - /** - * 页面上拉触底事件的处理函数 - */ - onReachBottom() { - - }, - - /** - * 用户点击右上角分享 - */ - onShareAppMessage() { - - } -}) \ No newline at end of file diff --git a/pages/explore/index.json b/pages/explore/index.json deleted file mode 100644 index ac05698..0000000 --- a/pages/explore/index.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "navigationBarTitleText": "发现", - "usingComponents": {} -} \ No newline at end of file diff --git a/pages/explore/index.less b/pages/explore/index.less deleted file mode 100644 index 204b9db..0000000 --- a/pages/explore/index.less +++ /dev/null @@ -1 +0,0 @@ -/* pages/explore/index.wxss */ \ No newline at end of file diff --git a/pages/explore/index.wxml b/pages/explore/index.wxml deleted file mode 100644 index 179190c..0000000 --- a/pages/explore/index.wxml +++ /dev/null @@ -1,3 +0,0 @@ - - Explore Page - \ No newline at end of file diff --git a/pages/home/components/card/index.js b/pages/home/components/card/index.js new file mode 100644 index 0000000..ec0f0fe --- /dev/null +++ b/pages/home/components/card/index.js @@ -0,0 +1,23 @@ +// pages/home/components/card/index.js +Component({ + /** 组件的属性列表 */ + properties: { + activity: { + type: Object, + value: { + activityId: 0, + image: '', + name: '', + rate: 0, + bottomPrice: 0, + topPrice: 0, + } + } + }, + + /** 组件的初始数据 */ + data: {}, + + /** 组件的方法列表 */ + methods: {} +}) diff --git a/pages/home/components/card/index.json b/pages/home/components/card/index.json new file mode 100644 index 0000000..277a90a --- /dev/null +++ b/pages/home/components/card/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "t-rate": "tdesign-miniprogram/rate/rate" + } +} \ No newline at end of file diff --git a/pages/home/components/card/index.less b/pages/home/components/card/index.less new file mode 100644 index 0000000..4ff9172 --- /dev/null +++ b/pages/home/components/card/index.less @@ -0,0 +1,48 @@ +/* pages/home/components/card/index.wxss */ +.card { + position: relative; + display: flex; + box-shadow: 0 12rpx 60rpx 10rpx #0000000d, 0 32rpx 48rpx 4rpx #0000000a, 0 16rpx 20rpx -10rpx #00000014; + border-radius: 18rpx; +} + +.image { + width: 240rpx; + height: 240rpx; + border-radius: 18rpx 0 0 18rpx; +} + +.content { + display: flex; + flex-direction: column; + box-sizing: border-box; + width: 446rpx; + height: 240rpx; + padding: 32rpx 32rpx 24rpx; + border-radius: 0 18rpx 18rpx 0; + background-color: #ffffff; +} + +.name { + margin-bottom: 16rpx; + line-height: 44rpx; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.rate { + display: flex; + align-items: center; + gap: 16rpx; + height: 40rpx; + color: #E37318; + font-size: 24rpx; + font-weight: bold; +} + +.price { + margin-top: auto; + font-weight: bold; + line-height: 44rpx; +} diff --git a/pages/home/components/card/index.wxml b/pages/home/components/card/index.wxml new file mode 100644 index 0000000..1709fb3 --- /dev/null +++ b/pages/home/components/card/index.wxml @@ -0,0 +1,27 @@ + + + + + {{ activity.name }} + + + {{ activity.rate }}分 + + {{ utils.formatPrice(activity.bottomPrice, activity.topPrice) }} + + + + + /** 格式化价格 */ + function formatPrice(bottomPrice, topPrice) { + if (bottomPrice === 0 && topPrice === 0) + return '免费活动' + if (bottomPrice === topPrice) + return '¥' + bottomPrice.toFixed(2) + return '¥' + bottomPrice.toFixed(2) + ' - ¥' + topPrice.toFixed(2) + } + + module.exports = { + formatPrice: formatPrice + } + \ No newline at end of file diff --git a/pages/home/components/loading-card/index.js b/pages/home/components/loading-card/index.js new file mode 100644 index 0000000..a6a83a7 --- /dev/null +++ b/pages/home/components/loading-card/index.js @@ -0,0 +1,23 @@ +// pages/home/components/loading-card/index.js +Component({ + /** + * 组件的属性列表 + */ + properties: { + + }, + + /** + * 组件的初始数据 + */ + data: { + + }, + + /** + * 组件的方法列表 + */ + methods: { + + } +}) diff --git a/pages/home/components/loading-card/index.json b/pages/home/components/loading-card/index.json new file mode 100644 index 0000000..c785a3c --- /dev/null +++ b/pages/home/components/loading-card/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "t-skeleton": "tdesign-miniprogram/skeleton/skeleton" + } +} \ No newline at end of file diff --git a/pages/home/components/loading-card/index.less b/pages/home/components/loading-card/index.less new file mode 100644 index 0000000..0d66f5e --- /dev/null +++ b/pages/home/components/loading-card/index.less @@ -0,0 +1,11 @@ +/* pages/home/components/loading-card/index.wxss */ +.card { + position: relative; + display: flex; + gap: 32rpx; +} + +.content { + width: 414rpx; + margin-top: 16rpx; +} diff --git a/pages/home/components/loading-card/index.wxml b/pages/home/components/loading-card/index.wxml new file mode 100644 index 0000000..edc6f0b --- /dev/null +++ b/pages/home/components/loading-card/index.wxml @@ -0,0 +1,6 @@ + + + + + + diff --git a/pages/home/components/navigation-bar/index.js b/pages/home/components/navigation-bar/index.js new file mode 100644 index 0000000..5e10887 --- /dev/null +++ b/pages/home/components/navigation-bar/index.js @@ -0,0 +1,53 @@ +// pages/home/components/navigation-bar/index.js +import { fetchCurrentCity } from '../../../../services/location' +const app = getApp() + +Component({ + /** 组件的属性列表 */ + properties: {}, + + /** 组件的初始数据 */ + data: { + statusBarHeight: wx.getSystemInfoSync().statusBarHeight, + capsule: wx.getMenuButtonBoundingClientRect(), + city: null, + loading: true + }, + + /** 组件的生命周期 */ + lifetimes: { + attached: function() { + this.getCurrentCity() + } + }, + + /** 组件的方法列表 */ + methods: { + /** 获取当前所在城市 */ + getCurrentCity() { + fetchCurrentCity().then(({ data }) => { + this.setData({ city: data }) + app.globalData.city = data + this.triggerEvent('select-city') + }).finally(() => { + this.setData({ loading: false }) + }) + }, + + /** 打开地区选择页面 */ + selectCity() { + const app = getApp() + wx.navigateTo({ + url: '/pages/city-picker/index?city=' + app.globalData.city, + events: { + /** 完成选择 */ + selectCity: (city) => { + this.setData({ city }) + app.globalData.city = city + this.triggerEvent('select-city') + } + } + }) + }, + } +}) diff --git a/pages/home/components/navigation-bar/index.json b/pages/home/components/navigation-bar/index.json new file mode 100644 index 0000000..084fe41 --- /dev/null +++ b/pages/home/components/navigation-bar/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "t-icon": "tdesign-miniprogram/icon/icon", + "t-search": "tdesign-miniprogram/search/search" + } +} \ No newline at end of file diff --git a/pages/home/components/navigation-bar/index.less b/pages/home/components/navigation-bar/index.less new file mode 100644 index 0000000..bd0d9b3 --- /dev/null +++ b/pages/home/components/navigation-bar/index.less @@ -0,0 +1,21 @@ +/* pages/home/components/navigation-bar/index.wxss */ +.navigation-bar { + background: #ffffff no-repeat top; + background-size: 750rpx; +} + +.nav-bar { + display: inline-flex; + align-items: center; + gap: 8rpx; + height: 48rpx; + padding: 0 32rpx; +} + +.city { + font-size: 28rpx; +} + +.search { + padding: 16rpx 32rpx; +} diff --git a/pages/home/components/navigation-bar/index.wxml b/pages/home/components/navigation-bar/index.wxml new file mode 100644 index 0000000..fe1c7f4 --- /dev/null +++ b/pages/home/components/navigation-bar/index.wxml @@ -0,0 +1,11 @@ + + + + + + {{ loading ? '正在定位...' : city || '定位失败' }} + + + + + \ No newline at end of file diff --git a/pages/home/index.js b/pages/home/index.js new file mode 100644 index 0000000..bb53e61 --- /dev/null +++ b/pages/home/index.js @@ -0,0 +1,230 @@ +// pages/home/index.js +import { fetchHotActivities, fetchActivities } from '../../services/activity' +Page({ + + /** 页面的初始数据 */ + data: { + city: null, + navigationBarHeight: 0, // 顶部导航栏高度 + hotActivities: [], // 热门推荐活动 + filterVisible: false, // 是否显示筛选面板 + fieldFilter: [ // 筛选:面向领域 + { value: 0, text: 'IT互联网', selected: false }, + { value: 1, text: '艺术设计', selected: false }, + { value: 2, text: '科技', selected: false }, + { value: 3, text: '电商', selected: false }, + { value: 4, text: '教育', selected: false }, + { value: 5, text: '医疗健康', selected: false }, + { value: 6, text: '心理学', selected: false }, + { value: 7, text: '摄影', selected: false }, + ], + formFilter: [ // 筛选:活动形式 + { value: 0, text: '讲座', selected: false }, + { value: 1, text: '展览', selected: false }, + { value: 2, text: '工作坊', selected: false }, + ], + dateFilter: { // 筛选:活动日期 + visible: false, + startTime: null, + endTime: null, + }, + priceFilter: { // 筛选:价格区间 + bottomPrice: 0, + topPrice: 588, + }, + filterBackup: {}, // 筛选的备份数据 + + sortType: 0, // 活动排序方式(0:最新活动,1:高分活动) + activities: [], // 活动列表 + pageIndex: 1, // 下一次分页查询的页码 + loading: true, // 是否正在加载 + }, + + /** 生命周期函数--监听页面加载 */ + onLoad(options) { + this.getHotActivities() + }, + + /** 生命周期函数--监听页面初次渲染完成 */ + onReady() { + wx.createSelectorQuery() + .select('.navigation-bar').boundingClientRect() + .exec((res) => { + this.setData({ navigationBarHeight: res[0].height }) + }); + }, + + /** 生命周期函数--监听页面显示 */ + onShow() { + this.getTabBar().setData({ value: 'home' }) + }, + + /** 生命周期函数--监听页面隐藏 */ + onHide() {}, + + /** 生命周期函数--监听页面卸载 */ + onUnload() {}, + + /** 页面相关事件处理函数--监听用户下拉动作 */ + onPullDownRefresh() {}, + + /** 页面上拉触底事件的处理函数 */ + onReachBottom() { + if (this.data.loading) + return + this.getActivities() + }, + + /** 用户点击右上角分享 */ + onShareAppMessage() {}, + + /** 获取热门推荐活动列表 */ + getHotActivities() { + fetchHotActivities().then(({ data }) => { + this.setData({ hotActivities: [...data] }) + }) + }, + + /** 点击热门推荐活动 */ + handleTapHotActivity({ detail }) { + const activityId = this.data.hotActivities[detail.index].activityId + wx.navigateTo({ url: '/pages/activity/index?activityId=' + activityId }) + }, + + /** 修改排序方式 */ + changeSortType(event) { + const sortType = event.currentTarget.dataset.type + this.setData({ sortType }) + this.refreshActivities() + }, + + /** 打开活动筛选 */ + openFilter() { + this.backupFilter() + this.setData({ filterVisible: true }) + }, + + /** 备份筛选数据 */ + backupFilter() { + const { fieldFilter, formFilter, dateFilter, priceFilter } = this.data + this.data.filterBackup = JSON.parse(JSON.stringify({ + fieldFilter, + formFilter, + dateFilter, + priceFilter, + })) + }, + + /** 点击活动筛选遮罩 */ + handleFilterVisibleChange({ detail }) { + if (!detail.visible) + this.closeFilter() + }, + + /** 关闭活动筛选,并恢复备份的筛选数据 */ + closeFilter() { + const data = this.data.filterBackup + this.setData({ + filterVisible: false, + ...data + }) + }, + + /** 点击筛选选项 */ + handleTapFilterOption(event) { + const { filter, index } = event.currentTarget.dataset + const data = {} + this.data[filter][index].selected = !this.data[filter][index].selected + data[filter] = this.data[filter] + this.setData(data) + }, + + /** 打开日期选择器 */ + openDateFilter() { + this.setData({ + dateFilter: { + visible: true, + startTime: null, + endTime: null, + } + }) + }, + + /** 选择日期 */ + selectDate({ detail }) { + const startTime = detail.value[0], endTime = (detail.value[1] || startTime) + 86400000 + this.setData({ + dateFilter: { + visible: false, + startTime, + endTime, + } + }) + }, + + /** 选择价格区间 */ + selectPrice({ detail }) { + this.setData({ + priceFilter: { + bottomPrice: detail.value[0], + topPrice: detail.value[1] + } + }) + }, + + /** 重置活动筛选 */ + resetFilter() { + const { fieldFilter, formFilter, dateFilter, priceFilter } = this.data + for (const item of fieldFilter) + item.selected = false + for (const item of formFilter) + item.selected = false + dateFilter.startTime = dateFilter.endTime = null + priceFilter.bottomPrice = 0 + priceFilter.topPrice = 588 + this.setData({ + fieldFilter, + formFilter, + dateFilter, + priceFilter, + }) + }, + + /** 完成活动筛选 */ + saveFilter() { + this.data.filterBackup = {} + this.setData({ + filterVisible: false + }) + this.refreshActivities() + }, + + /** 获取活动列表(分页) */ + getActivities() { + const { pageIndex, sortType } = this.data + const fields = this.data.fieldFilter.filter(item => item.selected).map(item => item.value) + const forms = this.data.formFilter.filter(item => item.selected).map(item => item.value) + const { startTime, endTime } = this.data.dateFilter + const { bottomPrice, topPrice } = this.data.priceFilter + this.setData({ + loading: true + }) + fetchActivities({ pageIndex, sortType, fields, forms, startTime, endTime, bottomPrice, topPrice }).then(({ data }) => { + if (data.length > 0) + this.data.pageIndex++ + this.setData({ activities: [...this.data.activities, ...data] }) + }).finally(() => { + this.setData({ loading: false }) + }) + }, + + /** 刷新活动列表 */ + refreshActivities() { + this.setData({ + activities: [], + loading: true + }) + this.data.pageIndex = 1 + this.getActivities() + }, +}) \ No newline at end of file diff --git a/pages/home/index.json b/pages/home/index.json new file mode 100644 index 0000000..e56b62a --- /dev/null +++ b/pages/home/index.json @@ -0,0 +1,16 @@ +{ + "usingComponents": { + "nav-bar": "./components/navigation-bar/index", + "t-swiper": "tdesign-miniprogram/swiper/swiper", + "t-swiper-nav": "tdesign-miniprogram/swiper-nav/swiper-nav", + "t-icon": "tdesign-miniprogram/icon/icon", + "t-popup": "tdesign-miniprogram/popup/popup", + "t-divider": "tdesign-miniprogram/divider/divider", + "t-calendar": "tdesign-miniprogram/calendar/calendar", + "t-slider": "tdesign-miniprogram/slider/slider", + "t-button": "tdesign-miniprogram/button/button", + "loading-card": "./components/loading-card/index", + "card": "./components/card/index" + }, + "navigationStyle": "custom" +} \ No newline at end of file diff --git a/pages/home/index.less b/pages/home/index.less new file mode 100644 index 0000000..2a6d095 --- /dev/null +++ b/pages/home/index.less @@ -0,0 +1,186 @@ +/* pages/home/index.wxss */ +@import '/style/global.less'; + +page { + padding-bottom: calc(env(safe-area-inset-bottom) + 112rpx); + background-color: #ffffff; + font-size: 28rpx; +} + +.navigation-bar { + position: sticky; + top: 0; + z-index: 100; +} + +.section-title-hot, .section-title-all { + font-size: 40rpx; + font-weight: bold; +} + +.section-title-hot { + padding: 32rpx; +} + +.t-swiper { + position: relative; + z-index: 10; + padding-bottom: 36rpx; + margin-bottom: 16rpx; + --td-swiper-item-padding: 0 12rpx; + --td-swiper-radius: 0; + --td-swiper-nav-dot-active-color: @brand-color; + --td-swiper-nav-dot-color: #DCDCDC; +} + +.t-swiper-image { + position: relative; + width: 566rpx !important; + /* height: 318rpx !important; */ + /* box-shadow: 0 6px 30px 5px #0000000d, 0 16px 24px 2px #0000000a, 0 8px 10px -5px #00000014; */ +} + +.t-swiper-nav { + bottom: 0 !important; +} + +.section-title-all { + padding: 32rpx 32rpx 0; +} + +.tabs { + position: sticky; + z-index: 100; + display: flex; + border-bottom: 1rpx solid #E7E7E7; + background-color: #ffffff; +} + +.tab { + position: relative; + display: flex; + justify-content: center; + align-items: center; + gap: 4rpx; + width: 250rpx; + height: 96rpx; + font-size: 28rpx; + line-height: 1; +} + +.filter-tab::before { + content: ""; + position: absolute; + left: 0; + top: 26rpx; + bottom: 26rpx; + width: 2rpx; + background-color: #E7E7E7; +} + +.tab.current { + color: @brand-color; + font-weight: bold; +} + +.filter { + max-height: 80vh; + border-radius: 24rpx 24rpx 0 0; + padding: 32rpx 32rpx 0; + background-color: #ffffff; + overflow-y: scroll; +} + + +.filter-title { + position: relative; + margin-bottom: 28rpx; + font-size: 36rpx; + font-weight: bold; + text-align: center; +} + +.filter-close { + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); +} + +.filter-section { + margin-bottom: 48rpx; +} + +.filter-section-title { + margin-bottom: 24rpx; + font-weight: bold; +} + +.filter-options { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-gap: 24rpx; +} + +.filter-option { + display: flex; + justify-content: center; + align-items: center; + box-sizing: border-box; + height: 80rpx; + border-radius: 40rpx; + background-color: #F3F3F3; +} + +.filter-option.selected { + border: 2rpx solid @brand-color; + background-color: #F2F3FF; +} + +.filter-divider { + margin: 0 0 48rpx 0 !important; +} + +.filter-date { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 32rpx; +} + +.filter-date-button { + margin: 0; + font-size: 28rpx !important; +} + +.filter-bottom { + position: sticky; + bottom: 0; + z-index: 200; + display: flex; + gap: 16rpx; + padding: 32rpx 0; + background-color: #ffffff; +} + +.filter-button { + flex-grow: 1; +} + +.activities { + display: flex; + flex-direction: column; + gap: 32rpx; + padding: 32rpx; +} + +.loading-card { + display: flex; + width: 686rpx; + gap: 32rpx; +} + +.extra { + color: @extra-text-color; + text-align: center; +} diff --git a/pages/home/index.wxml b/pages/home/index.wxml new file mode 100644 index 0000000..2a88bf7 --- /dev/null +++ b/pages/home/index.wxml @@ -0,0 +1,128 @@ + + + + + + +热门推荐 + + + +全部活动 + + 最新活动 + 高分活动 + + + 筛选 + + + + + + + + + 全部筛选 + + + + + + 面向领域 + + {{ item.text }} + + + + + + 活动形式 + + {{ item.text }} + + + + + + + 活动日期 + + {{ utils.formatDate(dateFilter.startTime, dateFilter.endTime) }} + 选择日期 + + + + + + + + 价格范围(元) + + + + + + + + 重置 + 完成 + + + + + + + + + + 暂时没有活动 + 正在加载… + + + + /** 从热门推荐活动中获取图片数组 */ + function getImages(activities) { + var list = [] + activities.forEach(function (activity) { + if (activity.image) + list.push(activity.image) + }) + return list + } + + /** 格式化日期 */ + function formatDate(startTime, endTime) { + if (startTime === null && endTime === null) + return '不限' + endTime -= 86400000 + var start = getDate(startTime) + var y1 = start.getFullYear(), m1 = start.getMonth() + 1, d1 = start.getDate() + if (startTime === endTime) + return y1 + '年' + m1 + '月' + d1 + '日' + var end = getDate(endTime) + var y2 = end.getFullYear(), m2 = end.getMonth() + 1, d2 = end.getDate() + if (y1 === y2) + return y1 + '年' + m1 + '月' + d1 + '日 - ' + m2 + '月' + d2 + '日' + return y1 + '年' + m1 + '月' + d1 + '日 - ' + y2 + '年' + m2 + '月' + d2 + '日' + } + + module.exports = { + getImages: getImages, + formatDate: formatDate, + } + \ No newline at end of file diff --git a/pages/index/index.js b/pages/index/index.js deleted file mode 100644 index 0bc1771..0000000 --- a/pages/index/index.js +++ /dev/null @@ -1,48 +0,0 @@ -// index.js -// 获取应用实例 -const app = getApp() - -Page({ - data: { - motto: 'Hello World', - userInfo: {}, - hasUserInfo: false, - canIUse: wx.canIUse('button.open-type.getUserInfo'), - canIUseGetUserProfile: false, - canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false - }, - // 事件处理函数 - bindViewTap() { - wx.navigateTo({ - url: '../logs/logs' - }) - }, - onLoad() { - if (wx.getUserProfile) { - this.setData({ - canIUseGetUserProfile: true - }) - } - }, - getUserProfile(e) { - // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗 - wx.getUserProfile({ - desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写 - success: (res) => { - console.log(res) - this.setData({ - userInfo: res.userInfo, - hasUserInfo: true - }) - } - }) - }, - getUserInfo(e) { - // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息 - console.log(e) - this.setData({ - userInfo: e.detail.userInfo, - hasUserInfo: true - }) - } -}) diff --git a/pages/index/index.json b/pages/index/index.json deleted file mode 100644 index a860429..0000000 --- a/pages/index/index.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "navigationBarTitleText": "首页", - "usingComponents": {} -} \ No newline at end of file diff --git a/pages/index/index.less b/pages/index/index.less deleted file mode 100644 index eb64203..0000000 --- a/pages/index/index.less +++ /dev/null @@ -1,19 +0,0 @@ -/**index.wxss**/ -.userinfo { - display: flex; - flex-direction: column; - align-items: center; - color: #aaa; -} - -.userinfo-avatar { - overflow: hidden; - width: 128rpx; - height: 128rpx; - margin: 20rpx; - border-radius: 50%; -} - -.usermotto { - margin-top: 200px; -} \ No newline at end of file diff --git a/pages/index/index.wxml b/pages/index/index.wxml deleted file mode 100644 index f00d294..0000000 --- a/pages/index/index.wxml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - 请使用1.4.4及以上版本基础库 - - - - {{userInfo.nickName}} - - - - {{motto}} - - diff --git a/pages/my/index.wxml b/pages/my/index.wxml index d5ba77b..3ad4cbb 100644 --- a/pages/my/index.wxml +++ b/pages/my/index.wxml @@ -1,4 +1,2 @@ - - - My Page - + +pages/my/index.wxml diff --git a/project.private.config.json b/project.private.config.json index 48b9b50..14c2956 100644 --- a/project.private.config.json +++ b/project.private.config.json @@ -1,7 +1,8 @@ { - "projectname": "miniprogram-starter", + "projectname": "tdesign-miniprogram-starter-apply", "setting": { "compileHotReLoad": true }, - "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html" + "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", + "libVersion": "2.32.3" } \ No newline at end of file diff --git a/services/activity.js b/services/activity.js new file mode 100644 index 0000000..1f4ec26 --- /dev/null +++ b/services/activity.js @@ -0,0 +1,56 @@ +import { delay } from './delay' + +/** 获取热门推荐活动 */ +export function fetchHotActivities() { + const mockData = [ + { activityId: 1, image: '/images/mock/activity/hot-activity.png' }, + { activityId: 2, image: '/images/mock/activity/hot-activity.png' }, + { activityId: 3, image: '/images/mock/activity/hot-activity.png' }, + { activityId: 4, image: '/images/mock/activity/hot-activity.png' }, + { activityId: 5, image: '/images/mock/activity/hot-activity.png' }, + ] + return delay().then(() => ({ code: 200, data: mockData })) +} + +/** 获取活动列表 */ +export function fetchActivities({ pageIndex }) { + const mockData = [ + { + activityId: pageIndex * 4 - 3, + image: '/images/mock/activity/activity-1.png', + name: '少年与星空 插画巡展', + rate: 4.5, + bottomPrice: 98, + topPrice: 118, + }, + { + activityId: pageIndex * 4 - 2, + image: '/images/mock/activity/activity-2.png', + name: 'Universe AI艺术展', + rate: 3.5, + bottomPrice: 128, + topPrice: 228, + }, + { + activityId: pageIndex * 4 - 1, + image: '/images/mock/activity/activity-3.png', + name: '2021 SICC服务设计创新大会', + rate: 4.5, + bottomPrice: 88, + topPrice: 228, + }, + { + activityId: pageIndex * 4, + image: '/images/mock/activity/activity-4.png', + name: '2019 SICC服务设计创新大会', + rate: 5, + bottomPrice: 0, + topPrice: 0, + }, + ] + return delay().then(() => { + if (pageIndex > 5) + return { code: 200, data: [] } + return { code: 200, data: mockData } + }) +} \ No newline at end of file diff --git a/services/delay.js b/services/delay.js new file mode 100644 index 0000000..1dfa0e8 --- /dev/null +++ b/services/delay.js @@ -0,0 +1,4 @@ +/** 模拟网络请求的延迟 */ +export function delay(ms = 500) { + return new Promise((resolve) => { setTimeout(resolve, ms); }) +} \ No newline at end of file diff --git a/services/location.js b/services/location.js new file mode 100644 index 0000000..3ba39aa --- /dev/null +++ b/services/location.js @@ -0,0 +1,6 @@ +import { delay } from './delay' + +/** 获取当前所在城市 */ +export function fetchCurrentCity() { + return delay(2000).then(() => ({ code: 200, data: '深圳' })) +} \ No newline at end of file diff --git a/style/global.less b/style/global.less new file mode 100644 index 0000000..67bc1f7 --- /dev/null +++ b/style/global.less @@ -0,0 +1,4 @@ +/* style/global.wxss */ +@brand-color: #0052d9; +@main-text-color: #000000e6; +@extra-text-color: #00000080;