python学习

This commit is contained in:
2020-11-17 18:52:15 +08:00
parent 780443e7d1
commit 51fd976127
329 changed files with 14341 additions and 358 deletions

226
native/pages/card/main.js Normal file
View File

@@ -0,0 +1,226 @@
const WXAPI = require('apifm-wxapi')
const AUTH = require('../../utils/auth')
const APP = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
wxlogin: true,
showMpjbutton: false,
openShare: false,
cardUserInfo: undefined,
kActionType: {},
content: '...',
qrcode: undefined
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (e) {
if (e.scene) { // 扫码
const scene = decodeURIComponent(e.scene)
wx.setStorageSync('referrer', scene)
wx.setStorageSync('cardUid', scene)
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
async onShow () {
AUTH.checkHasLogined().then(isLogined => {
this.setData({
wxlogin: isLogined
})
})
await WXAPI.queryConfigBatch('mallName,DEFAULT_FRIEND_UID').then(function (res) {
if (res.code == 0) {
res.data.forEach(config => {
wx.setStorageSync(config.key, config.value);
})
}
})
const cardUid = await this.getCardUid()
this.getCardInfo(cardUid)
const qrcode = APP.globalData._haibaoimg_qrcode
if (!qrcode) {
// 获取二维码
WXAPI.wxaQrcode({
scene: cardUid,
page: 'pages/card/main',
is_hyaline: false,
expireHours: 1
}).then(res => {
if(res.code == 0){
APP.globalData._haibaoimg_qrcode = res.data
this.setData({
qrcode: res.data
})
}
})
} else {
this.setData({
qrcode
})
}
},
async getCardUid(){
let cardUid = wx.getStorageSync('cardUid')
const uid = wx.getStorageSync('uid')
if (!cardUid) {
// 没有通过链接或者扫码进来
if (uid) {
// 当前用户已登录
const res = await WXAPI.userDetail(wx.getStorageSync('token'))
if (res.code == 0 && res.data.userLevel && res.data.userLevel.name === 'aicard') {
return uid
}
}
// 读取默认设置
cardUid = wx.getStorageSync('DEFAULT_FRIEND_UID')
}
return cardUid
},
async getCardInfo(cardUid){
const uid = wx.getStorageSync('uid')
const token = wx.getStorageSync('token')
if (uid) {
// 添加到我的名片夹
WXAPI.addFriend(token, cardUid)
}
// 读取名片详情信息
const res = await WXAPI.friendUserDetail(token, cardUid)
if (res.code == 0) {
const _data = {
kActionType: {}
}
if (res.data.userLevel && res.data.userLevel.maxUser && res.data.userLevel.maxUser > 1) {
_data.showMpjbutton = true
}
_data.cardUserInfo = res.data
if (_data.cardUserInfo.ext) {
Object.keys(_data.cardUserInfo.ext).forEach(k => {
// kActionType
const v = _data.cardUserInfo.ext[k]
_data.kActionType[k] = v
})
}
wx.setNavigationBarTitle({
title: _data.cardUserInfo.base.nick + ' - ' + wx.getStorageSync('mallName')
})
this.setData(_data)
}
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
return {
title: '您好,我是 ' + wx.getStorageSync('mallName') + ' 的' + this.data.cardUserInfo.base.nick + ',请惠存我的名片。',
path: '/pages/card/main?cardUid=' + this.data.cardUserInfo.base.id,
imageUrl: this.data.cardUserInfo.base.avatarUrl
}
},
callPhone(){
wx.makePhoneCall({
phoneNumber: this.data.cardUserInfo.base.mobile
})
},
copyData(e){
const v = e.currentTarget.dataset.v
wx.setClipboardData({
data: v,
success: (res) => {
wx.showToast({
title: '复制成功',
icon: 'success'
})
}
})
},
goIndex(){
wx.navigateTo({
url: '/pages/index/main'
})
},
createHaibao() { // 生成海报
wx.chooseImage({
count: 1,
success: (res) => {
console.log(res)
wx.setStorageSync('_haibaoimg', res.tempFilePaths[0])
this.cardposter()
}
})
},
cardposter() {
wx.navigateTo({
url: '/pages/cardposter/main?cardUid=' + this.data.cardUserInfo.base.id
})
},
addPhoneContact() {
// 调用登录接口
wx.addPhoneContact({
photoFilePath: this.data.cardUserInfo.base.avatarUrl,
organization: wx.getStorageSync('mallName'),
title: this.data.cardUserInfo.ext['职位'],
firstName: this.data.cardUserInfo.base.nick,
mobilePhoneNumber: this.data.cardUserInfo.base.mobile
})
},
cancelLogin() {
this.setData({
wxlogin: true
})
},
processLogin(e) {
if (!e.detail.userInfo) {
wx.showToast({
title: '已取消',
icon: 'none',
})
return;
}
AUTH.register(this);
},
})

View File

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

View File

@@ -0,0 +1,51 @@
<view class="container">
<view class="max-width">
<image class="userinfo-avatar" src="{{cardUserInfo.base.avatarUrl}}" mode="widthFix" />
</view>
<view class="profile-box">
<view class="profile">
<view class="name">{{ cardUserInfo.base.nick }}</view>
<view class="position">{{ cardUserInfo.ext ? cardUserInfo.ext['职位'] : '-' }}</view>
</view>
<view class="profile2">
<view class="name">手机</view>
<view class="position">{{cardUserInfo.base.mobile}}</view>
<view class="action">
<button class="action" bindtap="callPhone">拨打</button>
</view>
</view>
<view wx:for="{{cardUserInfo.ext}}" wx:for-index='k' wx:key="index" class="profile2">
<view class="name">{{k}}</view>
<view class="position">{{item}}</view>
<view class="action">
<button class="action" data-v="{{item}}" bindtap="copyData">复制</button>
</view>
</view>
</view>
<view class="action-buttons">
<view class="button" bindtap="createHaibao">
<image class="img" src="/images/mp/posters.png" />
<view class="txt">生成海报</view>
</view>
<view class="button" bindtap="addPhoneContact">
<image class="img" src="/images/mp/txl.png" />
<view class="txt">存入通讯录</view>
</view>
<view class="button">
<button open-type="share" plain="true" style="border:none;">
<image class="img" style="margin-left:0;" src="/images/mp/share.png" />
</button>
<view class="txt">分享好友</view>
</view>
</view>
<view>
<image wx:if="{{ qrcode }}" class="qrcode" src="{{qrcode}}" />
</view>
<view wx:if="{{showMpjbutton}}" class="sharempj" bindtap="goIndex">
<image class="shareimg" src="/images/mp/mpj.png" />
</view>
</view>
<import src="/template/login/index.wxml" />
<template is="apifmLogin" data="{{wxlogin: wxlogin}}" />

140
native/pages/card/main.wxss Normal file
View File

@@ -0,0 +1,140 @@
@import "/template/login/index.wxss";
.container {
width: 750rpx;
background-color: #faf9f9;
}
.max-width {
width: 750rpx;
background-color: #ffffff;
}
.userinfo-avatar {
width: 750rpx;
}
.profile-box {
position: relative;
width:650rpx;
background-color: #ffffff;
bottom:100rpx;
}
.action-buttons {
width: 750rpx;
display: flex;
text-align: center;
}
.action-buttons .button {
width: 250rpx;
text-align: center;
}
.action-buttons .button .img {
width: 180rpx;
height: 180rpx;
margin-left: 35rpx;
display: block;
}
.action-buttons .button .txt {
font-size: 12px;
display: block;
}
.profile {
text-align: left;
padding: 20rpx;
color:#555555;
display: flex;
flex-direction: row;
align-items:flex-end;
}
.profile .name {
font-size: 20px;
}
.profile .position {
font-size: 12px;
margin-left: 30rpx;
}
.phone {
text-align: left;
padding: 20rpx;
font-size: 14px;
}
.profile2 {
text-align: left;
padding: 20rpx;
color:#555555;
display: flex;
flex-direction: row;
justify-content:space-between;
align-items:flex-end;
}
.profile2 .name {
font-size: 16px;
width:120rpx;
}
.profile2 .position {
font-size: 14px;
width:400rpx;
}
.profile2 .action {
font-size: 12px;
width:120rpx;
}
.share {
position:fixed;
right:0rpx;
top: 600rpx;
}
.sharempj {
position:fixed;
left:0rpx;
top: 60rpx;
}
.share .shareimg {
width:110rpx;
height:110rpx;
}
.sharempj .shareimg {
width:90rpx;
height:60rpx;
}
.shareFloatDiv1 {
position:fixed;
width:100%;
height:100%;
background-color:#555;filter:Alpha(Opacity=60);opacity:0.6;
}
.shareFloatDiv2 {
position:fixed;
width:100%;
height:400rpx;
background-color: #ffffff;
bottom: 0rpx;
}
.shareFloatDiv2 .p1 {
height:260rpx;
display: flex;
flex-direction: row;
}
.shareFloatDiv2 .p1 .wx {
font-size: 14px;
width:375rpx;
text-align: center;
padding-top: 50rpx;
}
.shareFloatDiv2 .p1 .wx .shareimg {
width:150rpx;
height:150rpx;
}
.shareFloatDiv2 .p2 {
height:20rpx;
background-color: #EEEEEE;
}
.shareFloatDiv2 .p3 {
height:100rpx;
line-height: 100rpx;
text-align: center;
color:#555555;
font-size: 14px;
}
.qrcode {
width:300rpx;
height:300rpx;
margin-top: 50rpx;
}

View File

@@ -0,0 +1,133 @@
const WXAPI = require('apifm-wxapi')
const APP = getApp()
import imageUtil from '../../utils/image.js'
let ctx
Page({
/**
* 页面的初始数据
*/
data: {
canvasstyle: '',
cardUid: undefined,
cardUserInfo: undefined
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (e) {
if (e && e.cardUid) {
this.setData({
cardUid: e.cardUid
})
}
wx.showLoading({
title: ''
})
this.downLoadTouxiang()
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
downLoadTouxiang() {
let _this = this
wx.getImageInfo({
src: wx.getStorageSync('_haibaoimg'),
success: (res) => {
const imageSize = imageUtil(res.width, res.height)
const additionHeight = 50
const qrcodeWidth = imageSize.windowWidth / 3
_this.setData({
canvasstyle: 'height:' + (imageSize.imageHeight + additionHeight + qrcodeWidth) + 'px'
})
ctx = wx.createCanvasContext('firstCanvas')
ctx.setFillStyle('#fff')
ctx.fillRect(0, 0, imageSize.windowWidth, imageSize.imageHeight + additionHeight + qrcodeWidth)
ctx.drawImage(res.path, imageSize.x, imageSize.y, imageSize.imageWidth, imageSize.imageHeight)
// 画二维码
const left = (imageSize.imageWidth - qrcodeWidth) / 2
const top = imageSize.imageHeight + additionHeight / 2
wx.getImageInfo({
src: APP.globalData._haibaoimg_qrcode,
success: (res) => {
ctx.drawImage(res.path, left, top, qrcodeWidth, qrcodeWidth)
setTimeout(function () {
wx.hideLoading()
ctx.draw()
}, 1000)
}
})
}
})
},
saveToMobile() {
wx.canvasToTempFilePath({
canvasId: 'firstCanvas',
success: function (res) {
let tempFilePath = res.tempFilePath
wx.saveImageToPhotosAlbum({
filePath: tempFilePath,
success: (res) => {
wx.showModal({
content: '名片海报已保存到手机相册',
showCancel: false,
confirmText: '知道了',
confirmColor: '#333'
})
},
fail: (res) => {
wx.showToast({
title: res.errMsg,
icon: 'none',
duration: 2000
})
}
})
}
})
},
})

View File

@@ -0,0 +1,3 @@
{
"navigationBarTitleText": "生成海报"
}

View File

@@ -0,0 +1,4 @@
<view class="container">
<canvas class="canvas" style="{{canvasstyle}}" canvas-id="firstCanvas"></canvas>
<button class="button" type="primary" bindtap="saveToMobile">保存到手机相册</button>
</view>

View File

@@ -0,0 +1,8 @@
.canvas {
width:750rpx;
}
.button {
width: 700rpx;
margin-top: 30rpx;
margin-bottom: 30rpx;
}

118
native/pages/index/main.js Normal file
View File

@@ -0,0 +1,118 @@
const AUTH = require('../../utils/auth')
const WXAPI = require('apifm-wxapi')
Page({
/**
* 页面的初始数据
*/
data: {
wxlogin: true,
cardList: [],
cardUid: undefined
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.setNavigationBarTitle({
title: '名片夹 - ' + wx.getStorageSync('mallName')
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
AUTH.checkHasLogined().then(isLogined => {
this.setData({
wxlogin: isLogined
})
if (isLogined) {
this.fetchFriends();
}
})
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
goCard(e) {
const uid = e.currentTarget.dataset.id
wx.setStorageSync('cardUid', uid)
wx.switchTab({
url: '/pages/card/main'
})
},
async fetchFriends() {
// 判断自己是不是名片
const token = wx.getStorageSync('token')
const cardList = []
let res = await WXAPI.userDetail(token)
if (res.code == 0 && res.data.userLevel && res.data.userLevel.name === 'aicard') {
cardList.push(res.data)
}
res = await WXAPI.friendList({
token: token
})
if (res.code == 0) {
for (let i = 0; i < res.data.result.length; i++){
const element = res.data.result[i]
const _res = await WXAPI.friendUserDetail(token, element.uids)
if (_res.code === 0) {
cardList.push(_res.data)
}
}
}
this.setData({
cardList
})
},
cancelLogin() {
wx.switchTab({
url: '/pages/card/main'
})
},
processLogin(e) {
if (!e.detail.userInfo) {
wx.showToast({
title: '已取消',
icon: 'none',
})
return;
}
AUTH.register(this);
},
})

View File

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

View File

@@ -0,0 +1,17 @@
<import src="/template/login/index.wxml" />
<view class="container">
<view wx:if="{{item.ext}}" wx:for="{{cardList}}" wx:key="id" class="card" data-id="{{item.base.id}}" bindtap="goCard">
<view class="profile">
<view class="name">{{ item.base.nick }}</view>
<view class="position">{{ item.ext['职位'] }}</view>
<view class="phone">{{ item.base.mobile }}</view>
<view class="mail">{{ item.ext['邮箱'] }}</view>
</view>
<view class="photo">
<image class="userinfo-avatar" src="{{item.base.avatarUrl}}" mode="widthFix" />
</view>
</view>
</view>
<template is="apifmLogin" data="{{wxlogin: wxlogin}}" />

View File

@@ -0,0 +1,38 @@
@import "/template/login/index.wxss";
.card {
display: flex;
flex-direction: row;
width: 680rpx;
height: 300rpx;
background-color: #ffffff;
border-radius:10px;
margin-top: 30rpx;
}
.card .profile {
width: 400rpx;
color:#555555;
padding-left: 20rpx;
}
.card .profile .name {
font-size: 30px;
}
.card .profile .position {
font-size: 20px;
}
.card .profile .phone {
margin-top: 60rpx;
font-size: 15px;
}
.card .profile .mail {
font-size: 15px;
}
.card .photo {
width: 280rpx;
height: 300rpx;
overflow: hidden;
}
.card .photo .userinfo-avatar {
width: 280rpx;
border-radius: 10px;
}

View File

@@ -0,0 +1,81 @@
const WxParse = require('../../wxParse/wxParse.js');
const WXAPI = require('apifm-wxapi')
Page({
/**
* 页面的初始数据
*/
data: {
newsId: undefined,
newsObject: {
title: undefined,
content: undefined
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (e) {
this.setData({
newsId: e.newsId
})
this.fetchNewsContent()
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
fetchNewsContent() {
WXAPI.cmsArticleDetail(this.data.newsId).then(res => {
if (res.code === 0) {
this.setData({
newsObject: res.data
})
wx.setNavigationBarTitle({
title: res.data.title + ' - ' + wx.getStorageSync('mallName')
})
WxParse.wxParse('article', 'html', res.data.content, this, 5);
}
})
}
})

View File

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

View File

@@ -0,0 +1,9 @@
<import src="../../wxParse/wxParse.wxml" />
<div class="container" style="background-color: #fff">
<div class="title">{{newsObject.title}}</div>
<div class="datetime">{{newsObject.dateAdd}}</div>
<div class="wxparse-content">
<template is="wxParse" data="{{wxParseData:article.nodes}}"/>
</div>
</div>

View File

@@ -0,0 +1,17 @@
@import "/wxParse/wxParse.wxss";
.title {
text-align: left;
width:700rpx;
}
.datetime {
width:700rpx;
font-size: 12px;
margin-top: 10px;
color:#aaa;
}
.wxparse-content {
width: 700rpx;
text-align: left;
font-size: 14px;
}

82
native/pages/news/main.js Normal file
View File

@@ -0,0 +1,82 @@
const WXAPI = require('apifm-wxapi')
Page({
/**
* 页面的初始数据
*/
data: {
newsList: undefined,
content: '...'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.setNavigationBarTitle({
title: wx.getStorageSync('mallName')
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
this.fetchNews()
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
fetchNews() {
WXAPI.cmsArticles({
categoryId: wx.getStorageSync('news_category_dt').id
}).then(res => {
if (res.code === 0) {
this.setData({
newsList: res.data
})
} else {
this.setData({
newsList: []
})
}
})
},
goDetail(e) {
wx.navigateTo({
url: '/pages/news-detail/main?newsId=' + e.currentTarget.dataset.id
})
}
})

View File

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

View File

@@ -0,0 +1,18 @@
<div class="container" style="background-color: #fff;">
<div wx:if="{{!newsList}}" class="noData">
<image class="logo" src="/images/mp/nodata-message.png" mode="widthFix" />
<div>暂无数据 ~ </div>
</div>
<div wx:for="{{newsList}}" wx:for-index='id' class="newsList" bindtap="goDetail" data-id="{{item.id}}">
<div class="title">{{item.title}}</div>
<div class="descriptDiv">
<div class="word" :style="item.pic ? 'width: 75%;' : ''">
<div class="descript">{{item.descript}}</div>
<div style="clear:both;" />
</div>
<div wx:if="{{item.pic}}" class="cover">
<image class="cover-img" src="{{item.pic}}" mode="widthFix" />
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,43 @@
.noData {
text-align: center;
font-size: 12px;
color:#666;
width: 750rpx;
height:200rpx;
padding-top: 100rpx;
}
.noData .logo {
width:300rpx;
margin-top:180rpx;
}
.newsList {
width: 720rpx;
padding-top:30rpx;
padding-bottom:30rpx;
border-bottom: 1px solid #f0f0f0;
display: flex;
flex-direction: column;
}
.title {
width: 100%;
}
.descriptDiv {
margin-top:10rpx;
display: flex;
flex-direction: row;
}
.descript {
font-size: 13px;
color:#666;
}
.word {
line-height: 25px;
}
.cover {
width: 25%;
}
.cover-img {
width: 100%;
border-radius: 10px;
}

View File

@@ -0,0 +1,82 @@
const WXAPI = require('apifm-wxapi')
Page({
/**
* 页面的初始数据
*/
data: {
newsList: undefined,
content: '...'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.setNavigationBarTitle({
title: wx.getStorageSync('mallName')
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
this.fetchNews()
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
fetchNews() {
WXAPI.cmsArticles({
categoryId: wx.getStorageSync('news_category_zs').id
}).then(res => {
if (res.code === 0) {
this.setData({
newsList: res.data
})
} else {
this.setData({
newsList: []
})
}
})
},
goDetail(e) {
wx.navigateTo({
url: '/pages/news-detail/main?newsId=' + e.currentTarget.dataset.id
})
}
})

View File

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

View File

@@ -0,0 +1,13 @@
<div class="container" style="background-color: #fff;">
<div wx:if="{{!newsList}}" class="noData">
<image class="logo" src="/static/images/nodata-message.png" mode="widthFix" />
<div>暂无数据 ~ </div>
</div>
<div wx:for="{{newsList}}" wx:for-index='id' class="newsList" bindtap="goDetail" data-id="{{item.id}}">
<div wx:if="{{item.pic}}" class="cover">
<image class="cover-img" src="{{item.pic}}" mode="widthFix" />
</div>
<div class="title">{{item.title}}</div>
<div class="descript">{{item.descript}}</div>
</div>
</div>

View File

@@ -0,0 +1,36 @@
.noData {
text-align: center;
font-size: 12px;
color:#666;
width: 750rpx;
height:200rpx;
padding-top: 100rpx;
}
.noData .logo {
width:300rpx;
margin-top:180rpx;
}
.newsList {
width: 720rpx;
padding-top:30rpx;
padding-bottom:30rpx;
border-bottom: 1px solid #f0f0f0;
display: flex;
flex-direction: column;
}
.cover {
width: 100%;
}
.cover-img {
width: 100%;
border-radius: 10px;
}
.title {
margin-top: 10px;
}
.descript {
margin-top: 10px;
line-height: 25px;
font-size: 13px;
color:#666;
}