qk 1 year ago
parent a3de5d245a
commit 79500451a7

@ -0,0 +1,7 @@
{
"permissions": {
"openapi": [
"customerServiceMessage.send"
]
}
}

@ -0,0 +1,25 @@
const cloud = require('wx-server-sdk')
cloud.init({
// API 调用都保持和云函数当前所在环境一致
env: cloud.DYNAMIC_CURRENT_ENV
})
// 云函数入口函数
exports.main = async (event, context) => {
console.log(event)
const { OPENID } = cloud.getWXContext()
const result = await cloud.openapi.customerServiceMessage.send({
touser: OPENID,
msgtype: 'text',
text: {
content: `收到:${event.Content}`,
}
})
console.log(result)
return result
}

@ -0,0 +1,14 @@
{
"name": "callback",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.5.1"
}
}

@ -0,0 +1,5 @@
{
"permissions": {
"openapi": []
}
}

@ -0,0 +1,8 @@
const cloud = require('wx-server-sdk')
exports.main = async (event, context) => {
// event.userInfo 是已废弃的保留字段,在此不做展示
// 获取 OPENID 等微信上下文请使用 cloud.getWXContext()
delete event.userInfo
return event
}

@ -0,0 +1,14 @@
{
"name": "echo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.5.1"
}
}

@ -0,0 +1,6 @@
{
"permissions": {
"openapi": [
]
}
}

@ -0,0 +1,16 @@
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
return {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
}
}

@ -0,0 +1,14 @@
{
"name": "getOpenid",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.5.1"
}
}

@ -0,0 +1,6 @@
{
"permissions": {
"openapi": [
]
}
}

@ -0,0 +1,25 @@
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
var len_collect=event.collect.length
var len_content=event.content.length
var array=new Array()
first:for(var i=0;i<len_content;i++){
for(var j=0;j<len_collect;j++){
if(event.collect[j]==event.content[i]._id){
array.push(1)
continue first
}
}
array.push(0)
}
return {
event,
array
}
}

@ -0,0 +1,14 @@
{
"name": "getcollect",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.5.1"
}
}

@ -0,0 +1,26 @@
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
var len_like=event.like.length
var len_content=event.content.length
var array=new Array()
first:for(var i=0;i<len_content;i++){
for(var j=0;j<len_like;j++){
if(event.like[j]==event.content[i]._id){
array.push(1)
continue first
}
}
array.push(0)
}
return {
event,
array
}
}

@ -0,0 +1,14 @@
{
"name": "getlike",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.5.1"
}
}

@ -0,0 +1,5 @@
{
"permissions": {
"openapi": []
}
}

@ -0,0 +1,36 @@
// 云函数模板
// 部署:在 cloud-functions/login 文件夹右击选择 “上传并部署”
const cloud = require('wx-server-sdk')
// 初始化 cloud
cloud.init({
// API 调用都保持和云函数当前所在环境一致
env: cloud.DYNAMIC_CURRENT_ENV
})
/**
* 这个示例将经自动鉴权过的小程序用户 openid 返回给小程序端
*
* event 参数包含小程序端调用传入的 data
*
*/
exports.main = async (event, context) => {
console.log(event)
console.log(context)
// 可执行其他自定义逻辑
// console.log 的内容可以在云开发云函数调用日志查看
// 获取 WX Context (微信调用上下文),包括 OPENID、APPID、及 UNIONID需满足 UNIONID 获取条件)等信息
const wxContext = cloud.getWXContext()
return {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
env: wxContext.ENV,
}
}

@ -0,0 +1,14 @@
{
"name": "login",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.5.1"
}
}

@ -0,0 +1,15 @@
{
"permissions": {
"openapi": [
"wxacode.get",
"subscribeMessage.send",
"subscribeMessage.addTemplate",
"templateMessage.send",
"templateMessage.addTemplate",
"templateMessage.deleteTemplate",
"templateMessage.getTemplateList",
"templateMessage.getTemplateLibraryById",
"templateMessage.getTemplateLibraryList"
]
}
}

@ -0,0 +1,86 @@
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
console.log(event)
switch (event.action) {
case 'requestSubscribeMessage': {
return requestSubscribeMessage(event)
}
case 'sendSubscribeMessage': {
return sendSubscribeMessage(event)
}
case 'getWXACode': {
return getWXACode(event)
}
case 'getOpenData': {
return getOpenData(event)
}
default: {
return
}
}
}
async function requestSubscribeMessage(event) {
// 此处为模板 ID开发者需要到小程序管理后台 - 订阅消息 - 公共模板库中添加模板,
// 然后在我的模板中找到对应模板的 ID填入此处
return '请到管理后台申请模板 ID 然后在此替换' // 如 'N_J6F05_bjhqd6zh2h1LHJ9TAv9IpkCiAJEpSw0PrmQ'
}
async function sendSubscribeMessage(event) {
const { OPENID } = cloud.getWXContext()
const { templateId } = event
const sendResult = await cloud.openapi.subscribeMessage.send({
touser: OPENID,
templateId,
miniprogram_state: 'developer',
page: 'pages/openapi/openapi',
// 此处字段应修改为所申请模板所要求的字段
data: {
thing1: {
value: '咖啡',
},
time3: {
value: '2020-01-01 00:00',
},
}
})
return sendResult
}
async function getWXACode(event) {
// 此处将获取永久有效的小程序码,并将其保存在云文件存储中,最后返回云文件 ID 给前端使用
const wxacodeResult = await cloud.openapi.wxacode.get({
path: 'pages/openapi/openapi',
})
const fileExtensionMatches = wxacodeResult.contentType.match(/\/([^/]+)/)
const fileExtension = (fileExtensionMatches && fileExtensionMatches[1]) || 'jpg'
const uploadResult = await cloud.uploadFile({
// 云文件路径,此处为演示采用一个固定名称
cloudPath: `wxacode_default_openapi_page.${fileExtension}`,
// 要上传的文件内容可直接传入图片 Buffer
fileContent: wxacodeResult.buffer,
})
if (!uploadResult.fileID) {
throw new Error(`upload failed with empty fileID and storage server status code ${uploadResult.statusCode}`)
}
return uploadResult.fileID
}
async function getOpenData(event) {
return cloud.getOpenData({
list: event.openData.list,
})
}

@ -0,0 +1,14 @@
{
"name": "openapi",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.5.1"
}
}

@ -0,0 +1,36 @@
//app.js
App({
onLaunch: function () {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用wx.cloud.xxx会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
env: 'gzyzx1-3ghhs462720864e0',
traceUser: true,
})
this.getOpenId = (function(that){
return new Promise((resolve, reject) =>{
wx.cloud.callFunction({
name: 'getOpenid',
data: {},
success: res => {
that.globalData.openid = res.result.openid
resolve(res.result.openid)
},
fail: err => {
console.error('[云函数] [getOpenid] 调用失败', err)
}
})
})
})(this)
}
this.globalData = {}
}
})

@ -0,0 +1,46 @@
{
"pages": [
"pages/find/find",
"pages/community/community",
"pages/my/my",
"pages/publish/publish",
"pages/detail/detail",
"pages/index/index",
"pages/more/more",
"pages/choose/choose",
"pages/webview/webview"
],
"window": {
"backgroundColor": "#F6F6F6",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#F6F6F6",
"navigationBarTitleText": "中医专线",
"navigationBarTextStyle": "black"
},
"tabBar": {
"color": "#000000",
"selectedColor": "#000000",
"list": [
{
"pagePath": "pages/find/find",
"text": "发现",
"iconPath": "images/fx.png",
"selectedIconPath": "images/fx_selected.png"
},
{
"pagePath": "pages/community/community",
"text": "社区",
"iconPath": "images/sq.png",
"selectedIconPath": "images/sq_selected.png"
},
{
"pagePath": "pages/my/my",
"text": "我的",
"iconPath": "images/wd.png",
"selectedIconPath": "images/wd_selected.png"
}
]
},
"sitemapLocation": "sitemap.json",
"style": "v2"
}

@ -0,0 +1,183 @@
/**app.wxss**/
/* miniprogram/pages/community/community.wxss */
button {
background: initial;
}
button:focus{
outline: 0;
}
button::after{
border: none;
}
page {
background: #f6f6f6;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.userinfo, .uploader, .tunnel {
margin-top: 40rpx;
height: 140rpx;
width: 100%;
background: #fff;
border: 1px solid rgba(0, 0, 0, 0.1);
border-left: none;
border-right: none;
display: flex;
flex-direction: row;
align-items: center;
transition: all 300ms ease;
}
.userinfo-avatar {
width: 100rpx;
height: 100rpx;
margin: 20rpx;
border-radius: 50%;
background-size: cover;
background-color: white;
}
.userinfo-avatar:after {
border: none;
}
.userinfo-nickname {
font-size: 32rpx;
color: #007aff;
background-color: white;
background-size: cover;
}
.userinfo-nickname::after {
border: none;
}
.uploader, .tunnel {
height: auto;
padding: 0 0 0 40rpx;
flex-direction: column;
align-items: flex-start;
box-sizing: border-box;
}
.uploader-text, .tunnel-text {
width: 100%;
line-height: 52px;
font-size: 34rpx;
color: #007aff;
}
.uploader-container {
width: 100%;
height: 400rpx;
padding: 20rpx 20rpx 20rpx 0;
display: flex;
align-content: center;
justify-content: center;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.uploader-image {
width: 100%;
height: 360rpx;
}
.tunnel {
padding: 0 0 0 40rpx;
}
.tunnel-text {
position: relative;
color: #222;
display: flex;
flex-direction: row;
align-content: center;
justify-content: space-between;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.tunnel-text:first-child {
border-top: none;
}
.tunnel-switch {
position: absolute;
right: 20rpx;
top: -2rpx;
}
.disable {
color: #888;
}
.service {
position: fixed;
right: 40rpx;
bottom: 40rpx;
width: 140rpx;
height: 140rpx;
border-radius: 50%;
background: linear-gradient(#007aff, #0063ce);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
display: flex;
align-content: center;
justify-content: center;
transition: all 300ms ease;
}
.service-button {
position: absolute;
top: 40rpx;
}
.service:active {
box-shadow: none;
}
.request-text {
padding: 20rpx 0;
font-size: 24rpx;
line-height: 36rpx;
word-break: break-all;
}
.clear::after{
content: "";
display: block;
clear: both;
}
.container2{
width: 670rpx;
margin: 0 40rpx;
}
.c-bottom{
margin: 10rpx auto;
text-align: center;
font-size: 20rpx;
color: #8c8c8c;
margin-bottom: 100rpx;
}
.search{
width: 100%;
height: 60rpx;
margin: 30rpx 0;
background-color: #ccc;
border-radius: 25rpx;
}
.search2{
width: 610rpx;
height: 60rpx;
margin: 0 30rpx;
display: flex;
}
.search-input{
width: 500rpx;
height: 60rpx;
}
.search-input input{
width: 100%;
height: 60rpx;
text-align: left;
}
.search-submit{
width: 100rpx;
height: 60rpx;
margin-left: 10rpx;
}
.search-submit image{
width: 50rpx;
height: 50rpx;
margin: 5rpx 25rpx;
}
.container {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #fff;
}

@ -0,0 +1,337 @@
const FATAL_REBUILD_TOLERANCE = 10
const SETDATA_SCROLL_TO_BOTTOM = {
scrollTop: 100000,
scrollWithAnimation: true,
}
Component({
properties: {
envId: String,
collection: String,
groupId: String,
groupName: String,
userInfo: Object,
onGetUserInfo: {
type: Function,
},
getOpenID: {
type: Function,
},
},
data: {
chats: [],
textInputValue: '',
openId: '',
scrollTop: 0,
scrollToMessage: '',
hasKeyboard: false,
},
methods: {
onGetUserInfo(e) {
this.properties.onGetUserInfo(e)
},
getOpenID() {
return this.properties.getOpenID()
},
mergeCommonCriteria(criteria) {
return {
groupId: this.data.groupId,
...criteria,
}
},
async initRoom() {
this.try(async () => {
await this.initOpenID()
const { envId, collection } = this.properties
this.db = wx.cloud.database({
env: envId,
})
const db = this.db
const _ = db.command
const { data: initList } = await db.collection(collection).where(this.mergeCommonCriteria()).orderBy('sendTimeTS', 'desc').get()
console.log('init query chats', initList)
this.setData({
chats: initList.reverse(),
scrollTop: 10000,
})
this.initWatch(initList.length ? {
sendTimeTS: _.gt(initList[initList.length - 1].sendTimeTS),
} : {})
}, '初始化失败')
},
async initOpenID() {
return this.try(async () => {
const openId = await this.getOpenID()
this.setData({
openId,
})
}, '初始化 openId 失败')
},
async initWatch(criteria) {
this.try(() => {
const { collection } = this.properties
const db = this.db
const _ = db.command
console.warn(`开始监听`, criteria)
this.messageListener = db.collection(collection).where(this.mergeCommonCriteria(criteria)).watch({
onChange: this.onRealtimeMessageSnapshot.bind(this),
onError: e => {
if (!this.inited || this.fatalRebuildCount >= FATAL_REBUILD_TOLERANCE) {
this.showError(this.inited ? '监听错误,已断开' : '初始化监听失败', e, '重连', () => {
this.initWatch(this.data.chats.length ? {
sendTimeTS: _.gt(this.data.chats[this.data.chats.length - 1].sendTimeTS),
} : {})
})
} else {
this.initWatch(this.data.chats.length ? {
sendTimeTS: _.gt(this.data.chats[this.data.chats.length - 1].sendTimeTS),
} : {})
}
},
})
}, '初始化监听失败')
},
onRealtimeMessageSnapshot(snapshot) {
console.warn(`收到消息`, snapshot)
if (snapshot.type === 'init') {
this.setData({
chats: [
...this.data.chats,
...[...snapshot.docs].sort((x, y) => x.sendTimeTS - y.sendTimeTS),
],
})
this.scrollToBottom()
this.inited = true
} else {
let hasNewMessage = false
let hasOthersMessage = false
const chats = [...this.data.chats]
for (const docChange of snapshot.docChanges) {
switch (docChange.queueType) {
case 'enqueue': {
hasOthersMessage = docChange.doc._openid !== this.data.openId
const ind = chats.findIndex(chat => chat._id === docChange.doc._id)
if (ind > -1) {
if (chats[ind].msgType === 'image' && chats[ind].tempFilePath) {
chats.splice(ind, 1, {
...docChange.doc,
tempFilePath: chats[ind].tempFilePath,
})
} else chats.splice(ind, 1, docChange.doc)
} else {
hasNewMessage = true
chats.push(docChange.doc)
}
break
}
}
}
this.setData({
chats: chats.sort((x, y) => x.sendTimeTS - y.sendTimeTS),
})
if (hasOthersMessage || hasNewMessage) {
this.scrollToBottom()
}
}
},
async onConfirmSendText(e) {
this.try(async () => {
if (!e.detail.value) {
return
}
const { collection } = this.properties
const db = this.db
const _ = db.command
const doc = {
_id: `${Math.random()}_${Date.now()}`,
groupId: this.data.groupId,
avatar: this.data.userInfo.avatarUrl,
nickName: this.data.userInfo.nickName,
msgType: 'text',
textContent: e.detail.value,
sendTime: new Date(),
sendTimeTS: Date.now(), // fallback
}
this.setData({
textInputValue: '',
chats: [
...this.data.chats,
{
...doc,
_openid: this.data.openId,
writeStatus: 'pending',
},
],
})
this.scrollToBottom(true)
await db.collection(collection).add({
data: doc,
})
this.setData({
chats: this.data.chats.map(chat => {
if (chat._id === doc._id) {
return {
...chat,
writeStatus: 'written',
}
} else return chat
}),
})
}, '发送文字失败')
},
async onChooseImage(e) {
wx.chooseImage({
count: 1,
sourceType: ['album', 'camera'],
success: async res => {
const { envId, collection } = this.properties
const doc = {
_id: `${Math.random()}_${Date.now()}`,
groupId: this.data.groupId,
avatar: this.data.userInfo.avatarUrl,
nickName: this.data.userInfo.nickName,
msgType: 'image',
sendTime: new Date(),
sendTimeTS: Date.now(), // fallback
}
this.setData({
chats: [
...this.data.chats,
{
...doc,
_openid: this.data.openId,
tempFilePath: res.tempFilePaths[0],
writeStatus: 0,
},
]
})
this.scrollToBottom(true)
const uploadTask = wx.cloud.uploadFile({
cloudPath: `${this.data.openId}/${Math.random()}_${Date.now()}.${res.tempFilePaths[0].match(/\.(\w+)$/)[1]}`,
filePath: res.tempFilePaths[0],
config: {
env: envId,
},
success: res => {
this.try(async () => {
await this.db.collection(collection).add({
data: {
...doc,
imgFileID: res.fileID,
},
})
}, '发送图片失败')
},
fail: e => {
this.showError('发送图片失败', e)
},
})
uploadTask.onProgressUpdate(({ progress }) => {
this.setData({
chats: this.data.chats.map(chat => {
if (chat._id === doc._id) {
return {
...chat,
writeStatus: progress,
}
} else return chat
})
})
})
},
})
},
onMessageImageTap(e) {
wx.previewImage({
urls: [e.target.dataset.fileid],
})
},
scrollToBottom(force) {
if (force) {
console.log('force scroll to bottom')
this.setData(SETDATA_SCROLL_TO_BOTTOM)
return
}
this.createSelectorQuery().select('.body').boundingClientRect(bodyRect => {
this.createSelectorQuery().select(`.body`).scrollOffset(scroll => {
if (scroll.scrollTop + bodyRect.height * 3 > scroll.scrollHeight) {
console.log('should scroll to bottom')
this.setData(SETDATA_SCROLL_TO_BOTTOM)
}
}).exec()
}).exec()
},
async onScrollToUpper() {
if (this.db && this.data.chats.length) {
const { collection } = this.properties
const _ = this.db.command
const { data } = await this.db.collection(collection).where(this.mergeCommonCriteria({
sendTimeTS: _.lt(this.data.chats[0].sendTimeTS),
})).orderBy('sendTimeTS', 'desc').get()
this.data.chats.unshift(...data.reverse())
this.setData({
chats: this.data.chats,
scrollToMessage: `item-${data.length}`,
scrollWithAnimation: false,
})
}
},
async try(fn, title) {
try {
await fn()
} catch (e) {
this.showError(title, e)
}
},
showError(title, content, confirmText, confirmCallback) {
console.error(title, content)
wx.showModal({
title,
content: content.toString(),
showCancel: confirmText ? true : false,
confirmText,
success: res => {
res.confirm && confirmCallback()
},
})
},
},
ready() {
global.chatroom = this
this.initRoom()
this.fatalRebuildCount = 0
},
})

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

@ -0,0 +1,85 @@
<view class="chatroom">
<view class="header">
<!-- display number of people in the room -->
<view class="left"></view>
<!-- room name -->
<view class="middle">{{groupName}}</view>
<!-- reserved -->
<view class="right"></view>
</view>
<!-- chats -->
<scroll-view
class="body"
scroll-y
scroll-with-animation="{{scrollWithAnimation}}"
scroll-top="{{scrollTop}}"
scroll-into-view="{{scrollToMessage}}"
bindscrolltoupper="onScrollToUpper"
>
<view
wx:for="{{chats}}"
wx:key="{{item._id}}"
id="item-{{index}}"
class="message {{openId == item._openid ? 'message__self' : ''}}"
>
<image
class="avatar"
src="{{item.avatar}}"
mode="scaleToFill"
></image>
<view class="main">
<view class="nickname">{{item.nickName}}</view>
<block wx:if="{{item.msgType === 'image'}}">
<view class="image-wrapper">
<view class="loading" wx:if="{{item.writeStatus > -1}}">{{item.writeStatus}}%</view>
<image
src="{{item.tempFilePath || item.imgFileID}}"
data-fileid="{{item.tempFilePath || item.imgFileID}}"
class="image-content"
style="{{item.imgStyle}}"
mode="scallToFill"
bindtap="onMessageImageTap"></image>
</view>
</block>
<block wx:else>
<view class="text-wrapper">
<view class="loading" wx:if="{{item.writeStatus === 'pending'}}">···</view>
<view class="text-content">{{item.textContent}}</view>
</view>
</block>
</view>
</view>
</scroll-view>
<!-- message sender -->
<view class="footer">
<view class="message-sender" wx:if="{{userInfo}}">
<input
class="text-input"
type="text"
confirm-type="send"
bindconfirm="onConfirmSendText"
cursor-spacing="20"
value="{{textInputValue}}"
></input>
<image
src="./photo.png"
class="btn-send-image"
mode="scaleToFill"
bindtap="onChooseImage"
></image>
</view>
<view class="message-sender" wx:if="{{!userInfo}}">
<button
open-type="getUserInfo"
bindgetuserinfo="onGetUserInfo"
class="userinfo"
>请先登录后参与聊天</button>
</view>
</view>
</view>

@ -0,0 +1,161 @@
.chatroom {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.chatroom .header {
flex-basis: fit-content;
display: flex;
flex-direction: row;
border-bottom: 1px solid #ddd;
padding: 20rpx 0 30rpx;
font-size: 30rpx;
/* background: rgb(34, 187, 47);
color: rgba(255, 255, 255, 1) */
/* font-family: 'Microsoft YaHei' */
}
.chatroom .header .left {
flex: 1;
}
.chatroom .header .middle {
flex: 2;
text-align: center;
}
.chatroom .header .right {
flex: 1;
}
.chatroom .body {
flex: 2;
display: flex;
flex-direction: column;
background: rgb(237,237,237);
padding-bottom: 16rpx;
}
.body .message {
display: flex;
flex-direction: row;
position: relative;
margin: 12rpx 0;
}
.body .message.message__self {
flex-direction: row-reverse;
}
.body .message .avatar {
position: relative;
top: 5rpx;
width: 60rpx;
height: 60rpx;
border-radius: 5rpx;
margin: 15rpx;
}
.body .message .main {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.body .message.message__self .main {
align-items: flex-end;
}
.body .message .nickname {
font-size: 24rpx;
color: #444;
}
.body .message .text-content {
border: 1px solid transparent;
border-radius: 3px;
background-color: #fff;
margin: 2px 0 0 0;
padding: 4px 10px;
font-size: 30rpx;
display: inline-block;
}
.body .message.message__self .text-content {
background-color: paleturquoise;
}
.body .message .text-wrapper {
display: flex;
flex-direction: row;
align-items: center;
max-width: 80%;
}
.body .message.message__self .text-wrapper .loading{
font-size: 16rpx;
margin-right: 18rpx;
}
.body .message .image-wrapper {
display: flex;
flex-direction: row;
align-items: center;
}
.body .message .image-content {
max-width: 240rpx;
max-height: 240rpx;
}
.body .message.message__self .image-wrapper .loading {
font-size: 20rpx;
margin-right: 18rpx;
}
.chatroom .footer {
flex-basis: fit-content;
display: flex;
flex-direction: row;
border-top: 1px solid #ddd;
font-size: 10rpx;
padding: 20rpx 30rpx;
background: rgb(246,246,246);
}
.chatroom .footer .message-sender {
flex: 1;
display: flex;
flex-direction: row;
}
.message-sender .text-input {
flex: 1;
font-size: 16px;
border: 1px solid transparent;
border-radius: 5px;
padding: 3px 6px;
margin: 0 10px 0 5px;
background: #fff;
}
.message-sender .btn-send-image {
width: 50rpx;
height: 50rpx;
align-self: center;
}
button {
font-size: 30rpx;
}
button.userinfo {
background: darkturquoise;
color: aliceblue;
padding: 0 100rpx;
border: 1px solid #ddd;
border-radius: 20px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

@ -0,0 +1,82 @@
// pages/choose/choose.js
Page({
/**
* 页面的初始数据
*/
data: {
},
recycle:function(){
wx.navigateTo({
url: '../publish/publish?mode=recycle',
})
},
partjob:function(){
wx.navigateTo({
url: '../publish/publish?mode=partjob',
})
},
college:function(){
wx.navigateTo({
url: '../publish/publish?mode=college',
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
wx.removeStorage({
key: 'content',
})
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

@ -0,0 +1,21 @@
<!--pages/choose/choose.wxml-->
<view class="container2">
<view bindtap="recycle">
<view class="img">
<image src="../../images/recycle.png"></image>
</view>
<view>二手闲置</view>
</view>
<view bindtap="partjob">
<view class="img">
<image src="../../images/partjob.png"></image>
</view>
<view>兼职实习</view>
</view>
<view bindtap="college">
<view class="img">
<image src="../../images/college.png"></image>
</view>
<view>校园资讯</view>
</view>
</view>

@ -0,0 +1,26 @@
/* pages/choose/choose.wxss */
.container2>view{
margin-top: 40rpx;
border-radius: 20rpx;
box-shadow: 5px 5px 5px #888888;
border-bottom: 1px solid #808080;
display: flex;
flex-wrap: wrap;
width: 100%;
height: 200rpx;
align-items: center;
justify-content: space-evenly;
font-size: 40rpx;
font-weight: 700;
}
.img{
width: 100rpx;
height: 100rpx;
}
.container2>view>view{
display: inline-block
}
image{
width: 100%;
height: 100%;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,5 @@
{
"usingComponents": {},
"enablePullDownRefresh": true
}

@ -0,0 +1,181 @@
<!--miniprogram/pages/community/community.wxml-->
<wxs module="func">
var transtime=function(dateTime){
var dateTimeStamp =getDate(dateTime);
var result = '';
var minute = 1000 * 60;
var hour = minute * 60;
var day = hour * 24;
var halfamonth = day * 15;
var month = day * 30;
var year = day * 365;
var now = getDate();
var diffValue = now - dateTimeStamp;
if (diffValue < 0) {
return;
}
var monthEnd = diffValue / month;
var weekEnd = diffValue / (7 * day);
var dayEnd = diffValue / day;
var hourEnd = diffValue / hour;
var minEnd = diffValue / minute;
var yearEnd = diffValue / year;
if (yearEnd >= 1) {
result = dateTime;
} else if (monthEnd >= 1) {
result = dateTime;
} else if (dayEnd >= 4) {
result = dateTime;
} else if ((dayEnd >= 1)&&(dayEnd<=3)){
result = "" + parseInt(dayEnd) + "天前";
} else if (hourEnd >= 1) {
result = "" + parseInt(hourEnd) + "小时前";
} else if (minEnd >= 1) {
result = "" + parseInt(minEnd) + "分钟前";
} else {
result = "刚刚";
}
return result;
}
module.exports.transtime = transtime
</wxs>
<view class="container2" >
<view class="search">
<view class="search2">
<view class="search-input"><input placeholder="输入关键字搜索" bindinput="inputchange" value="{{inputcon}}"/></view>
<view class="search-submit"><image src="../../images/ss.png" bindtap="search"></image></view>
</view>
</view>
<view class="menu">
<view class="{{new_}}" bindtap="menu_new">论坛</view>
<view class="{{hot_}}" bindtap="menu_hot">视频</view>
<picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}" name="type" style="display:inline-block">
<view class="picker" >
筛选
</view>
</picker>
<view class="backtop" bindtap="backtop">
回到顶部
</view>
</view>
<view wx:if="{{new_}}" class="forum" >
<scroll-view scroll-y="true" bindscrolltolower="lower" scroll-top="{{main_top}}" refresher-enabled="true" bindrefresherrefresh="refresh" refresher-triggered="{{isrefresh}}" style="height:1100rpx">
<view class="content" wx:for="{{content}}" wx:key="index">
<view class="num">
<view>{{index<9?'0'+(index+1):index+1}}</view>
</view>
<view class="content2" bindtap="detail" data-index="{{index}}">
<text class="title">#{{item.type}}</text>
<image class="title_img" wx:if="{{item.type=='二手闲置'}}" src="../../images/recycle.png"></image>
<image class="title_img" wx:if="{{item.type=='兼职实习'}}" src="../../images/partjob.png"></image>
<image class="title_img" wx:if="{{item.type=='校园资讯'}}" src="../../images/college.png"></image>
<text class="title">#{{item.z_type}}\n</text>
<text class="message" wx:if="{{item.type=='二手闲置'}}">
{{item.recycle.obj_name+'*'+item.recycle.obj_num+':'+item.recycle.obj_price}}\n
</text>
<text class="message" wx:if="{{item.type=='兼职实习'}}">
{{item.partjob.unit+'-'+item.partjob.name}}\n
</text>
<text class="message" wx:if="{{item.type=='校园资讯'}}">{{item.college}}\n</text>
<text class="c-time">{{func.transtime(item.date)}}</text>
</view>
<view class="img" wx:if="{{item.img}}">
<image src="{{item.img}}"/>
</view>
<view class="con-bottom">
<view class="good" bindtap="good" data-index="{{index}}" data-id="{{item._id}}">
<image src="{{like[index]==1?'../../images/good-active.png':'../../images/good.png'}}"></image>
<text>{{item.like}}</text>
</view>
<view class="comment" bindtap="comment" data-index="{{index}}" data-id="{{item._id}}">
<image src="../../images/comment.png"></image>
<text>{{item.comment}}</text>
</view>
<view class="favor" bindtap="favor" data-index="{{index}}" data-id="{{item._id}}">
<image src="{{collect[index]==1?'../../images/favor-active.png':'../../images/favor.png'}}"></image>
<text>{{item.collect_num}}</text>
</view>
</view>
</view>
<view class="c-bottom" style="height:500rpx">欢迎关注微信公众号广中E专线一</view>
</scroll-view>
<button class="publish" bindtap="publish" wx:if="{{canIUseGetUserProfile}}" >
<image src="../../images/publish.png"></image>
</button>
</view>
<view wx:if="{{hot_}}">
<scroll-view scroll-y="true" bindscrolltolower="lower" scroll-top="{{main_top}}" refresher-enabled="true" bindrefresherrefresh="refresh1" refresher-triggered="{{isrefresh1}}" style="height:1100rpx">
<view class="content" wx:for="{{video}}" wx:key="index">
<view class="num v-num">
<view>{{index<9?'0'+(index+1):index+1}}</view>
</view>
<text class="title v-title">#{{item.type}}\n</text>
<video
src="{{item.src}}"
binderror="videoErrorCallback"
show-center-play-btn='{{false}}'
show-play-btn="{{true}}"
controls
picture-in-picture-mode="{{['push', 'pop']}}"
bindenterpictureinpicture='bindVideoEnterPictureInPicture'
bindleavepictureinpicture='bindVideoLeavePictureInPicture'
></video>
<view class="con-bottom">
<view class="good" bindtap="good_video" data-index="{{index}}" data-id="{{item._id}}">
<image src="{{like_video[index]==1?'../../images/good-active.png':'../../images/good.png'}}"></image>
<text>{{item.like_video}}</text>
</view>
<view class="comment" bindtap="comment" data-index="{{index}}" data-id="{{item._id}}">
<image src="../../images/comment.png"></image>
<text>{{item.comment}}</text>
</view>
<view class="favor" bindtap="favor_video" data-index="{{index}}" data-id="{{item._id}}">
<image src="{{collect_video[index]==1?'../../images/favor-active.png':'../../images/favor.png'}}"></image>
<text>{{item.collect_video}}</text>
</view>
</view>
</view>
<view class="c-bottom" style="height:400rpx">欢迎关注微信公众号广中E专线一</view>
</scroll-view>
</view>
</view>
<view class="container3 {{iscomment?'show':'none'}} " >
<view style="width:100%;height:38%" bindtap="close"></view>
<view class="comment1">
<scroll-view scroll-y="true" bindscrolltolower="lower2" style="height:100%">
<view class="c-title">全部评论</view>
<view class="c-content clear" wx:for="{{comment}}" >
<view class="c-content1">
<view class="h-cut">
<image src="{{item.img}}"></image>
</view>
</view>
<view class="c-content2">
<view class="c-name">{{item.username}}</view>
<text>\n</text>
<text class="c-mess">{{item.content}}</text>
<text>\n</text>
<view class="c-time">{{func.transtime(item.date)}}</view>
</view>
</view>
<view class="c-bottom" style="height:200rpx">{{comment==''?'还没有人评论过,快来抢沙发吧~':'欢迎关注微信公众号:中医专线'}}</view>
</scroll-view>
</view>
<form catchsubmit="formSubmit">
<view class="input">
<view class="input1">
<textarea type="text" name="com_content" value="{{commentinput}}"
style="height:68rpx;line-height:10rpx;width:auto"></textarea>
</view>
<button class="input2" wx:if="{{canIUseGetUserProfile&&!getprofile}}" bindtap="getUserProfile">评论</button>
<button class="input2" wx:if="{{canIUseGetUserProfile&&getprofile}}" formType="submit">评论</button>
</view>
</form>
</view>

@ -0,0 +1,265 @@
page{
height: 100%;
overflow: hidden;
}
.menu{
width: fit-content;
border-radius: 10rpx;
overflow: hidden;
margin: 0 auto;
text-align: center;
}
.backtop{
position: relative;
margin-left: 30rpx;
}
.backtop::after{
position: absolute;
right: 116rpx;
top: 16rpx;
border: 15rpx solid transparent;
border-top: 20rpx solid #808080;
content: "";
transform: rotate(180deg);
}
.active{
background-color: #169BD5;
color:#fff!important
}
.menu view{
display: inline-block;
width:120rpx;
height: 80rpx;
line-height: 80rpx;
font-size: 25rpx;
color: #8C8C8C;
}
.content:nth-of-type(1) .num{
background-color: #ca5639!important;
}
.content:nth-of-type(2) .num{
background-color: #f1c020!important;
}
.content:nth-of-type(3) .num{
background-color:#ceba04!important;
}
/* .content:nth-last-of-type(1){
margin-bottom: 500rpx!important;
} */
.content{
padding: 10rpx 0;
border-bottom: 1px solid #ddd;
}
.num{
width:fit-content;
padding: 0 10rpx;
height: 50rpx;
line-height: 50rpx;
border-radius: 10rpx;
background-color: #ddd;
text-align: center;
font-size: 25rpx;
font-weight: 700;
}
.content2{
width: 100%;
max-width: 500rpx;
height: 160rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-top: 10rpx;
display: inline-block;
clear: both;
}
.title{
font-size: 30rpx;
color: #169BD5;
}
.title_img{
width: 35rpx;
height:35rpx;
margin: 0 10rpx;
}
.message{
font-size: 25rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.img{
width: 150rpx;
height: 150rpx;
float: right;
margin-right: 20rpx;
}
.img image{
width: 100%;
height: 100%;
}
.con-bottom{
display: flex;
}
.con-bottom>view{
display: inline-block;
width: 33%;
height: 50rpx;
line-height: 50rpx;
font-size: 25rpx;
color: #8C8C8C;
}
.con-bottom image{
margin-right: 10rpx;
width: 30%;
height: 60%;
}
.good{
padding-right: 100rpx;
text-align: left;
}
.comment{
padding: 0 50rpx;
text-align: center;
}
.favor{
padding-left: 100rpx;
text-align: right;
}
.good>text,
.comment>text,
.favor>text{
display: inline-block;
width: 50rpx;
text-align: center;
}
.publish{
padding: 0;
position: absolute;
display: inline-block;
width: 100rpx!important;
height: 100rpx!important;
left: 0;
right: 0;
margin: auto;
bottom: 30rpx;
}
.publish image{
width: 100%;
height: 100%;
}
video{
margin: 20rpx 0;
width: 100%;
}
.none{
bottom: -100%;
}
.show{
bottom: 0;
}
.container3{
width: 100%;
height: 100%;
position: absolute;
background-color: transparent;
transition: 0.5s;
}
.comment1{
border: 1px solid #ddd;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 60%;
background-color: #fff;
padding: 20rpx;
overflow: scroll;
}
.h-cut{
width: 80rpx;
height: 80rpx;
overflow:hidden;
border-radius: 50%;
}
.h-cut image{
width: 100%;
height: 100%;
}
.c-title{
font-weight: 700;
}
.c-content{
margin-top: 20rpx;
padding: 20rpx 0;
width: 100%;
border-bottom: 1px solid #ddd;
background-color: rgb(255, 255, 255,0.5);
}
.c-content view{
display: inline-block;
}
.c-content1{
max-width: 120rpx;
max-height: 160rpx;
text-align: center;
float: left;
margin:5rpx 18rpx;
}
.c-content2{
max-width: 550rpx;
}
.c-name{
font-size: 25rpx;
font-weight: 700;
}
.c-mess{
font-size: 25rpx;
word-break: break-all;
}
.c-time{
font-size: 18rpx;
color: #8c8c8c;
}
.input{
display: flex;
justify-content: space-around;
align-items: center;
bottom: 0;
position: absolute;
height: 100rpx;
width: 100%;
background-color: #fff;
}
.input1{
width: 500rpx;
height: 70rpx;
line-height: 70rpx;
border-radius: 20rpx;
border: 1px solid #ddd;
}
.input2{
padding: 0;
margin: 0!important;
width: 130rpx!important;
height: 70rpx!important;
line-height: 70rpx;
text-align: center;
border-radius: 20rpx;
color: #fff;
background-color: #169BD5;
}
.v-num,.v-title{
display: inline-block;
margin-right: 20rpx;
}

@ -0,0 +1,218 @@
// miniprogram/pages/detail/detail.js
var util = require('../../utils/util.js')
const app = getApp();
const db=wx.cloud.database().collection('user')
const dd=wx.cloud.database()
const db2=wx.cloud.database().collection('community')
Page({
/**
* 页面的初始数据
*/
data: {
main_top:'',
openid:'',
currentdate:'',
canIUse: wx.canIUse('button.open-type.getUserInfo'),
userInfo: {},
hasUserInfo: false,
canIUseGetUserProfile: false,
imgList: [],
head_cut:'',
authorname:'',
content:[],
comment:[],
commentinput:'',
showtop:false
},
formSubmit(e) {
const that= this
var input_content=e.detail.value.com_content
var _time = util.formatTime(new Date())
if(!input_content){
wx.showToast({
title: '请输入评论内容!',
icon:'none'
})
return
}
const _=dd.command
dd.collection('comment').add({
data: {
commentid: that.data.content._id,
username:that.data.userInfo.nickName,
img:that.data.userInfo.avatarUrl,
content:input_content,
date:_time
},
success: function(res) {
// res 是一个对象,其中有 _id 字段标记刚创建的记录的 id
console.log(res)
wx.showToast({
title: '评论成功!',
})
var array=[{
commentid: that.data.content._id,
username:that.data.userInfo.nickName,
img:that.data.userInfo.avatarUrl,
content:input_content,
date:_time
}]
that.setData({
comment:array.concat(that.data.comment),
commentinput:''
})
db2.doc(that.data.content._id).update({
data:{
comment:_.inc(1)
}
}).then()
}
})
},
preview(event) {
let currentUrl = event.currentTarget.dataset.src
const that=this
wx.cloud.getTempFileURL({
fileList:[currentUrl],
success(res){
console.log(res)
const a = `imgList[${0}]`
that.setData({
[a]:res.fileList[0].tempFileURL
})
console.log(that.data.imgList)
wx.previewImage({
current: currentUrl, // 当前显示图片的http链接
urls: that.data.imgList // 需要预览的图片http链接列表
})
}
})
},
getUserProfile(e) {
// 推荐使用wx.getUserProfile获取用户信息开发者每次通过该接口获取用户个人信息均需用户确认
// 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
const that= this
if(that.data.hasUserInfo){
console.log(that.data.userInfo)
}else{
wx.getUserProfile({
desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
that.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
wx.setStorageSync('userInfo', that.data.userInfo)
db.add({
data:{
_id:that.data.openid,
nickName:that.data.userInfo.nickName,
avatarUrl:that.data.userInfo.avatarUrl,
city:that.data.userInfo.city,
collect:[],
like:[]
}
})
}
})
}
},
onShow:function(){
const that=this
var _time = util.formatTime(new Date())
that.setData({
currentdate:_time
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
const that= this
if (wx.getUserProfile) {
this.setData({
canIUseGetUserProfile: true
})
}
var openid=wx.getStorageSync('openid')
that.setData({
content:JSON.parse(options.content),
comment:[],
openid:openid
})
db.doc(that.data.content._openid).get({
success:function(res){
console.log(res.data)
that.setData({
head_cut:res.data.avatarUrl,
authorname:res.data.nickName
})
}
})
dd.collection('comment').orderBy("date","desc").where({
commentid:that.data.content._id
}).get({
success: function(res) {
// res.data 是包含以上定义的两条记录的数组
wx.showLoading({
title: '加载中',
mask:'true'
})
that.setData({
comment:res.data,
}, () => {
wx.hideLoading()
})
}
})
var arr=wx.getStorageSync('userInfo')
console.log(arr)
that.setData({
userInfo:arr
})
},
lower(e){
const that=this
var x=that.data.comment.length
let old_data = that.data.comment
wx.showLoading({
title: '加载中...',
mask:'true'
})
var _=dd.command
dd.collection('comment').where({
commentid:that.data.content._id,
date:_.lt(that.data.currentdate)
}).orderBy('date','desc').skip(x) // 限制返回数量为 20 条
.get()
.then(res => {
console.log(res.data)
// 利用concat函数连接新数据与旧数据
if(res.data.length==0){
wx.hideLoading()
wx.showToast({
title: '已经到底了!',
icon:'none'
})
return
}
this.setData({
comment: old_data.concat(res.data),
})
wx.hideLoading({
success: (res) => {},
})
})
.catch(err => {
console.error(err)
})
}
})

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

@ -0,0 +1,79 @@
<!--miniprogram/pages/detail/detail.wxml-->
<scroll-view scroll-y="true" bindscrolltolower="lower" scroll-top="{{main_top}}" style="height:100vh" scroll-top="{{main_top}}" enable-back-to-top="true">
<view class="container4">
<view class="author">
<view class="a-head">
<image src="{{head_cut}}"></image>
</view>
<view class="a-content">
<view class="a-name">{{authorname}}</view>
<view class="c-time">{{content.date}}</view>
</view>
</view>
<view class="title">#{{content.type}}</view>
<image class="title_img" wx:if="{{content.type=='二手闲置'}}" src="../../images/recycle.png"></image>
<image class="title_img" wx:if="{{content.type=='兼职实习'}}" src="../../images/partjob.png"></image>
<image class="title_img" wx:if="{{content.type=='校园资讯'}}" src="../../images/college.png"></image>
<view class="title">#{{content.z_type}}\n</view>
<!-- <view class="content">
<text>{{content.content}}</text>
</view> -->
<view class="content" wx:if="{{content.type=='二手闲置'}}">
<view><text>物品名称:</text> {{content.recycle.obj_name}}</view>
<view><text>数量(个):</text>{{content.recycle.obj_num}}</view>
<view><text>价格(¥):</text>{{content.recycle.obj_price}}</view>
<view><text>交易地点:</text>{{content.recycle.obj_address}}</view>
<view><text>联系方式:</text>{{content.recycle.obj_contact}}</view>
<view wx:if="{{content.recycle.obj_note}}"><text>备注:\n</text><text>{{content.recycle.obj_note}}</text></view>
</view>
<view class="content" wx:if="{{content.type=='兼职实习'}}">
<view><text>工作单位:</text>{{content.partjob.unit}}</view>
<view><text>岗位名称:</text>{{content.partjob.name}}</view>
<view><text>工作时间:</text>{{content.partjob.time}}</view>
<view><text>工作地点:</text>{{content.partjob.address}}</view>
<view><text>工作内容:\n</text> <text>{{content.partjob.content}}</text></view>
<view><text>工作要求:\n</text> <text>{{content.partjob.require}}</text></view>
<view><text>薪资及发放方式:</text>{{content.partjob.salary}}</view>
<view><text>报名方式:</text>{{content.partjob.sign_way}}</view>
<view wx:if="{{content.partjob.note}}"><text>备注:\n</text> <text>{{content.partjob.note}}</text></view>
</view>
<view class="content" wx:if="{{content.type=='校园资讯'}}">
<view style="line-height:50rpx"><text>{{content.college}}</text></view>
</view>
<view class="photo" wx:if="{{content.img}}">
<image mode="widthFix" src="{{content.img}}" bindtap="preview" data-src="{{content.img}}"></image>
</view>
<view class="split"></view>
</view>
<view class="comment1">
<view class="c-title">全部评论</view>
<view class="c-content clear" wx:for="{{comment}}">
<view class="c-content1">
<view class="h-cut">
<image src="{{item.img}}"></image>
</view>
</view>
<view class="c-content2">
<view class="c-name">{{item.username}}</view>
<text>\n</text>
<view class="c-mess">
<text>{{item.content}}</text>
</view>
<text>\n</text>
<view class="c-time">{{item.date}}</view>
</view>
</view>
<view class="c-bottom">{{comment==''?'还没有人评论过,快来抢沙发吧~':'欢迎关注微信公众号:广中医专线一'}}</view>
</view>
</scroll-view>
<form catchsubmit="formSubmit">
<view class="input">
<view class="input1">
<textarea type="text" name="com_content" value="{{commentinput}}"
style="height:68rpx;line-height:10rpx;width:auto"></textarea>
</view>
<button class="input2" wx:if="{{canIUseGetUserProfile&&userInfo==''}}" bindtap="getUserProfile">评论</button>
<button class="input2" wx:if="{{canIUseGetUserProfile&&userInfo}}" formType="submit" >评论</button>
</view>
</form>

@ -0,0 +1,139 @@
/* miniprogram/pages/detail/detail.wxss */
.title_img{
width: 50rpx;
height:50rpx;
margin: -10rpx 10rpx;
}
.author{
height: 80rpx;
line-height: 40rpx;
}
.author>view{
display: inline-block;
}
.a-head{
width: 80rpx;
height: 80rpx;
overflow: hidden;
border-radius: 50%;
}
.a-head image{
width: 100%;
height: 100%;
}
.a-content{
max-width: 80%;
margin-left: 30rpx;
}
.a-name{
font-weight: 600;
}
.container4{
padding: 20rpx 40rpx;
background-color: #fff;
/* background-color: aqua; */
}
.title{
display: inline-block;
margin-top: 20rpx;
color: #169BD5;
font-size: 40rpx;
}
.content{
margin: 20rpx 0;
font-size: 30rpx;
}
.content view{
word-break: break-all;
font-family: fangsong;
line-height: 60rpx;
}
.content view text:nth-of-type(1){
font-weight: 700;
}
.split{
margin-top: 20rpx;
border: 2px dashed #8c8c8c;
}
.comment1{
background-color: #fff;
padding: 20rpx;
margin-bottom: 100rpx;
}
.h-cut{
width: 80rpx;
height: 80rpx;
overflow:hidden;
border-radius: 50%;
}
.h-cut image{
width: 100%;
height: 100%;
}
.c-title{
font-weight: 700;
}
.c-content{
margin-top: 20rpx;
padding: 20rpx 0;
width: 100%;
border-bottom: 1px solid #ddd;
background-color: rgb(255, 255, 255,0.5);
}
.c-content view{
display: inline-block;
}
.c-content1{
max-width: 120rpx;
max-height: 160rpx;
text-align: center;
float: left;
margin:5rpx 18rpx;
}
.c-content2{
max-width: 550rpx;
}
.c-name{
font-size: 25rpx;
font-weight: 700;
}
.c-mess{
font-size: 25rpx;
word-break: break-all;
}
.c-time{
font-size: 15rpx;
color: #8c8c8c;
}
.input{
display: flex;
justify-content: space-around;
align-items: center;
bottom: 0;
position: fixed;
height: 100rpx;
width: 100%;
background-color: #fff;
}
.input1{
width: 500rpx;
height: 70rpx;
line-height: 70rpx;
border-radius: 20rpx;
border: 1px solid #ddd;
}
.input2{
padding: 0;
margin: 0!important;
width: 130rpx!important;
height: 70rpx!important;
line-height: 70rpx;
text-align: center;
border-radius: 20rpx;
color: #fff;
background-color: #169BD5;
}

@ -0,0 +1,111 @@
// miniprogram/pages/find/find.js
const db = wx.cloud.database();
Page({
data: {
inputcon:'',
swiperImg:
[],//轮播图图片列表
showindex1:0,
bannerImg1:[
'cloud://iii-apple-5g4fz3cz1a2cc511.6969-iii-apple-5g4fz3cz1a2cc511-1304058842/互联网.png',
'cloud://iii-apple-5g4fz3cz1a2cc511.6969-iii-apple-5g4fz3cz1a2cc511-1304058842/数学建模.png',
'cloud://iii-apple-5g4fz3cz1a2cc511.6969-iii-apple-5g4fz3cz1a2cc511-1304058842/数学能力挑战赛.png'],
showindex2:0,
},
/**
* 生命周期函数--监听页面加载
*/
sliderto:function(e){
console.log(e)
var url=e.currentTarget.dataset.url
wx.navigateTo({
url: '/pages/webview/webview?url=' + url,
})
},
onLoad: function (options) {
const that=this
/*轮播图 */
db.collection('slider').orderBy('index','asc').get({
success:function(res){
that.setData({
swiperImg:res.data
})
}
})
/*推荐栏*/
db.collection('recommend').limit(6).orderBy('index','asc').get({
success:function(res){
console.log(res)
that.setData({
bannerImg1:res.data
})
}
})
},
search: function(){
var that = this;
if(this.data.inputcon==''){
wx.showToast({
title: '请输入搜索内容',
icon:'none'
})
}else{
var key = this.data.inputcon;
db.collection('recommend').where({
title: db.RegExp({
regexp: key,
options: 'i'
})
})
.get({
success: function(res) {
console.log(res.data)
that.setData({
inputcon: ''
})
if(res.data.length==0){
wx.showToast({
title: '搜索内容暂无!',
icon:'none'
})
}else{
var model = JSON.stringify(res.data);
wx.navigateTo({
url: '../more/more?model='+model,
})
}
}
})
}
},
bindchange1(e) {
this.setData({
showindex1: e.detail.current,
})
},
bindchange2(e) {
this.setData({
showindex2: e.detail.current
})
},
gotomore1:function(){
wx.navigateTo({
url: '../more/more?isfirst=true',
})
},
gotomore2:function(){
wx.navigateTo({
url: '../more/more?isfirst=false',
})
},
gotocompete:function(){
},
inputchange:function(e){
this.setData({
inputcon: e.detail.value
})
},
})

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

@ -0,0 +1,95 @@
<!--miniprogram/pages/find/find.wxml-->
<view class="container3">
<view class="container2">
<view class="search">
<view class="search2">
<view class="search-input"><input placeholder="输入关键字搜索" bindinput="inputchange" value="{{inputcon}}"/></view>
<view class="search-submit">
<image src="../../images/ss.png" bindtap="search"></image>
</view>
</view>
</view>
<view class="top">
<swiper indicator-dots="true" interval="5000" autoplay="true" indicator-active-color="white">
<block wx:for="{{swiperImg}}" wx:key="index">
<swiper-item bindtap="sliderto" data-url="{{item.url}}">
<image src="{{item.src}}" />
</swiper-item>
</block>
</swiper>
</view>
<view class="main">
<view class="main-top">
<view class="main-top-left">
<view class="main-top-left-img">
<image src="../../images/ch-med.png"></image>
</view>
<view class="main-top-left-text">中医内容</view>
</view>
<view class="main-top-right">
<view class="main-top-right-text" ><text bindtap="gotomore1">查看更多</text></view>
<view class="main-top-right-img" bindtap="gotomore1">
<image src="../../images/more.png"></image>
</view>
</view>
</view>
<view class="main-center">
<view class='slide'>
<swiper class='picker' circular previous-margin='80rpx' next-margin="80rpx" bindchange="bindchange1"
autoplay='true'>
<swiper-item wx:for="{{bannerImg1}}" wx:key="item.index" wx:if="{{item.isfirst=='true'}}"
bindtap="sliderto"
data-url="{{item.url}}">
<view class='picker-one'>
<image src='{{item.src}}' class='{{showindex1==item.index?"imgs":"imgs1"}}' bindtap="gotocompete"></image>
<view class="picker-two">
<view class="picker-two-title">{{item.title}}</view>
<view class="picker-two-con">
<view class="picker-two-icon"><image src="../../images/note.png"></image></view>
<view class="picker-two-time">{{item.note}}</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
</view>
</view>
<view class="main">
<view class="main-top">
<view class="main-top-left">
<view class="main-top-left-img">
<image src="../../images/school.png"></image>
</view>
<view class="main-top-left-text">校园生活</view>
</view>
<view class="main-top-right">
<view class="main-top-right-text"><text bindtap="gotomore2">查看更多</text></view>
<view class="main-top-right-img" bindtap="gotomore2">
<image src="../../images/more.png"></image>
</view>
</view>
</view>
<view class="main-center">
<view class='slide'>
<swiper class='picker' circular previous-margin='80rpx' next-margin="80rpx" bindchange="bindchange2"
autoplay='true'>
<swiper-item wx:for="{{bannerImg1}}" wx:key="item.index" id="{{item.index}}" wx:if="{{item.isfirst=='false'}}" bindtap="sliderto"
data-url="{{item.url}}">
<view class='picker-one'>
<image src='{{item.src}}' class='{{showindex2==item.index?"imgs":"imgs1"}}'></image>
<view class="picker-two">
<view class="picker-two-title">{{item.title}}</view>
<view class="picker-two-con">
<view class="picker-two-icon"><image src="../../images/note.png"></image></view>
<view class="picker-two-time">{{item.note}}</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
</view>
</view>
</view>
</view>

@ -0,0 +1,208 @@
/* miniprogram/pages/find/find.wxss */
.container2{
width: 670rpx;
/* height: 700px; */
margin: 0 40rpx;
/* background-color: aqua; */
}
.search{
width: 100%;
height: 60rpx;
margin: 30rpx 0;
background-color: #ccc;
border-radius: 25rpx;
}
.search2{
width: 610rpx;
height: 60rpx;
margin: 0 30rpx;
display: flex;
}
.search-input{
width: 500rpx;
height: 60rpx;
}
.search-input input{
width: 100%;
height: 60rpx;
text-align: center;
}
.search-submit{
width: 100rpx;
height: 60rpx;
margin-left: 10rpx;
}
.search-submit image{
width: 50rpx;
height: 50rpx;
margin: 5rpx 25rpx;
}
.top{
width: 100%;
margin: 30rpx 0;
height: 350rpx;
}
.top swiper{
width: 100%;
height: 100%;
border-radius: 25rpx;
overflow: hidden;
}
.top swiper swiper-item{
width: 100%;
height: 100%;
border-radius: 25rpx;
}
.top swiper swiper-item image{
width: 100%;
height: 100%;
border-radius: 25rpx;
}
.main{
width: 100%;
min-height: 400rpx;
overflow: hidden;
}
.main-top{
width: 100%;
height: 60rpx;
display: flex;
margin: 10rpx 0;
}
.main-top-left, .main-top-right{
flex: 1;
height: 60rpx;
}
.main-top-left-img{
float: left;
width: 60rpx;
height: 60rpx;
}
.main-top-left-img image{
width: 100%;
height: 100%;
}
.main-top-left-text{
float: left;
width: 200rpx;
margin-left: 10rpx;
height: 60rpx;
line-height: 60rpx;
font-weight: 700;
}
.main-top-right{
display: flex;
}
.main-top-right-text{
/* float: right; */
width: 270rpx;
text-align: right;
color: gold;
height: 60rpx;
line-height: 60rpx;
}
.main-top-right-img{
/* float: right; */
width: 40rpx;
height: 40rpx;
margin: 10rpx;
}
.main-top-right-img image{
width: 100%;
height: 100%;
}
.main-center{
width: 100%;
}
.slide{
width: 100%;
height: 320rpx;
}
.slide>.picker{
width: 100%;
height: 320rpx;
}
.slide>.picker .picker-one{
width:100%;
height: 320rpx;
position: relative;
}
.slide>.picker .picker-one .imgs{
width: 450rpx;
height: 200rpx;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: 30rpx auto;
border-radius: 20rpx;
transform: scale(1);
animation: change 0.5s linear
}
@keyframes change{
0%{transform: scale(0.8)}
100%{transform: scale(1);}
}
.slide>.picker .picker-one .imgs1{
width: 500rpx;
height: 200rpx;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: 30rpx auto;
border-radius: 20rpx;
transform: scale(0.8);
animation: change1 0.5s linear
}
@keyframes change1{
0%{transform: scale(1)}
100%{transform: scale(0.8);}
}
.picker-two{
text-align: center;
width: 100%;
position: absolute;
bottom: 0;
/* left: 50rpx; */
}
.picker-two-title{
margin: 5rpx 0;
width: 100%;
height: 30rpx;
line-height: 30rpx;
font-size: 25rpx;
font-weight: 700;
}
.picker-two-con{
display: flex;
width: 100%;
height: 30rpx;
margin: 5rpx 0;
line-height: 30rpx;
font-size: 25rpx;
justify-content: center;
}
.picker-two-icon{
width: 25rpx;
height: 25rpx;
margin-right: 8rpx;
}
.picker-two-icon image{
width: 100%;
height: 100%;
}
.picker-two-time{
overflow: hidden;
text-overflow: ellipsis;
max-width: 280rpx;
}

@ -0,0 +1,124 @@
//index.js
const app = getApp()
Page({
data: {
avatarUrl: './user-unlogin.png',
userInfo: {},
hasUserInfo: false,
logged: false,
takeSession: false,
requestResult: '',
canIUseGetUserProfile: false,
canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') // 如需尝试获取用户信息可改为false
},
onLoad: function() {
if (!wx.cloud) {
wx.redirectTo({
url: '../chooseLib/chooseLib',
})
return
}
if (wx.getUserProfile) {
this.setData({
canIUseGetUserProfile: true,
})
}
},
getUserProfile() {
// 推荐使用wx.getUserProfile获取用户信息开发者每次通过该接口获取用户个人信息均需用户确认开发者妥善保管用户快速填写的头像昵称避免重复弹窗
wx.getUserProfile({
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
this.setData({
avatarUrl: res.userInfo.avatarUrl,
userInfo: res.userInfo,
hasUserInfo: true,
})
}
})
},
onGetUserInfo: function(e) {
if (!this.data.logged && e.detail.userInfo) {
this.setData({
logged: true,
avatarUrl: e.detail.userInfo.avatarUrl,
userInfo: e.detail.userInfo,
hasUserInfo: true,
})
}
},
onGetOpenid: function() {
// 调用云函数
wx.cloud.callFunction({
name: 'login',
data: {},
success: res => {
console.log('[云函数] [login] user openid: ', res.result.openid)
app.globalData.openid = res.result.openid
wx.navigateTo({
url: '../userConsole/userConsole',
})
},
fail: err => {
console.error('[云函数] [login] 调用失败', err)
wx.navigateTo({
url: '../deployFunctions/deployFunctions',
})
}
})
},
// 上传图片
doUpload: function () {
// 选择图片
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
wx.showLoading({
title: '上传中',
})
const filePath = res.tempFilePaths[0]
// 上传图片
const cloudPath = `my-image${filePath.match(/\.[^.]+?$/)[0]}`
wx.cloud.uploadFile({
cloudPath,
filePath,
success: res => {
console.log('[上传文件] 成功:', res)
app.globalData.fileID = res.fileID
app.globalData.cloudPath = cloudPath
app.globalData.imagePath = filePath
wx.navigateTo({
url: '../storageConsole/storageConsole'
})
},
fail: e => {
console.error('[上传文件] 失败:', e)
wx.showToast({
icon: 'none',
title: '上传失败',
})
},
complete: () => {
wx.hideLoading()
}
})
},
fail: e => {
console.error(e)
}
})
},
})

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

@ -0,0 +1,6 @@
<!--index.wxml-->
<view class="container">
发现
</view>

@ -0,0 +1,161 @@
/**index.wxss**/
page {
background: #f6f6f6;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.userinfo, .uploader, .tunnel {
margin-top: 40rpx;
height: 140rpx;
width: 100%;
background: #fff;
border: 1px solid rgba(0, 0, 0, 0.1);
border-left: none;
border-right: none;
display: flex;
flex-direction: row;
align-items: center;
transition: all 300ms ease;
}
.userinfo {
padding-left: 120rpx;
}
.userinfo-avatar {
width: 100rpx;
height: 100rpx;
margin: 20rpx;
border-radius: 50%;
background-size: cover;
background-color: white;
}
.userinfo-block-avatar {
width: 100rpx;
height: 100rpx;
margin: 20rpx;
border-radius: 50%;
overflow: hidden;
}
.userinfo-avatar[size] {
width: 100rpx;
}
.userinfo-avatar:after {
border: none;
}
.userinfo-nickname {
font-size: 32rpx;
color: #007aff;
background-color: white;
background-size: cover;
text-align: left;
padding-left: 0;
margin-left: 10px;
}
.userinfo-nickname::after {
border: none;
}
.userinfo-nickname-wrapper {
flex: 1;
}
.uploader, .tunnel {
height: auto;
padding: 0 0 0 40rpx;
flex-direction: column;
align-items: flex-start;
box-sizing: border-box;
}
.uploader-text, .tunnel-text {
width: 100%;
line-height: 52px;
font-size: 34rpx;
color: #007aff;
}
.uploader-container {
width: 100%;
height: 400rpx;
padding: 20rpx 20rpx 20rpx 0;
display: flex;
align-content: center;
justify-content: center;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.uploader-image {
width: 100%;
height: 360rpx;
}
.tunnel {
padding: 0 0 0 40rpx;
}
.tunnel-text {
position: relative;
color: #222;
display: flex;
flex-direction: row;
align-content: center;
justify-content: space-between;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.tunnel-text:first-child {
border-top: none;
}
.tunnel-switch {
position: absolute;
right: 20rpx;
top: -2rpx;
}
.disable {
color: #888;
}
.service {
position: fixed;
right: 40rpx;
bottom: 40rpx;
width: 140rpx;
height: 140rpx;
border-radius: 50%;
background: linear-gradient(#007aff, #0063ce);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
display: flex;
align-content: center;
justify-content: center;
transition: all 300ms ease;
}
.service-button {
position: absolute;
top: 40rpx;
}
.service:active {
box-shadow: none;
}
.request-text {
padding: 20rpx 0;
font-size: 24rpx;
line-height: 36rpx;
word-break: break-all;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

@ -0,0 +1,51 @@
// miniprogram/pages/more/more.js
const db = wx.cloud.database();
Page({
/**
* 页面的初始数据
*/
data: {
list:[]
},
sliderto:function(e){
var url=e.currentTarget.dataset.url
wx.navigateTo({
url: '/pages/webview/webview?url=' + url,
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
const that = this;
wx.showLoading({
title: '加载中',
})
if(options.model){
var list = JSON.parse(options.model)
this.setData({
list: list
})
wx.hideLoading();
return
}
db.collection('recommend').orderBy('index','asc').where({
isfirst:options.isfirst
}).get({
success: function(res) {
// res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条
console.log(res.data)
that.setData({
list: res.data
})
wx.hideLoading();
}
})
},
gotocompete:function(e){
},
})

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

@ -0,0 +1,16 @@
<!--miniprogram/pages/more/more.wxml-->
<view class="container">
<view class="container2">
<view class="list" wx:for="{{list}}" bindtap="gotocompete" wx:key="{{item.index}}" bindtap="sliderto"
data-url="{{item.url}}" >
<view class="list-img"><image src="{{item.src}}"></image></view>
<view class="list-con">
<view class="list-con-title">{{item.title}}</view>
<view class="list-con-time">
<view class="list-con-icon"><image src="../../images/note.png"></image></view>
<view class="list-con-time2">{{item.note}}</view>
</view>
</view>
</view>
</view>
</view>

@ -0,0 +1,60 @@
/* miniprogram/pages/more/more.wxss */
page{
background-color: #ccc;
}
.container2{
width: 670rpx;
/* height: 700px; */
margin: 0 40rpx;
/* background-color: aqua; */
}
.list{
width: 100%;
min-height: 400rpx;
margin-bottom: 30rpx;
background-color: white;
border-radius: 25rpx 25rpx 0 0;
overflow: hidden;
}
.list-img{
width: 100%;
height: 300rpx;
border-radius: 25rpx 25rpx 0 0;
}
.list-img image{
width: 100%;
height: 100%;
border-radius: 25rpx 25rpx 0 0;
}
.list-con-title{
margin: 10rpx;
width: 100%;
height: 40rpx;
line-height: 40rpx;
font-size: 32rpx;
font-weight: 800;
}
.list-con-time{
width: 100%;
max-width: 630rpx;
height: 40rpx;
margin: 10rpx 0;
line-height: 40rpx;
font-size: 28rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.list-con-icon{
width: 30rpx;
height: 30rpx;
margin: 5rpx 10rpx;
display: inline-block;
}
.list-con-time2{
display: inline-block;
}
.list-con-icon image{
width: 100%;
height: 100%;
}

@ -0,0 +1,178 @@
// miniprogram/pages/my/my.js
const app = getApp();
const dd=wx.cloud.database()
const db=wx.cloud.database().collection('user')
const db2=wx.cloud.database().collection('community')
Page({
/**
* 页面的初始数据
*/
data: {
openid: '',
ismyfavor:"active",
isempty:false,
isvideoempty:true,
isother:'',
myfavor:[],
mycollect:[],
mycollect_video:[],
myfavor_video:[]
},
go:function(){
wx.switchTab({
url: '../community/community',
})
},
menu_favor:function(){
const that=this;
that.setData({
ismyfavor:'active',
isother:''
})
console.log(that.data.myfavor)
},
menu_other:function(){
const that=this;
that.setData({
ismyfavor:'',
isother:'active',
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
into:function(e){
const that=this
var index=e.currentTarget.dataset.index
wx.navigateTo({
url: '../detail/detail?content='+JSON.stringify(that.data.mycollect[index]),
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
const that=this
that.setData({
isempty:true,
isvideoempty:true
})
wx.showLoading({
title: '加载中...',
mask:true
})
app.getOpenId.then(res => {
that.setData({
openid:res
})
db.doc(res).get({
success: function(res) {
console.log(res.data)
that.setData({
myfavor:res.data.collect,
myfavor_video:res.data.collect_video
})
console.log(res.data.collect.length)
if(res.data.collect.length!=0){
that.setData({
isempty:false,
})
}
if(res.data.collect_video.length!=0){
that.setData({
isvideoempty:false,
})
}
const _=dd.command
db2.where({
_id: _.in(that.data.myfavor)
}).get({
success: function(res1) {
// res.data 是包含以上定义的两条记录的数组
console.log(res1.data)
that.setData({
mycollect:res1.data,
})
}
})
dd.collection('video').where({
_id: _.in(that.data.myfavor_video)
}).get({
success: function(res1) {
// res.data 是包含以上定义的两条记录的数组
console.log(res1.data)
that.setData({
mycollect_video:res1.data,
})
}
})
},
fail:function(){
that.setData({
isempty:true,
isvideoempty:true
})
}
})
})
wx.hideLoading({
success: (res) => {},
})
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

@ -0,0 +1,63 @@
<!--miniprogram/pages/my/my.wxml-->
<view class="container">
<view class="top">
<view class="h-cut">
<open-data type="userAvatarUrl"></open-data>
</view>
<view class="t_content">
<open-data type="userNickName"></open-data>
<view class="profile">
<open-data type="userCity" lang="zh_CN"></open-data>
<text decode="emsp">&emsp;</text>
<open-data type="userGender" lang="zh_CN"></open-data>
</view>
</view>
</view>
<view class="main">
<view class="m-menu">
<view class="{{ismyfavor}} myfavor" bindtap="menu_favor">帖子收藏</view>
<view class=" {{isother}} other" bindtap="menu_other">视频收藏</view>
</view>
<view class="empty" wx:if="{{(ismyfavor&&isempty)||(isother&&isvideoempty)}}">
<view class="e-icon">
<image src="../../images/no.png"></image>
</view>
<view class='e-title'>
您还没有任何收藏~
</view>
<view class="btn-go" bindtap="go">去逛逛</view>
</view>
<view class="full" wx:if="{{ismyfavor&&!isempty}}">
<view class="f-container" wx:for="{{mycollect}}" wx:key="index" bindtap="into" data-index="{{index}}">
<view class="f-img">
<image mode="widthFix" src="{{item.img==''?'../../images/default.png':item.img}}" alt="" />
</view>
<view class="f-content">
<text class="message" wx:if="{{item.type=='二手闲置'}}">
{{'#'+item.type+'-'+item.recycle.obj_name+'*'+item.recycle.obj_num+':'+item.recycle.obj_price}}\n
</text>
<text class="message" wx:if="{{item.type=='兼职实习'}}">
{{'#'+item.type+'-'+item.partjob.unit+'-'+item.partjob.name}}\n
</text>
<text class="message" wx:if="{{item.type=='校园资讯'}}">{{'#'+item.type+'-'+item.college}}\n</text>
</view>
</view>
</view>
<view class="video" wx:if="{{isother}}">
<view wx:for="{{mycollect_video}}">
<view class="title">{{'#'+item.type}}</view>
<video
src="{{item.src}}"
binderror="videoErrorCallback"
show-center-play-btn='{{false}}'
show-play-btn="{{true}}"
controls
picture-in-picture-mode="{{['push', 'pop']}}"
bindenterpictureinpicture='bindVideoEnterPictureInPicture'
bindleavepictureinpicture='bindVideoLeavePictureInPicture'
></video>
</view>
</view>
</view>
</view>

@ -0,0 +1,140 @@
/* miniprogram/pages/my/my.wxss */
page{
background-color: #fff;
}
.container{
position: absolute;
width: 100%;
height: 100%;
background-color: #FBF8F3;
}
.top{
position: relative;
margin-top: 50rpx;
}
.top>view{
display: inline-block;
}
.t_content{
margin-top: 20rpx;
margin-left: 200rpx;
max-width: 60%;
max-height: 200rpx;
overflow: hidden;
}
.name{
font-weight: 700;
}
.profile{
margin-top: 10rpx;
font-size: 20rpx;
}
.h-cut{
position: absolute;
margin-left: 50rpx;
border-radius: 50%;
width: 100rpx;
height: 100rpx;
overflow: hidden;
}
.h-cut image{
width: 100%;
height: 100%;
}
.main{
position: absolute;
padding: 20rpx;
bottom: 0;
left: 0;
right: 0;
height: 75%;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
background-color: #fff;
}
.m-menu{
border-radius: 20rpx;
width: fit-content;
overflow: hidden;
}
.active{
background-color: #F4CA2B!important;
color:#FFF
}
.m-menu>view{
display: inline-block;
text-align: center;
width: 150rpx;
height: 70rpx;
line-height: 70rpx;
background-color: #ddd;
font-size: 25rpx;
}
.empty{
margin-top: 200rpx;
}
.empty >view{
text-align: center;
margin: 30rpx auto;
}
.e-icon{
width: 150rpx;
height: 150rpx;
}
.e-icon image{
width: 100%;
height: 100%;
}
.e-title{
font-size: 25rpx;
}
.btn-go{
border-radius: 20rpx;
width: 150rpx;
height: 60rpx;
line-height: 60rpx;
background-color: #F4CA2B;
color: #FFF;
}
.full{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.f-container{
display: inline-block;
margin: 30rpx;
width: 250rpx;
height: 250rpx;
}
.f-img{
border-radius: 20rpx;
overflow: hidden;
width: 250rpx;
height: 200rpx;
}
.f-img image{
width: 100%;
height: 100%;
}
.f-content{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
font-size: 25rpx;
height: 70rpx;
}
.video{
margin-top: 20rpx;
}
.title{
font-weight: 700;
color: rgb(49, 163, 230);
}
.video video{
margin: 20rpx 0;
}
.video video{
width: 100%;
}

@ -0,0 +1,308 @@
// miniprogram/pages/publish/publish.js
const app = getApp();
var util = require('../../utils/util.js')
const db = wx.cloud.database().collection('community')
Page({
data: {
openid:'',
array: [],
photo_src:'',
fileID:'',
userInfo: {},
hasUserInfo: false,
canIUseGetUserProfile:false,
type:"",
recycle:{
obj_name:'',
obj_num:'',
obj_price:'',
obj_address:'',
obj_contact:'',
obj_note:''
},
partjob:{
unit:"",
name:'',
time:'',
address:'',
content:"",
require:'',
salary:'',
sign_way:'',
note:''
},
college:'',
},
bindPickerChange: function(e) {
this.setData({
index: e.detail.value
})
},
upload:function(e){
const that=this;
wx.chooseImage({
count: 1,
success(res){
console.log(res.tempFilePaths[0])
that.setData({
photo_src:res.tempFilePaths[0]
})
wx.showLoading({
title: '上传中...',
})
var _time = util.formatTime(new Date())
wx.cloud.uploadFile({
cloudPath:'gzy/'+_time+that.data.openid,
filePath:res.tempFilePaths[0],
success(res){
console.log(res)
that.setData({
fileID:res.fileID
})
wx.hideLoading()
wx.showToast({
title: '上传成功!',
})
}
})
}
})
},
formSubmit(e){
const that=this
if(!e.detail.value.type){
wx.showToast({
title: '请选择标题',
icon: 'none',
})
return
}
//判断类型
if(that.data.type=='recycle'){
if(!e.detail.value.obj_name||!e.detail.value.obj_num||!e.detail.value.obj_price
||!e.detail.value.obj_address||!e.detail.value.obj_contact){
wx.showToast({
title: '请填写完整信息!',
icon: 'none',
})
return
}else{
wx.showModal({
title: '提示',
content: '确认发布吗?',
success (res) {
if (res.confirm) {
console.log('用户点击确定')
console.log(that.data.userInfo)
var _time = util.formatTime(new Date())
db.add({
data:{
username:that.data.userInfo.nickName,
headcut:that.data.userInfo.avatarUrl,
type:'二手闲置',
z_type:that.data.array[e.detail.value.type],
img:that.data.fileID,
recycle:{
obj_name:e.detail.value.obj_name,
obj_num:e.detail.value.obj_num,
obj_price:e.detail.value.obj_price,
obj_address:e.detail.value.obj_address,
obj_contact:e.detail.value.obj_contact,
obj_note:e.detail.value.obj_note
},
date:_time,
comment:0,
like:0,
collect_num:0
}
}).then(res => {
wx.showToast({
title: '发布成功',
})
that.setData({
recycle:{
obj_name:'',
obj_num:'',
obj_price:'',
obj_address:'',
obj_contact:'',
obj_note:''
},
})
setTimeout(function () {
wx.navigateBack({
delta: 1,
})
}, 1000)
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
}else if(that.data.type=='partjob'){
if(!e.detail.value.unit||!e.detail.value.name||!e.detail.value.time||!e.detail.value.address
||!e.detail.value.content||!e.detail.value.require||!e.detail.value.salary||!e.detail.value.sign_way){
wx.showToast({
title: '请填写完整信息!',
icon: 'none',
})
return
}else{
wx.showModal({
title: '提示',
content: '确认发布吗?',
success (res) {
if (res.confirm) {
console.log('用户点击确定')
console.log(that.data.userInfo)
var _time = util.formatTime(new Date())
db.add({
data:{
username:that.data.userInfo.nickName,
headcut:that.data.userInfo.avatarUrl,
type:'兼职实习',
z_type:that.data.array[e.detail.value.type],
img:that.data.fileID,
partjob:{
unit:e.detail.value.unit,
name:e.detail.value.name,
time:e.detail.value.time,
address:e.detail.value.address,
content:e.detail.value.content,
require:e.detail.value.require,
salary:e.detail.value.salary,
sign_way:e.detail.value.sign_way,
note:e.detail.value.note
},
date:_time,
comment:0,
like:0,
collect_num:0
}
}).then(res => {
wx.showToast({
title: '发布成功',
})
that.setData({
partjob:{
unit:"",
name:'',
time:'',
address:'',
content:"",
require:'',
salary:'',
sign_way:'',
note:''
},
})
setTimeout(function () {
wx.navigateBack({
delta: 1,
})
}, 1000)
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
}else if(that.data.type=='college'){
if(!e.detail.value.college){
wx.showToast({
title: '请填写完整信息!',
icon: 'none',
})
return
}else{
console.log(e)
wx.showModal({
title: '提示',
content: '确认发布吗?',
success (res) {
if (res.confirm) {
console.log('用户点击确定')
console.log(that.data.userInfo)
var _time = util.formatTime(new Date())
db.add({
data:{
username:that.data.userInfo.nickName,
headcut:that.data.userInfo.avatarUrl,
type:'校园资讯',
z_type:that.data.array[e.detail.value.type],
img:that.data.fileID,
college:e.detail.value.college,
date:_time,
comment:0,
like:0,
collect_num:0
}
}).then(res => {
wx.showToast({
title: '发布成功',
})
that.setData({
college:''
})
setTimeout(function () {
wx.navigateBack({
delta: 1,
})
}, 1000)
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
const that=this
that.setData({
type:options.mode
})
app.getOpenId.then(res => {
that.setData({
openid:res
})
})
if (wx.getUserProfile) {
this.setData({
canIUseGetUserProfile: true
})
}
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
const that=this
if(that.data.type=="recycle"){
that.setData({
array:['出闲置','收闲置']
})
}else if(that.data.type=="partjob"){
that.setData({
array:['兼职招人','实习招人']
})
}else if(that.data.type=="college"){
that.setData({
array:['校园活动','校园产品','校园生活']
})
}
},
})

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

@ -0,0 +1,53 @@
<!--miniprogram/pages/publish/publish.wxml-->
<view class="container2">
<form catchsubmit="formSubmit">
<picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}" name="type">
<view class="picker" >
标题:<text>{{array[index]}}</text>
</view>
</picker>
<view wx:if="{{type=='recycle'}}">
<view class="input1">物品名称:<input name="obj_name" value="{{recycle.obj_name}}" /></view>
<view class="input1">数量(个):<input type="number" name="obj_num" value="{{recycle.obj_num}}"/></view>
<view class="input1">价格(¥):<input type="number" name="obj_price" value="{{recycle.obj_price}}"/></view>
<view class="input1">交易地点:<input name="obj_address" value="{{recycle.obj_address}}"/></view>
<view class="input1">联系方式:<input name="obj_contact" value="{{recycle.obj_contact}}"/></view>
<view class="input2">
<textarea name="note" cols="30" rows="10" placeholder="若有备注信息,请在此输入.." placeholder-style="color:#ddd" maxlength="500" value="{{recycle.obj_note}}" style="margin:0" ></textarea>
</view>
</view>
<view wx:if="{{type=='partjob'}}">
<view class="input1">工作单位:<input name="unit" value="{{partjob.unit}}"/></view>
<view class="input1">岗位名称:<input name="name" value="{{partjob.name}}"/></view>
<view class="input1">工作时间:<input name="time" value="{{partjob.time}}"/></view>
<view class="input1">工作地点:<input name="address" value="{{partjob.address}}"/></view>
<view class="input2">工作内容:
<textarea name="content" cols="30" rows="10" maxlength="500" value="{{partjob.content}}" ></textarea>
</view>
<view class="input2">工作要求:
<textarea name="require" cols="30" rows="10" maxlength="500" value="{{partjob.require}}" ></textarea>
</view>
<view class="input1">薪资及发放方式:<input name="salary" value="{{partjob.salary}}"/></view>
<view class="input1">报名方式:<input name="sign_way" value="{{partjob.sign_way}}"/></view>
<view class="input2">
<textarea name="note" cols="30" rows="10" placeholder="若有备注信息,请在此输入.." placeholder-style="color:#ddd" maxlength="500" value="{{partjob.note}}" style="margin:0" ></textarea>
</view>
</view>
<view wx:if="{{type=='college'}}">
<view class="input2">
<textarea name="college" cols="30" rows="10" placeholder="请在此输入信息..." placeholder-style="color:#ddd" maxlength="500" value="{{college}}" style="margin:0" ></textarea>
</view>
</view>
<view class="photo" wx:if="{{photo_src}}">
<image src="{{photo_src}}" mode="widthFix"></image>
</view>
<view class="upload">
<image src="../../images/upload.png" alt="" bindtap="upload"></image>
<text>上传图片</text>
</view>
<button class="submit" formType="submit" wx:if="{{canIUseGetUserProfile}}">发布</button>
</form>
</view>

@ -0,0 +1,84 @@
/* miniprogram/pages/publish/publish.wxss */
.container2{
padding: 30rpx 0;
font-weight: 600;
}
.input1{
display: flex;
margin-bottom: 30rpx;
height: 90rpx;
padding: 13px;
background-color: #FFFFFF;
border-radius: 20rpx;
border: 1px solid #ddd;
box-sizing: border-box;
font-size: 30rpx;
}
.input1 input{
flex:1
}
.input2{
margin-bottom: 30rpx;
padding: 13px;
background-color: #FFFFFF;
border-radius: 20rpx;
border: 1px solid #ddd;
box-sizing: border-box;
font-size: 30rpx;
}
.input2 textarea{
margin-top: 20rpx;
}
.message{
margin-bottom: 30rpx;
width: 100%;
height: 500rpx;
border: 1px solid #ddd;
border-radius: 20rpx;
background-color: #FFFFFF;
}
.picker{
margin-bottom: 30rpx;
position: relative;
padding: 13px;
background-color: #FFFFFF;
border-radius: 20rpx;
border: 1px solid #ddd;
box-sizing: border-box;
font-size: 30rpx;
}
.picker::after{
position: absolute;
right: 20rpx;
top: 35rpx;
border: 15rpx solid transparent;
border-top: 20rpx solid #000;
content: "";
}
.upload{
margin: 0 auto;
width: 200rpx;
height: 100rpx;
line-height: 100rpx;
font-size: 30rpx;
color: #8c8c8c;
}
.upload image{
width: 40%;
height: 50%;
}
.photo{
width: 100%;
}
.submit{
padding: 0!important;
margin: 50rpx auto;
width: 200rpx;
height: 80rpx;
line-height: 80rpx!important;
border-radius: 20rpx;
color: #fff;
background-color: #169BD5;
text-align: center;
}

@ -0,0 +1,68 @@
// miniprogram/pages/webview/webview.js
Page({
/**
* 页面的初始数据
*/
data: {
url:''
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.setData({
url:options.url // 通过传参实现跳转公众号推文
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save