乡村相册迁移位置

This commit is contained in:
aixianling
2022-08-08 10:33:18 +08:00
parent e912b6d00c
commit 91abd76323
109 changed files with 5 additions and 5 deletions

View File

@@ -0,0 +1,600 @@
<template>
<div class="album-home" ref="home">
<div class="userinfo">
<image :src="$cdn + 'avatar.png'" />
<div class="right">
<h2><AiOpenData v-if="user.wxOpenUserId" type="userName" :openid="user.wxOpenUserId"></AiOpenData></h2>
<p>欢迎使用工作相册</p>
</div>
</div>
<div class="album-total">
<div class="album-total__item">
<span>今日拍照人数</span>
<i>{{ countPhotographer || 0 }}</i>
</div>
<div class="album-total__item">
<span>今日拍照数量</span>
<i>{{ countPhotoNo || 0 }}</i>
</div>
</div>
<div class="space">
<div class="space-top">
<h2>相册空间({{ user.editionName }})</h2>
<span>{{ user.usedStorageSpaceStr || 0 }} / {{ user.storageSpaceStr }}</span>
</div>
<div class="rate">
<span :style="{width: rate + '%'}"></span>
</div>
</div>
<div class="album-operate">
<div class="left">
<div class="left-item" @click="addPhoto">
<image src="../images/paizhao.png" />
<span>拍照</span>
</div>
<div class="left-item" @click="linkTo('./AddReport')">
<image src="../images/pintu.png" />
<span>拼图汇报</span>
</div>
</div>
<div class="right">
<div class="right-top">
<image class="right-top__left" src="../images/xiaoxizhushou.png"/>
<image @click="linkTo('./Message')" class="right-top__right" src="../images/gengduo1.png" />
</div>
<div class="right-info">
<div class="right-info__news" v-if="msgInfo.content">
<span>最新</span>
<i v-if="msgInfo.channel !== '0'">{{ msgInfo.content }}</i>
<div style="display: inline" v-else>
<i v-for="(item, index) in msgInfo.msg" :key="index">
<i v-if="item.type === 0">{{ item.value }}</i>
<AiOpenData style="display: inline" v-else type="userName" :openid="item.value"></AiOpenData>
</i>
</div>
</div>
<i v-else>暂无消息</i>
<p>{{ msgInfo.createTime || '' }}</p>
</div>
</div>
</div>
<div class="album-list">
<h2>工作相册</h2>
<div class="album-list__wrapper">
<div class="item" v-for="(item, index) in list" :key="index" @click="linkTo('./AlbumDetail?id=' + item.id)">
<image src="./../images/icon.png" :loading-img="$cdn + 'watermark/loading.png'" v-if="!item.lastPhotoUrl" />
<u-lazy-load class="item-img" img-mode="aspectFill" :height="328" :image="item.lastPhotoUrl" v-else></u-lazy-load>
<div class="item-bottom">
<h2>{{ item.albumName }}</h2>
<div class="item-bottom__info">
<div class="left">
<span>今日新增</span>
<i>{{ item.dayPhtoto }}</i>
<span></span>
</div>
<div class="right">
<image src="../images/zhaopianshuliang.png" />
<span>{{ item.photoTotal }}</span>
</div>
</div>
</div>
</div>
<div class="item item-add" @click="linkTo('./AddAlbum')">
<div class="item-add__btn"></div>
<p>添加相册</p>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'Home',
data () {
return {
countPhotoNo: '',
countPhotographer: '',
list: [],
msgInfo: {}
}
},
computed: {
...mapState(['user']),
rate () {
if (!this.user.usedStorageSpace) {
return 0
}
return ((this.user.usedStorageSpace || 0) / this.user.storageSpace * 100)
}
},
mounted () {
this.getCountPhotoNo()
this.getAlbumList()
this.getMsgList()
this.getUserInfo()
},
destroyed () {
uni.$off('update')
},
methods: {
linkTo (url) {
uni.navigateTo({
url
})
},
update () {
this.getCountPhotoNo()
this.getAlbumList()
this.getMsgList()
this.getUserInfo()
},
getUserInfo () {
this.$http.post('/api/user/info').then(res => {
if (res.code === 0) {
this.$store.commit('setUser', res.data)
}
})
},
getCountPhotoNo () {
this.$http.post('/api/appalbumphoto/countPhotoNo').then(res => {
if (res.code === 0) {
this.countPhotoNo = res.data
}
})
this.$http.post('/api/appalbumphoto/countPhotographer').then(res => {
if (res.code === 0) {
this.countPhotographer = res.data
}
})
},
getMsgList () {
this.$http.post('/api/sysmessage/latestnews').then(res => {
if (res.code === 0) {
if (res.data) {
this.msgInfo = res.data
let msg = res.data.content
if (res.data.channel === '0') {
if (res.data.content.split('$').length === 3) {
msg = res.data.content.split('$').map((v, index) => {
if (index === 1) {
return {
type: 1,
value: v.split('=')[1]
}
}
return {
type: 0,
value: v
}
})
}
}
this.msgInfo.msg = msg
}
}
})
},
getAlbumList () {
this.$http.post('/api/appalbum/list', null, {
params: {
size: 10000
}
}).then(res => {
if (res.code === 0) {
this.list = res.data.records
}
})
},
addPhoto () {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['camera'],
success: res => {
this.linkTo(`./Watermark?url=${encodeURIComponent(res.tempFilePaths[0])}`)
}
})
}
}
}
</script>
<style lang="scss" scoped>
.album-home {
padding: 50px 32px 120px;
* {
box-sizing: border-box;
}
.space {
margin-top: 32px;
padding: 24px;
background: #FFFFFF;
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.02);
border-radius: 16px;
.rate {
display: flex;
position: relative;
align-items: center;
width: 100%;
height: 8px;
background: #EEEEEE;
border-radius: 4px;
overflow: hidden;
span {
position: absolute;
top: 0;
left: 0;
height: 100%;
border-radius: 4px;
background: #2BB1FF;
}
}
.space-top {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 32px;
h2 {
font-size: 32px;
font-weight: 600;
color: #333;
}
span {
font-size: 36px;
font-weight: 600;
color: #3B424A;
}
}
}
.album-list {
& > h2 {
height: 96px;
line-height: 96px;
color: #333333;
font-size: 36px;
font-weight: 600;
}
.item-add {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background: #EFF5FA;
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
border-radius: 16px;
border: 2px solid #FFFFFF;
p {
margin-top: 16px;
font-size: 26px;
color: #999;
}
.item-add__btn {
position: relative;
width: 64px;
height: 64px;
border-radius: 50%;
background: #FFFFFF;
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
&::after {
position: absolute;
left: 50%;
top: 50%;
z-index: 1;
width: 4px;
height: 32px;
background: #333333;
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
border-radius: 4px;
transform: translate(-50%, -50%);
content: ' ';
}
&::before {
position: absolute;
left: 50%;
top: 50%;
z-index: 1;
width: 32px;
height: 4px;
background: #333333;
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
border-radius: 4px;
transform: translate(-50%, -50%);
content: ' ';
}
}
}
.album-list__wrapper {
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: space-between;
.item {
display: flex;
position: relative;
align-items: center;
justify-content: center;
width: 328px;
height: 328px;
margin-top: 32px;
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
border-radius: 16px;
overflow: hidden;
background: #EFF5FA;
.item-bottom {
position: absolute;
left: 0;
bottom: 0;
z-index: 1;
width: 100%;
padding: 20px 16px 16px;
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%);
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
& > h2 {
margin-bottom: 14px;
font-size: 32px;
color: #fff;
}
.item-bottom__info {
display: flex;
align-items: center;
justify-content: space-between;
.right {
display: flex;
align-items: center;
justify-content: space-between;
width: 86px;
height: 48px;
padding: 0 8px;
color: #fff;
background: rgba(0, 0, 0, 0.5);
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
border-radius: 8px;
image {
width: 28px;
height: 28px;
}
}
.left {
span {
color: #c6c5c4;
font-size: 28px;
}
i {
padding: 0 3px;
color: #fff;
font-size: 28px;
}
}
}
}
& > span {
position: absolute;
left: 16px;
top: 16px;
z-index: 1;
width: 94px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 28px;
background: #FF524F;
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
border-radius: 8px;
}
& > image {
width: 80px;
height: 80px;
}
.item-img {
width: 100%;
height: 100%;
}
}
}
}
.album-operate {
display: flex;
align-items: center;
margin: 48px 0 32px;
.right {
flex: 1;
height: 256px;
padding: 24px;
background: #2BB1FF;
box-shadow: 0px 4px 8px 0px rgba(25, 81, 129, 0.12);
border-radius: 16px;
.right-top {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 26px;
.right-top__left {
width: 136px;
height: 32px;
}
.right-top__right {
width: 32px;
height: 32px;
}
}
.right-info {
& > i {
display: block;
padding-top: 14px;
color: #f8fcff;
font-size: 28px;
}
.right-info__news {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
margin-bottom: 12px;
span {
display: inline-block;
width: 68px;
height: 40px;
line-height: 40px;
margin-right: 8px;
text-align: center;
background: #FFBC5E;
border-radius: 8px;
color: #FFFFFF;
}
i {
color: #fff;
font-size: 28px;
}
}
p {
color: #fff;
opacity: 0.8;
font-size: 28px;
}
}
}
.left {
display: flex;
align-items: center;
justify-content: space-between;
flex-direction: column;
width: 288px;
height: 256px;
margin-right: 16px;
.left-item {
display: flex;
align-items: center;
width: 288px;
height: 120px;
padding-left: 48px;
background: #FFFFFF;
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.02);
border-radius: 16px;
&:first-child {
margin-bottom: 26px;
}
span {
color: #333333;
font-size: 32px;
font-weight: 600;
}
image {
width: 32px;
height: 32px;
margin-right: 16px;
}
}
}
}
.userinfo {
display: flex;
align-items: center;
margin-bottom: 50px;
image {
width: 112px;
height: 112px;
margin-right: 24px;
border-radius: 50%;
}
.right {
h2 {
margin-bottom: 10px;
font-weight: 600;
color: #333333;
font-size: 44px;
}
p {
font-size: 28px;
color: #999999;
}
}
}
i, em {
font-style: normal;
}
.album-total {
display: flex;
align-items: center;
.album-total__item {
display: flex;
flex: 1;
font-size: 28px;
i {
color: #3B424A;
font-weight: 600;
}
span {
margin-right: 16px;
color: #999999;
}
}
}
}
</style>

View File

@@ -0,0 +1,391 @@
<template>
<div class="Organize">
<div class="Organize-top">
<div>
<div class="left">
<h2>{{ DD }}</h2>
<div class="left-wrapper__right">
<h3>{{ yyyyMM }}</h3>
<p>·数据统计</p>
</div>
</div>
<div class="right" @click="isShow = true">
<image src="../images/qiehuan.png" />
<span>切换日期</span>
</div>
</div>
</div>
<div class="info">
<div class="info-item info-total">
<div class="info-item__title">
<h2>拍照统计</h2>
</div>
<div class="info-total__wrapper">
<div class="info-total__item">
<span>未拍照</span>
<div class="info-total__item--bottom">
<h3>{{ photoTotal.noPhtoto }}</h3>
<i></i>
</div>
</div>
<div class="info-total__item">
<span>已拍照</span>
<div class="info-total__item--bottom">
<h3>{{ photoTotal.userPhoto }}</h3>
<i></i>
</div>
</div>
<div class="info-total__item">
<span>拍照数</span>
<div class="info-total__item--bottom">
<h3>{{ photoTotal.allPhoto }}</h3>
<i></i>
</div>
</div>
</div>
</div>
<div class="info-item info-rank">
<div class="info-item__title">
<h2>成员拍照排名</h2>
<image src="../images/right.png" @click="linkTo('./PhotoRank?date=' + date.replace(/年|月/g, '-'))" />
</div>
<div class="info-rank__wrapper">
<div class="rank-item" v-for="(item, index) in list" :key="index">
<div class="rank-item__left">
<image src="../images/rank1.png" v-if="index === 0" />
<image src="../images/rank2.png" v-else-if="index === 1" />
<image src="../images/rank3.png" v-else-if="index === 2" />
<span v-else>{{ index + 1 > 9 ? index + 1 : '0' + (index + 1) }}</span>
<h2><AiOpenData v-if="item.name" type="userName" :openid="item.name"/></h2>
</div>
<div class="rank-item__right">
<span>已上传</span>
<i>{{ item.num }}</i>
<span></span>
</div>
</div>
<AiEmpty v-if="!list.length && isMore"></AiEmpty>
</div>
</div>
</div>
<u-calendar v-model="isShow" mode="date" @change="onDateChange"></u-calendar>
</div>
</template>
<script>
export default {
name: 'Organize',
data () {
return {
photoTotal: {},
date: '',
list: [],
isMore: false,
isShow: false,
yyyyMM: '',
DD: ''
}
},
mounted () {
this.date = this.$dayjs(new Date).format('YYYY年MM月DD')
this.yyyyMM = this.$dayjs(new Date).format('YYYY年MM月')
this.DD = this.$dayjs(new Date).format('DD')
this.getPhotoTotal()
},
methods: {
getPhotoTotal () {
this.$http.post(`/api/appattendancerecord/punchclocksum?queryTime=${this.date.replace(/年|月/g, '-')}`).then(res => {
if (res.code === 0) {
this.photoTotal = res.data
}
})
this.$http.post(`/api/appattendancerecord/userphotosort?queryTime=${this.date.replace(/年|月/g, '-')}`).then(res => {
if (res.code === 0) {
this.list = Object.keys(res.data).map(v => {
return {
name: v,
num: res.data[v]
}
})
this.isMore = true
}
})
},
onDateChange (e) {
this.date = `${e.year}${e.month > 9 ? e.month : '0' + e.month}${e.day > 9 ? e.day : '0' + e.day}`
this.yyyyMM = `${e.year}${e.month > 9 ? e.month : '0' + e.month}`
this.DD = e.day > 9 ? e.day : '0' + e.day
this.$nextTick(() => {
this.getPhotoTotal()
})
},
linkTo (url) {
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss" scoped>
.Organize {
padding: 0 0 40px;
* {
box-sizing: border-box;
line-height: 1;
}
i, em {
font-style: normal;
}
.info {
position: relative;
top: -116px;
padding: 0 32px;
.info-item {
margin-bottom: 32px;
padding: 0 32px 32px;
background: #FFFFFF;
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.02);
border-radius: 16px;
&:last-child {
margin-bottom: 0;
}
.info-rank__wrapper {
.rank-item {
display: flex;
align-items: center;
justify-content: space-between;
height: 112px;
border-bottom: 1px solid #DDDDDD;
&:last-child {
border-bottom: none;
}
& > div {
display: flex;
align-items: center;
}
.rank-item__right {
font-size: 28px;
color: #999999;
i {
color: #2E88FF;
}
}
.rank-item__left {
image {
width: 50px;
height: 50px;
margin-right: 32px;
}
span {
width: 60px;
margin-right: 22px;
padding-left: 6px;
color: #CCCCCC;
font-size: 32px;
font-weight: 600;
}
h2 {
color: #333333;
font-size: 32px;
}
}
}
}
.info-work__wrapper {
.top {
display: flex;
align-items: flex-end;
justify-content: space-between;
& > span {
font-size: 32px;
font-weight: 600;
color: #333333;
}
.left {
display: flex;
align-items: baseline;
h2 {
position: relative;
top: 6px;
color: #333;
font-size: 56px;
}
span {
font-size: 32px;
color: #333;
}
i {
margin-left: 12px;
font-size: 32px;
color: #999999;
}
}
}
.progress {
position: relative;
height: 16px;
margin-top: 32px;
margin-bottom: 16px;
background: #EEEEEE;
border-radius: 4px;
overflow: hidden;
& > div {
position: absolute;
top: 0;
left: 0;
height: 16px;
border-radius: 4px;
background: #2E88FF;
}
}
}
.info-total__wrapper {
display: flex;
align-items: center;
& > div {
display: flex;
justify-content: center;
flex-direction: column;
flex: 1;
height: 156px;
margin-right: 18px;
padding: 0 24px;
background: #FFFFFF;
border-radius: 8px;
border: 1px solid #E6E6E7;
&:last-child {
margin-right: 0;
}
.info-total__item--bottom {
display: flex;
align-items: center;
line-height: 1;
}
span {
margin-bottom: 20px;
font-size: 28px;
color: #333;
font-weight: 600;
}
i {
color: #333333;
font-size: 26px;
}
}
}
.info-item__title {
display: flex;
align-items: center;
justify-content: space-between;
height: 108px;
h2 {
font-weight: 600;
font-size: 32px;
color: #333;
}
image {
width: 32px;
height: 32px;
}
}
}
}
.Organize-top {
height: 320px;
width: 100%;
padding: 58px 32px 0;
background: #3975C6;
& > div {
display: flex;
justify-content: space-between;
align-items: center;
}
.right {
display: flex;
align-items: center;
height: 56px;
padding: 0 36px;
background: #285DA4;
border-radius: 28px;
image {
width: 36px;
height: 26px;
margin-right: 12px;
}
span {
color: #FFFFFF;
font-size: 28px;
}
}
.left {
display: flex;
align-items: center;
line-height: 1;
h2 {
margin-right: 16px;
font-size: 100px;
font-weight: 600;
color: #FFFFFF;
}
h3 {
margin-bottom: 8px;
color: #a9c3e6;
font-size: 28px;
}
p {
font-size: 32px;
color: #FFFFFF;
}
}
}
}
</style>

View File

@@ -0,0 +1,64 @@
<template>
<div class="form-wrapper">
<div class="form-content">
<Home ref="Home" v-if="currIndex === 0" @change="onChange"/>
<Organize ref="Organize" v-if="currIndex === 1" @change="onChange"/>
</div>
<AiTabbar :active.sync="currIndex" :list="tabBar"/>
</div>
</template>
<script>
import Home from './Home.vue'
import Organize from './Organize.vue'
export default {
name: 'Tabbar',
appName: '工作相册',
data() {
return {
currIndex: 0
}
},
components: {
Home,
Organize
},
computed: {
tabBar() {
const link = icon => `${this.$cdn}watermark/${icon}.png`
return [
{text: "相册", iconPath: "xiangce", selectedIconPath: "xiangce-active"},
{text: "组织", iconPath: "zuzhi", selectedIconPath: "zuzhi-active"}
].map(e => ({
...e,
iconPath: link(e.iconPath),
selectedIconPath: link(e.selectedIconPath)
}))
}
},
methods: {
onChange(e) {
this.$emit('change', e)
},
show() {
if (this.currIndex == 0) {
this.$nextTick(() => {
this.$refs.Home.update()
})
}
}
},
onReachBottom() {
if (this.currIndex === 0) {
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,954 @@
<template>
<view style="width: 100%; height: 100%; position: relative;" v-show="url" :mode="modeValue" :change:mode="mwx.changeMode" :rotate="rotate" :change:rotate="mwx.changeRotate">
<!-- #ifdef MP-WEIXIN -->
<canvas type="2d" class="canvas" :style="{width: target.width + 'px', height: target.height + 'px'}"></canvas>
<!-- #endif -->
<!-- #ifdef APP-PLUS || H5 -->
<canvas :canvas-id="canvasId" :style="{width: target.width + 'px', height: target.height + 'px'}"></canvas>
<!-- #endif -->
<view class="panel">
<view class="body" @touchstart="mwx.touchstart" @touchmove="mwx.touchmove" @touchend="mwx.touchend" @touchcancel="mwx.touchcancel">
<view class="image-wrap" :class="{transit: transit}" :change:rect="mwx.changeImage" :rect="image">
<image class="image" mode="widthFix" :class="{transit: transit}" :src="url" @load="imageLoad"/>
</view>
<view class="mask"></view>
<view class="frame" :class="{transit: transit}" :change:rect="mwx.changeFrame" :rect="frame">
<view class="rect">
<view class="image-rect" :class="{transit: transit}">
<image class="image" :class="{transit: transit}" :src="url"/>
</view>
</view>
<view class="line-one"></view>
<view class="line-two"></view>
<view class="line-three"></view>
<view class="line-four"></view>
<view class="frame-left-top" @touchstart="mwx.touchstart"></view>
<view class="frame-left-bottom" @touchstart="mwx.touchstart"></view>
<view class="frame-right-top" @touchstart="mwx.touchstart"></view>
<view class="frame-right-bottom" @touchstart="mwx.touchstart"></view>
</view>
</view>
<!-- <view class="toolbar">
<view @tap="oncancle" class="btn-cancel">取消</view>
<view @tap="rotateAngle" class="btn-rotate">旋转</view>
<view @tap="onok" class="btn-ok">确定</view>
</view> -->
</view>
</view>
</template>
<script>
/**
* @property {String} mode 模式
* @value fixed 固定模式,裁剪出固定大小
* @value ratio 等比模式,宽高等比缩放
* @value free 自由模式,不限制宽高比
* @property {String} url 图片路径
* @property {Number} width 宽度
* @property {Number} height 高度
* @property {Number} maxWidth 最大宽带
* @property {Number} minHeight 最大高度
*/
export default {
props: {
mode: {
type: String,
default: "free"
},
url: {
type: String,
default: ""
},
width: {
type: Number,
default: 200
},
height: {
type: Number,
default: 200
},
maxWidth: {
type: Number,
default: 10240
},
maxHeight: {
type: Number,
default: 10240
}
},
data() {
return {
canvasId: Math.random().toString(36).slice(-6),
real: {
width: 100,
height: 100
},
target: {
width: 100,
height: 100
},
body: {
width: 100,
height: 100
},
frame: {
left: 50,
top: 50,
width: 200,
height: 300
},
image: {
left: 20,
top: 20,
width: 300,
height: 400
},
rotate: 0,
transit: false,
modeValue: ""
};
},
methods: {
imageLoad(event) {
this.real.width = event.detail.width;
this.real.height = event.detail.height;
this.target = {};
var query = uni.createSelectorQuery().in(this);
query.select(".body").boundingClientRect((data) => {
this.body.width = data.width;
this.body.height = data.height;
this.init();
}).exec();
},
init() {
this.modeValue = this.mode;
this.rotate = 0;
var rate = this.width / this.height;
var width = this.body.width * 0.7;
var height = this.body.height * 0.7;
if (width / height > rate) {
width = height * rate;
} else {
height = width / rate;
}
var left = (this.body.width - width) / 2;
var top = (this.body.height - height) / 2;
this.frame = {
left: left,
top: top,
width: width,
height: height
};
rate = this.real.width / this.real.height;
width = this.frame.width;
height = this.frame.height;
if (width / height > rate) {
height = width / rate;
} else {
width = height * rate;
}
left = (this.frame.width - width) / 2 + this.frame.left;
top = (this.frame.height - height) / 2 + this.frame.top;
this.image = {
left: left,
top: top,
width: width,
height: height
};
},
async updateData(data) {
this.frame = data.frame;
this.image = data.image;
await this.$nextTick();
this.trimImage();
},
trimImage() {
var rate = this.frame.width / this.frame.height;
var width = this.body.width * 0.7;
var height = this.body.height * 0.7;
if (width / height > rate) {
width = height * rate;
} else {
height = width / rate;
}
var left = (this.body.width - width) / 2;
var top = (this.body.height - height) / 2;
var mul = width / this.frame.width;
var ox = this.frame.left - this.image.left;
var oy = this.frame.top - this.image.top;
this.frame = {
left: left,
top: top,
width: width,
height: height
};
width = this.image.width * mul;
height = this.image.height * mul;
left = this.frame.left - ox * mul;
top = this.frame.top - oy * mul;
this.image = {
left: left,
top: top,
width: width,
height: height
};
if (mul != 1) {
this.transit = true;
setTimeout(() => {
this.transit = false;
}, 300);
}
},
rotateAngle() {
this.rotate -= 90;
var width = this.image.height;
var height = this.image.width;
var left = this.image.left;
var top = this.image.top;
var rate = width / height;
if (width < this.frame.width) {
width = this.frame.width;
height = width / rate;
}
if (height < this.frame.height) {
height = this.frame.height;
width = height * rate;
}
if (left > this.frame.left) {
left = this.frame.left;
}
if (top > this.frame.top) {
top = this.frame.top;
}
if (left + width < this.frame.left + this.frame.width) {
left = this.frame.left + this.frame.width - width;
}
if (top + height < this.frame.top + this.frame.height) {
top = this.frame.top + this.frame.height - height;
}
this.image = {
left: left,
top: top,
width: width,
height: height
};
this.transit = true;
setTimeout(() => {
this.transit = false;
}, 300);
},
onok() {
// #ifdef MP-WEIXIN
this.cropWx();
// #endif
// #ifdef APP-PLUS || H5
this.cropAppH5();
// #endif
},
oncancle() {
this.$emit("cancel");
},
async cropWx() {
var mx = this.computeMatrix();
this.target = {
width: mx.tw,
height: mx.th
};
var canvas = await new Promise((resolve) => {
uni.createSelectorQuery()
.in(this)
.select(".canvas")
.fields({node: true})
.exec((rst) => {
var node = rst[0].node;
resolve(node);
});
});
canvas.width = mx.tw;
canvas.height = mx.th;
uni.showLoading({
title: "处理中"
});
await new Promise((resolve) => {
setTimeout(resolve, 200);
});
var context = canvas.getContext("2d");
var image = canvas.createImage();
await new Promise((resolve, reject) => {
image.onload = resolve;
image.onerror = reject;
image.src = this.url;
});
context.save();
context.rotate(this.rotate * Math.PI / 180);
context.drawImage(image, mx.sx, mx.sy, mx.sw, mx.sh, mx.dx, mx.dy, mx.dw, mx.dh);
context.restore();
uni.canvasToTempFilePath({
canvas: canvas,
destWidth: mx.tw,
destHeight: mx.th,
success: (rst) => {
var path = rst.tempFilePath;
this.$emit("ok", {
path: path
});
},
complete: () => {
uni.hideLoading();
}
});
},
async cropAppH5() {
var mx = this.computeMatrix();
this.target = {
width: mx.tw,
height: mx.th
};
uni.showLoading({
title: "处理中"
});
await new Promise((resolve) => {
setTimeout(resolve, 200);
});
var context = uni.createCanvasContext(this.canvasId, this);
context.save();
context.rotate(this.rotate * Math.PI / 180);
context.drawImage(this.url, mx.sx, mx.sy, mx.sw, mx.sh, mx.dx, mx.dy, mx.dw, mx.dh);
context.restore();
await new Promise((resolve) => {
context.draw(false, resolve);
});
uni.canvasToTempFilePath({
canvasId: this.canvasId,
destWidth: mx.tw,
destHeight: mx.th,
success: (rst) => {
var path = rst.tempFilePath;
// #ifdef H5
var base64 = path;
path = this.parseBlob(path);
this.$emit("ok", {
path: path,
base64: base64
});
// #endif
// #ifdef APP-PLUS
this.$emit("ok", {
path: path
});
// #endif
},
complete: () => {
uni.hideLoading();
}
}, this);
},
computeMatrix() {
var width = this.width;
var height = this.height;
var mul = this.image.width / this.real.width;
if (this.rotate % 180 != 0) {
mul = this.image.height / this.real.width;
}
if (this.mode != "fixed") {
width = this.frame.width / mul;
height = this.frame.height / mul;
}
var rate = width / height;
if (width > this.maxWidth) {
width = this.maxWidth;
height = width / rate;
}
if (height > this.maxHeight) {
height = this.maxHeight;
width = height * rate;
}
var sx = (this.frame.left - this.image.left) / mul;
var sy = (this.frame.top - this.image.top) / mul;
var sw = this.frame.width / mul;
var sh = this.frame.height / mul;
var ox = sx + sw / 2;
var oy = sy + sh / 2;
if (this.rotate % 180 != 0) {
var temp = sw;
sw = sh;
sh = temp;
}
var angle = this.rotate % 360;
if (angle < 0) {
angle += 360;
}
if (angle == 270) {
var x = this.real.width - oy;
var y = ox;
ox = x;
oy = y;
}
if (angle == 180) {
var x = this.real.width - ox;
var y = this.real.height - oy;
ox = x;
oy = y;
}
if (angle == 90) {
var x = oy;
var y = this.real.height - ox;
ox = x;
oy = y;
}
sx = ox - sw / 2;
sy = oy - sh / 2;
var dr = {x: 0, y: 0, w: width, h: height};
dr = this.parseRect(dr, -this.rotate);
return {
tw: width,
th: height,
sx: sx,
sy: sy,
sw: sw,
sh: sh,
dx: dr.x,
dy: dr.y,
dw: dr.w,
dh: dr.h
};
},
parsePoint(point, angle) {
var result = {};
result.x = point.x * Math.cos(angle * Math.PI / 180) - point.y * Math.sin(angle * Math.PI / 180);
result.y = point.y * Math.cos(angle * Math.PI / 180) + point.x * Math.sin(angle * Math.PI / 180);
return result;
},
parseRect(rect, angle) {
var x1 = rect.x;
var y1 = rect.y;
var x2 = rect.x + rect.w;
var y2 = rect.y + rect.h;
var p1 = this.parsePoint({x: x1, y: y1}, angle);
var p2 = this.parsePoint({x: x2, y: y2}, angle);
var result = {};
result.x = Math.min(p1.x, p2.x);
result.y = Math.min(p1.y, p2.y);
result.w = Math.abs(p2.x - p1.x);
result.h = Math.abs(p2.y - p1.y);
return result;
},
parseBlob(base64) {
var arr = base64.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
for(var i = 0; i < n; i++) {
u8arr[i] = bstr.charCodeAt(i);
}
var url = URL || webkitURL;
return url.createObjectURL(new Blob([u8arr], {type: mime}));
},
}
};
</script>
<script module="mwx" lang="wxs">
var mode = "";
var rotate = 0;
var image = {
left: 0,
top: 0,
width: 0,
height: 0
};
var frame = {
left: 0,
top: 0,
width: 0,
height: 0
};
var touches = [];
var touchType = "";
var start = {
frame: {
left: 0,
top: 0,
width: 0,
height: 0
},
image: {
left: 0,
top: 0,
width: 0,
height: 0
}
};
function changeMode(value) {
mode = value;
}
function changeRotate(value, old, oi, instance) {
rotate = value;
updateStyle(oi);
}
function changeImage(value, old, oi, instance) {
image = value;
updateStyle(oi);
}
function changeFrame(value, old, oi, instance) {
frame = value;
updateStyle(oi);
}
function touchstart(event, oi) {
// #ifdef APP-PLUS || H5
event.preventDefault();
event.stopPropagation();
// #endif
touches = event.touches;
var instance = event.instance;
if (instance.hasClass("body")) {
touchType = "body";
} else if (instance.hasClass("frame-left-top")) {
touchType = "left-top";
} else if (instance.hasClass("frame-left-bottom")) {
touchType = "left-bottom";
} else if (instance.hasClass("frame-right-top")) {
touchType = "right-top";
} else if (instance.hasClass("frame-right-bottom")) {
touchType = "right-bottom";
}
start.frame.left = frame.left;
start.frame.top = frame.top;
start.frame.width = frame.width;
start.frame.height = frame.height;
start.image.left = image.left;
start.image.top = image.top;
start.image.width = image.width;
start.image.height = image.height;
return false;
}
function touchmove(event, oi) {
// #ifdef APP-PLUS || H5
event.preventDefault();
event.stopPropagation();
// #endif
var instance = event.instance;
if (touches.length == 1) {
if (touchType == "body") {
moveImage(touches[0], event.touches[0], oi);
} else {
scaleFrame(touches[0], event.touches[0], oi);
}
} else if (touches.length == 2 && event.touches.length == 2) {
var ta = touches[0];
var tb = touches[1];
var tc = event.touches[0];
var td = event.touches[1];
if (ta.identifier != tc.identifier) {
var temp = tc;
tc = td;
td = temp;
}
scaleImage(ta, tb, tc, td, oi);
}
}
function touchend(event, oi) {
touches = [];
oi.callMethod("updateData", {frame: frame, image: image});
}
function touchcancel(event, oi) {
touches = [];
oi.callMethod("updateData", {frame: frame, image: image});
}
function moveImage(ta, tb, oi) {
var ax = tb.clientX - ta.clientX;
var ay = tb.clientY - ta.clientY;
image.left = start.image.left + ax;
image.top = start.image.top + ay;
var left = frame.left;
var top = frame.top;
var width = frame.width;
var height = frame.height;
if (image.left > left) {
image.left = left;
}
if (image.top > top) {
image.top = top;
}
if (image.left + image.width < left + width) {
image.left = left + width - image.width;
}
if (image.top + image.height < top + height) {
image.top = top + height - image.height;
}
updateStyle(oi);
}
function scaleImage(ta, tb, tc, td, oi) {
var x1 = ta.clientX;
var y1 = ta.clientY;
var x2 = tb.clientX;
var y2 = tb.clientY;
var x3 = tc.clientX;
var y3 = tc.clientY;
var x4 = td.clientX;
var y4 = td.clientY;
var ol = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
var el = Math.sqrt((x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4));
var ocx = (x1 + x2) / 2;
var ocy = (y1 + y2) / 2;
var ecx = (x3 + x4) / 2;
var ecy = (y3 + y4) / 2;
var ax = ecx - ocx;
var ay = ecy - ocy;
var scale = el / ol;
if (start.image.width * scale < frame.width) {
scale = frame.width / start.image.width;
}
if (start.image.height * scale < frame.height) {
scale = frame.height / start.image.height;
}
if (start.image.width * scale < frame.width) {
scale = frame.width / start.image.width;
}
image.left = start.image.left + ax - (ocx - start.image.left) * (scale - 1);
image.top = start.image.top + ay - (ocy - start.image.top) * (scale - 1);
image.width = start.image.width * scale;
image.height = start.image.height * scale;
if (image.left > frame.left) {
image.left = frame.left;
}
if (image.top > frame.top) {
image.top = frame.top;
}
if (image.left + image.width < frame.left + frame.width) {
image.left = frame.left + frame.width - image.width;
}
if (image.top + image.height < frame.top + frame.height) {
image.top = frame.top + frame.height - image.height;
}
updateStyle(oi);
}
function scaleFrame(ta, tb, oi) {
var ax = tb.clientX - ta.clientX;
var ay = tb.clientY - ta.clientY;
var x1 = start.frame.left;
var y1 = start.frame.top;
var x2 = start.frame.left + start.frame.width;
var y2 = start.frame.top + start.frame.height;
var cx1 = false;
var cy1 = false;
var cx2 = false;
var cy2 = false;
var mix = 30;
var rate = frame.width / frame.height;
if (touchType == "left-top") {
x1 += ax;
y1 += ay;
cx1 = true;
cy1 = true;
} else if (touchType == "left-bottom") {
x1 += ax;
y2 += ay;
cx1 = true;
cy2 = true;
} else if (touchType == "right-top") {
x2 += ax;
y1 += ay;
cx2 = true;
cy1 = true;
} else if (touchType == "right-bottom") {
x2 += ax;
y2 += ay;
cx2 = true;
cy2 = true;
}
if (x1 < image.left) {
x1 = image.left;
}
if (y1 < image.top) {
y1 = image.top;
}
if (x2 > image.left + image.width) {
x2 = image.left + image.width;
}
if (y2 > image.top + image.height) {
y2 = image.top + image.height;
}
if (cx1) {
if (x1 > x2 - mix) {
x1 = x2 - mix;
}
}
if (cy1) {
if (y1 > y2 - mix) {
y1 = y2 - mix;
}
}
if (cx2) {
if (x2 < x1 + mix) {
x2 = x1 + mix;
}
}
if (cy2) {
if (y2 < y1 + mix) {
y2 = y1 + mix;
}
}
if (cx1) {
if (mode != "free") {
var val = x2 - rate * (y2 - y1);
if (x1 < val) {
x1 = val;
}
}
}
if (cy1) {
if (mode != "free") {
var val = y2 - (x2 - x1) / rate;
if (y1 < val) {
y1 = val;
}
}
}
if (cx2) {
if (mode != "free") {
var val = rate * (y2 - y1) + x1;
if (x2 > val) {
x2 = val;
}
}
}
if (cy2) {
if (mode != "free") {
var val = (x2 - x1) / rate + y1;
if (y2 > val) {
y2 = val;
}
}
}
frame.left = x1;
frame.top = y1;
frame.width = x2 - x1;
frame.height = y2 - y1;
updateStyle(oi);
}
function updateStyle(oi) {
oi.selectComponent(".frame").setStyle({
"left": frame.left + "px",
"top": frame.top + "px",
"width": frame.width + "px",
"height": frame.height + "px"
});
oi.selectComponent(".image-wrap").setStyle({
"left": image.left + "px",
"top": image.top + "px",
"width": image.width + "px",
"height": image.height + "px"
});
oi.selectComponent(".image-rect").setStyle({
"left": image.left - frame.left + "px",
"top": image.top - frame.top + "px",
"width": image.width + "px",
"height": image.height + "px"
});
var left = 0;
var top = 0;
var width = image.width;
var height = image.height;
if (rotate % 180 != 0) {
width = image.height;
height = image.width;
top = width / 2 - height / 2;
left = height / 2 - width/ 2;
}
oi.selectComponent(".image-wrap .image").setStyle({
"left": left + "px",
"top": top + "px",
"width": width + "px",
"height": height + "px",
"transform": "rotate(" + rotate + "deg)"
});
oi.selectComponent(".image-rect .image").setStyle({
"left": left + "px",
"top": top + "px",
"width": width + "px",
"height": height + "px",
"transform": "rotate(" + rotate + "deg)"
});
}
module.exports = {
changeMode: changeMode,
changeRotate: changeRotate,
changeImage: changeImage,
changeFrame: changeFrame,
touchstart: touchstart,
touchmove: touchmove,
touchend: touchend,
touchcancel: touchcancel
};
</script>
<style scoped>
.panel {
position: absolute;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.canvas {
position: absolute;
top: 5000px;
left: 5000px;
}
.toolbar {
position: absolute;
width: 100%;
height: 100rpx;
left: 0rpx;
bottom: 0rpx;
display: flex;
justify-content: space-around;
align-items: center;
}
.btn-cancel {
font-size: 40rpx;
color: #d5dfe5;
font-weight: bold;
}
.btn-ok {
font-size: 40rpx;
color: #FFFFFF;
font-weight: bold;
}
.btn-rotate {
font-size: 40rpx;
color: #d5dfe5;
font-weight: bold;
}
.body {
position: absolute;
left: 0rpx;
right: 0rpx;
top: 0rpx;
bottom: 0rpx;
background: black;
overflow: hidden;
}
.mask {
position: absolute;
left: 0rpx;
right: 0rpx;
top: 0rpx;
bottom: 0rpx;
background: black;
opacity: 0.4;
}
.plank {
position: absolute;
left: 0rpx;
right: 0rpx;
top: 0rpx;
bottom: 0rpx;
}
.image-wrap {
position: absolute;
}
.image-rect {
position: absolute;
}
.image {
position: absolute;
}
.frame {
position: absolute;
left: 100px;
top: 100px;
width: 200px;
height: 200px;
}
.rect {
position: absolute;
left: -2px;
top: -2px;
width: 100%;
height: 100%;
border: 2px solid white;
overflow: hidden;
box-sizing:content-box;
}
.line-one {
position: absolute;
width: 100%;
height: 1px;
background: white;
left: 0;
top: 33.3%;
box-sizing:content-box;
}
.line-two {
position: absolute;
width: 100%;
height: 1px;
background: white;
left: 0;
top: 66.7%;
box-sizing:content-box;
}
.line-three {
position: absolute;
width: 1px;
height: 100%;
background: white;
top: 0;
left: 33.3%;
box-sizing:content-box;
}
.line-four {
position: absolute;
width: 1px;
height: 100%;
background: white;
top: 0;
left: 66.7%;
box-sizing:content-box;
}
.frame-left-top {
position: absolute;
width: 20px;
height: 20px;
left: -6px;
top: -6px;
border-left: 4px solid red;
border-top: 4px solid red;
box-sizing:content-box;
}
.frame-left-bottom {
position: absolute;
width: 20px;
height: 20px;
left: -6px;
bottom: -6px;
border-left: 4px solid red;
border-bottom: 4px solid red;
box-sizing:content-box;
}
.frame-right-top {
position: absolute;
width: 20px;
height: 20px;
right: -6px;
top: -6px;
border-right: 4px solid red;
border-top: 4px solid red;
box-sizing:content-box;
}
.frame-right-bottom {
position: absolute;
width: 20px;
height: 20px;
right: -6px;
bottom: -6px;
border-right: 4px solid red;
border-bottom: 4px solid red;
box-sizing:content-box;
}
.transit {
transition: width 0.3s, height 0.3s, left 0.3s, top 0.3s, transform 0.3s;
}
</style>

View File

@@ -0,0 +1,307 @@
<template>
<div class="Daily" ref="report">
<div class="top" @click="linkTo" v-if="isShowUnit">
<span>{{ unit }}</span>
</div>
<div class="body" @click="linkTo">
<h2 v-if="isShowTitle">{{ title }}</h2>
<div class="subtitle" v-if="subTitle">{{ subTitle }}</div>
</div>
<div class="bottom">
<div class="bottom-item__wrapper">
<div class="bottom-item" @click="linkTo">
<div class="left" v-if="isShowReporter">
<label>汇报人</label>
<span>{{ reporter }}</span>
</div>
<i v-if="isShowDate">{{ date }}</i>
</div>
<div class="bottom-item bottom-item__remark" @click="linkTo" v-if="isShowRemark">
<label>总结</label>
<span class="">{{ remark }}</span>
</div>
<RenderContent style="margin-top: 20px" :richList="richList" @onLongpress="onLongpress"></RenderContent>
</div>
<div class="add" data-html2canvas-ignore ref="add">
<div class="add-btn" @click.stop="addPhoto">
<span>添加图片</span>
</div>
<div class="add-btn" @click.stop="content = '', isShowText = true">
<span>添加文字</span>
</div>
</div>
</div>
<u-modal v-model="isShowText" @confirm="confirm" title="文本" show-cancel-button>
<view class="slot-content">
<textarea placeholder="请输入文本" :maxlength="-1" v-model="content"></textarea>
</view>
</u-modal>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
import RenderContent from './RenderContent.vue'
import { mapFieldLable } from '../../config'
export default {
name: 'Daily',
label: '日报',
props: ['config'],
components: {
RenderContent
},
data () {
return {
imgs: [],
configList: [],
title: '',
subTitle: '',
reporter: '',
date: '',
unit: '',
remark: '',
isShowTitle: true,
isShowSubTitle: true,
isShowDate: true,
isShowReporter: true,
isShowUnit: true,
isShowRemark: false,
richList: [],
isShowText: false,
content: '',
currIndex: -1
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const title = v.filter(v => v.type === '17')[0]
const subTitle = v.filter(v => v.type === '18')[0]
const reporter = v.filter(v => v.type === '19')[0]
const date = v.filter(v => v.type === '1')[0]
const unit = v.filter(v => v.type === '22')[0]
const remark = v.filter(v => v.type === '32')[0]
this.isShowTitle = title.status === '1'
this.isShowRemark = remark.status === '1'
this.isShowUnit = unit.status === '1'
this.isShowReporter = reporter.status === '1'
this.isShowDate = date.status === '1'
this.isShowSubTitle = subTitle.status === '1'
this.title = title.defaultValue || ''
this.subTitle = subTitle.defaultValue || ''
this.reporter = reporter.defaultValue || ''
this.date = date.defaultValue || this.$dayjs(new Date).format('YYYY-MM-DD')
this.unit = unit.defaultValue || ''
this.remark = remark.defaultValue || ''
}
},
deep: true
},
},
mounted () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
}
return v
})
uni.$on('change', e => {
this.configList = e
})
},
methods: {
screenshot () {
for (let i = 0; i < this.configList.length; i ++) {
if (['2', '3', '4', '5'].indexOf(this.configList[i].fieldType) === -1 && this.configList[i].fieldType && !this.configList[i].defaultValue && this.configList[i].status === '1') {
this.$u.toast(`请输入${mapFieldLable(this.config[i].type)}`)
return false
}
}
const height = this.$refs.report.offsetHeight - this.$refs.add.offsetHeight
return html2canvas(this.$refs.report, {
allowTaint: true,
useCORS: true,
height
})
},
onLongpress (e) {
if (e.action === 'remove') {
this.richList.splice(e.index, 1)
} else if (e.action === 'edit') {
this.currIndex = e.index
this.content = e.value
this.isShowText = true
} else {
this.richList[e.index].value = e.value
}
},
addPhoto () {
uni.chooseImage({
count: 9,
sizeType: ['compressed'],
success: res => {
res.tempFilePaths.forEach(v => {
this.richList.push({
type: 'img',
value: v
})
})
}
})
},
confirm () {
if (this.currIndex >= 0) {
if (!this.content) {
this.richList.splice(this.currIndex, 1)
} else {
this.richList[this.currIndex].value = this.content
}
} else {
if (this.content) {
this.richList.push({
type: 'text',
value: this.content
})
}
}
this.isShowText = false
this.content = ''
this.currIndex = -1
},
linkTo () {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url: './WatermarkConfig'
})
}
}
}
</script>
<style lang="scss" scoped>
.Daily {
padding: 40px 32px 0;
background: #fff;
* {
box-sizing: border-box;
}
.slot-content {
margin-top: 20px;
padding: 0 30px;
textarea {
width: 100%;
}
}
.top {
display: flex;
align-items: center;
padding: 8px 0 16px;
color: #333333;
font-size: 32px;
border-bottom: 4px solid #000;
}
.body {
margin-top: 16px;
h2 {
font-size: 68px;
color: #333;
font-weight: 600;
}
.subtitle {
margin-top: 24px;
margin-bottom: 24px;
color: #000;
font-size: 34px;
}
}
.bottom {
margin-top: 24px;
.bottom-item__wrapper {
.bottom-item {
display: flex;
justify-content: space-between;
line-height: 64px;
margin-bottom: 16px;
padding: 0 16px;
color: #fff;
font-size: 28px;
background: #D84A36;
i {
font-style: normal;
}
&.bottom-item__remark {
height: auto;
line-height: 1.3;
padding: 12px 16px;
margin-bottom: 0;
color: #D84A36;
font-size: 28px;
text-align: justify;
border: 3px solid #DB6352;
background: #fff;
span {
flex: 1;
}
}
}
}
.add {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
height: 480px;
margin-top: 32px;
background: #F7F7F7;
border-radius: 8px;
.add-btn {
display: flex;
align-items: center;
justify-content: center;
width: 232px;
height: 80px;
color: #FFFFFF;
font-size: 32px;
background: #408EF6;
border-radius: 40px;
&:last-child {
margin-top: 48px;
color: #408EF6;
background: #E7F5FE;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,330 @@
<template>
<div class="InspectLog" ref="report">
<div class="top" @click="linkTo">
</div>
<div class="body" @click="linkTo">
<h2 v-if="isShowTitle">{{ title }}</h2>
<div class="subtitle" v-if="isShowAddress">{{ address }}</div>
</div>
<div class="bottom">
<div class="bottom-item__wrapper" @click="linkTo">
<div class="bottom-item">
<div class="left" v-if="isShowAddress">
<label>巡查人</label>
<span>{{ reporter }}</span>
</div>
<div class="right">
<i v-if="isShowDate">{{ date }} </i>
<i v-if="isShowWeather"> {{ weather }}</i>
</div>
</div>
<div class="bottom-item bottom-item__remark" v-if="isShowRemark" @click="linkTo">
<label>巡查情况</label>
<span>{{ remark }}</span>
</div>
</div>
<RenderContent class="RenderContent" style="margin-top: 20px" :richList="richList" @onLongpress="onLongpress"></RenderContent>
<div class="add" data-html2canvas-ignore ref="add">
<div class="add-btn" @click="addPhoto">
<span>添加图片</span>
</div>
<div class="add-btn" @click.stop="content = '', isShowText = true">
<span>添加文字</span>
</div>
</div>
</div>
<u-modal v-model="isShowText" @confirm="confirm" title="文本" show-cancel-button>
<view class="slot-content">
<textarea placeholder="请输入文本" :maxlength="-1" v-model="content"></textarea>
</view>
</u-modal>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
import { mapFieldLable } from '../../config'
import RenderContent from './RenderContent.vue'
export default {
name: 'InspectLog',
label: '巡查日志',
props: ['config'],
components: {
RenderContent
},
data () {
return {
title: '巡查日志',
subTitle: '',
reporter: '',
date: '',
remark: '',
address: '',
weather: '',
isShowTitle: true,
isShowWeather: true,
isShowDate: true,
isShowReporter: false,
isShowAddress: false,
isShowRemark: false,
imgs: [],
configList: [],
richList: [],
isShowText: false,
content: '',
currIndex: -1
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const title = v.filter(v => v.type === '17')[0]
const reporter = v.filter(v => v.type === '24')[0]
const date = v.filter(v => v.type === '1')[0]
const address = v.filter(v => v.type === '23')[0]
const remark = v.filter(v => v.type === '25')[0]
const weather = v.filter(v => v.type === '2')[0]
this.isShowTitle = title.status === '1'
this.isShowRemark = remark.status === '1'
this.isShowReporter = reporter.status === '1'
this.isShowWeather = weather.status === '1'
this.isShowDate = date.status === '1'
this.isShowAddress = address.status === '1'
this.title = title.defaultValue || '巡查日志'
this.address = address.defaultValue || uni.getStorageSync('address').address
this.weather = uni.getStorageSync('address').weather || ''
this.reporter = reporter.defaultValue || ''
this.date = date.defaultValue || this.$dayjs(new Date).format('YYYY-MM-DD')
this.remark = remark.defaultValue || ''
}
},
deep: true
},
},
mounted () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '3') {
v.defaultValue = uni.getStorageSync('address').address || ''
}
if (v.fieldType === '2') {
v.defaultValue = uni.getStorageSync('address').weather || ''
}
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
}
return v
})
uni.$on('change', e => {
this.configList = e
})
},
methods: {
screenshot () {
for (let i = 0; i < this.configList.length; i ++) {
if (['2', '3', '4', '5'].indexOf(this.configList[i].fieldType) === -1 && this.configList[i].fieldType && !this.configList[i].defaultValue && this.configList[i].status === '1') {
this.$u.toast(`请输入${mapFieldLable(this.config[i].type)}`)
return false
}
}
const height = this.$refs.report.offsetHeight - this.$refs.add.offsetHeight
return html2canvas(this.$refs.report, {
allowTaint: true,
useCORS: true,
height
})
},
onLongpress (e) {
if (e.action === 'remove') {
this.richList.splice(e.index, 1)
} else if (e.action === 'edit') {
this.currIndex = e.index
this.content = e.value
this.isShowText = true
} else {
this.richList[e.index].value = e.value
}
},
addPhoto () {
uni.chooseImage({
count: 9,
sizeType: ['compressed'],
success: res => {
res.tempFilePaths.forEach(v => {
this.richList.push({
type: 'img',
value: v
})
})
}
})
},
confirm () {
if (this.currIndex >= 0) {
if (!this.content) {
this.richList.splice(this.currIndex, 1)
} else {
this.richList[this.currIndex].value = this.content
}
} else {
if (this.content) {
this.richList.push({
type: 'text',
value: this.content
})
}
}
this.isShowText = false
this.content = ''
this.currIndex = -1
},
linkTo () {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url: './WatermarkConfig'
})
}
}
}
</script>
<style lang="scss" scoped>
.InspectLog {
min-height: calc(100vh - 240px);
padding: 48px 32px 0;
background: #133CA5;
* {
box-sizing: border-box;
}
::v-deep .RenderContent {
p {
color: #fff;
}
}
.slot-content {
margin-top: 20px;
padding: 0 30px;
textarea {
width: 100%;
}
}
.top {
width: 100%;
height: 16px;
background: url(../../images/xc-icon.png) repeat;
background-size: 16px 16px;
}
.body {
margin-top: 32px;
h2 {
font-size: 112px;
color: #fff;
text-align: center;
font-weight: 600;
}
.subtitle {
margin-bottom: 32px;
color: #fff;
text-align: center;
font-size: 40px;
}
}
.bottom {
margin-top: 24px;
.bottom-item__wrapper {
.bottom-item {
display: flex;
justify-content: space-between;
line-height: 64px;
margin-bottom: 16px;
padding: 0 16px;
color: #133CA5;
font-size: 28px;
background: #F9FC4D;
.right {
display: flex;
align-items: center;
i {
font-style: normal;
&:last-child {
margin-left: 8px;
}
}
}
&.bottom-item__remark {
height: auto;
line-height: 1.3;
padding: 12px 16px;
margin-bottom: 0;
font-size: 28px;
text-align: justify;
border: 3px solid #F9FC4D;
span {
flex: 1;
}
}
}
}
.add {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
height: 480px;
margin-top: 72px;
background: #F7F7F7;
border-radius: 8px;
.add-btn {
display: flex;
align-items: center;
justify-content: center;
width: 232px;
height: 80px;
color: #FFFFFF;
font-size: 32px;
background: #408EF6;
border-radius: 40px;
&:last-child {
margin-top: 48px;
color: #408EF6;
background: #E7F5FE;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,302 @@
<template>
<div class="MeetingMminutes" ref="report">
<table @click="linkTo" class="table" border="1" cellspacing="0" cellpadding="16px" bordercolor="#2774CE">
<tr v-if="isShowTitle">
<th colspan="4" class="title">{{ title }}</th>
</tr>
<tr v-if="isShowWeather || isShowDate">
<td v-if="isShowDate" class="nowrap">会议日期</td>
<td colspan="3" v-if="isShowDate">{{ date }}</td>
<!-- <td v-if="isShowWeather" class="nowrap">天气</td>
<td v-if="isShowWeather">{{ weather }}</td> -->
</tr>
<tr v-if="isShowTheme">
<td class="nowrap">会议主题</td>
<td colspan="3">{{ theme }}</td>
</tr>
<tr v-if="isShowRecorder || isShowHoster">
<td class="nowrap" v-if="isShowHoster">主持人</td>
<td v-if="isShowHoster">{{ hoster }}</td>
<td class="nowrap" v-if="isShowRecorder">记录人</td>
<td v-if="isShowRecorder">{{ recorder }}</td>
</tr>
<tr v-if="isShowAttendee">
<td class="nowrap">参与人</td>
<td colspan="3">{{ attendee }}</td>
</tr>
<tr v-if="isShowAddress">
<td class="nowrap">会议地点</td>
<td colspan="3">{{ address }}</td>
</tr>
<tr colspan="2" v-if="isShowRemark">
<td class="nowrap">会议内容</td>
<td colspan="3">{{ remark }}</td>
</tr>
</table>
<RenderContent style="margin-top: 20px" :richList="richList" @onLongpress="onLongpress"></RenderContent>
<div class="bottom" data-html2canvas-ignore ref="add">
<div class="add">
<div class="add-btn" @click="addPhoto">
<span>添加图片</span>
</div>
<div class="add-btn" @click.stop="content = '', isShowText = true">
<span>添加文字</span>
</div>
</div>
</div>
<u-modal v-model="isShowText" @confirm="confirm" title="文本" show-cancel-button>
<view class="slot-content">
<textarea placeholder="请输入文本" :maxlength="-1" v-model="content"></textarea>
</view>
</u-modal>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
import RenderContent from './RenderContent.vue'
import { mapFieldLable } from '../../config'
export default {
name: 'MeetingMminutes',
label: '会议纪要',
props: ['config'],
components: {
RenderContent
},
data () {
return {
title: '巡查日志',
date: '',
hoster: '',
remark: '',
address: '',
recorder: '',
attendee: '',
weather: '',
theme: '',
isShowRecorder: true,
isShowAttendee: true,
isShowTitle: true,
isShowWeather: true,
isShowDate: true,
isShowTheme: true,
isShowAddress: true,
isShowRemark: true,
isShowHoster: true,
imgs: [],
configList: [],
richList: [],
isShowText: false,
content: '',
currIndex: -1
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const title = v.filter(v => v.type === '17')[0]
const hoster = v.filter(v => v.type === '26')[0]
const date = v.filter(v => v.type === '1')[0]
const address = v.filter(v => v.type === '29')[0]
const remark = v.filter(v => v.type === '31')[0]
const theme = v.filter(v => v.type === '30')[0]
const attendee = v.filter(v => v.type === '28')[0]
const recorder = v.filter(v => v.type === '27')[0]
this.isShowTitle = title.status === '1'
this.isShowRemark = remark.status === '1'
this.isShowRecorder = recorder.status === '1'
this.isShowAttendee = attendee.status === '1'
this.isShowTheme = theme.status === '1'
this.isShowDate = date.status === '1'
this.isShowAddress = address.status === '1'
this.isShowHoster = hoster.status === '1'
this.title = title.defaultValue || ''
this.address = address.defaultValue || uni.getStorageSync('address').address
this.hoster = hoster.defaultValue || ''
this.date = date.defaultValue || this.$dayjs(new Date).format('YYYY-MM-DD')
this.remark = remark.defaultValue || ''
this.theme = theme.defaultValue || ''
this.attendee = attendee.defaultValue || ''
this.recorder = recorder.defaultValue || ''
}
},
deep: true
}
},
mounted () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
}
if (v.fieldType === '3') {
v.defaultValue = uni.getStorageSync('address').address || ''
}
return v
})
uni.$on('change', e => {
this.configList = e
})
},
methods: {
screenshot () {
for (let i = 0; i < this.configList.length; i ++) {
if (['2', '3', '4', '5'].indexOf(this.configList[i].fieldType) === -1 && this.configList[i].fieldType && !this.configList[i].defaultValue && this.configList[i].status === '1') {
this.$u.toast(`请输入${mapFieldLable(this.config[i].type)}`)
return false
}
}
const height = this.$refs.report.offsetHeight - this.$refs.add.offsetHeight
return html2canvas(this.$refs.report, {
allowTaint: true,
useCORS: true,
height
})
},
onLongpress (e) {
if (e.action === 'remove') {
this.richList.splice(e.index, 1)
} else if (e.action === 'edit') {
this.currIndex = e.index
this.content = e.value
this.isShowText = true
} else {
this.richList[e.index].value = e.value
}
},
addPhoto () {
uni.chooseImage({
count: 9,
sizeType: ['compressed'],
success: res => {
res.tempFilePaths.forEach(v => {
this.richList.push({
type: 'img',
value: v
})
})
}
})
},
confirm () {
if (this.currIndex >= 0) {
if (!this.content) {
this.richList.splice(this.currIndex, 1)
} else {
this.richList[this.currIndex].value = this.content
}
} else {
if (this.content) {
this.richList.push({
type: 'text',
value: this.content
})
}
}
this.isShowText = false
this.content = ''
this.currIndex = -1
},
linkTo () {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url: './WatermarkConfig'
})
}
}
}
</script>
<style lang="scss" scoped>
.MeetingMminutes {
padding: 48px 32px 0;
background: #fff;
.slot-content {
margin-top: 20px;
padding: 0 30px;
textarea {
width: 100%;
}
}
.table {
width: 100%;
margin: 0;
padding: 0;
border-spacing: none;
text-align: justify;
.title {
color: #2774CE;
font-size: 58px;
font-weight: 600;
letter-spacing: 2px;
}
.nowrap {
word-break: keep-all;
white-space: nowrap;
color: #2774CE;
font-size: 28px;
font-weight: 600;
}
}
* {
box-sizing: border-box;
}
.bottom {
margin-top: 48px;
.add {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
height: 480px;
margin-top: 72px;
background: #F7F7F7;
border-radius: 8px;
.add-btn {
display: flex;
align-items: center;
justify-content: center;
width: 232px;
height: 80px;
color: #FFFFFF;
font-size: 32px;
background: #408EF6;
border-radius: 40px;
&:last-child {
margin-top: 48px;
color: #408EF6;
background: #E7F5FE;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,225 @@
<template>
<div class="rich">
<div
class="rich-item"
@click="onLongpress(item, index)"
v-for="(item, index) in richList"
:key="index"
:class="[currIndex === index ? 'active' : '']">
<p v-if="item.type === 'text'">{{ item.value }}</p>
<image v-else mode="widthFix" :src="item.value" />
</div>
<u-popup v-model="isShow" z-index="11" :closeable="false" border-radius="32" mode="bottom" @close="onClose">
<div class="rich-bottom">
<div class="top">
<h2>{{ type === 'text' ? '编辑文本' : '编辑图片' }}</h2>
<image @click="isShow = false, currIndex = -1" src="../../images/down_boldw.png" />
</div>
<div class="btns">
<div class="btn-item" hover-class="bg-hover" @click="remove">
<image src="../../images/remove-black.png" />
<span>删除</span>
</div>
<div class="btn-item" hover-class="bg-hover" v-if="type === 'text'" @click="toEditText">
<image src="../../images/xiugai.png" />
<span>修改</span>
</div>
<div class="btn-item" hover-class="bg-hover" @click="toClipping" v-else>
<image src="../../images/jiancai.png" />
<span>剪裁</span>
</div>
</div>
</div>
</u-popup>
</div>
</template>
<script>
export default {
props: ['richList'],
data () {
return {
currIndex: -1,
isShow: false,
type: '',
value: '',
action: ''
}
},
onShow () {
this.isShow = false
},
mounted () {
uni.$on('cropper', e => {
this.$emit('onLongpress', {
type: this.type,
value: e,
index: this.currIndex,
action: 'cropper'
})
this.isShow = false
})
},
methods: {
toEditText () {
this.$emit('onLongpress', {
type: this.type,
value: this.value,
index: this.currIndex,
action: 'edit'
})
this.currIndex = -1
this.isShow = false
},
onClose () {
this.isShow = false
this.currIndex = -1
},
remove () {
this.$confirm(this.type === 'text' ? '确定删除该条数据?' : '确定删掉该图片?').then(() => {
this.$emit('onLongpress', {
type: this.type,
value: this.value,
index: this.currIndex,
action: 'remove'
})
this.currIndex = -1
this.isShow = false
}).catch(() => {
})
},
toClipping () {
uni.navigateTo({
url: `./Clipping?url=${encodeURIComponent(this.value)}`
})
},
onLongpress (item, index) {
this.currIndex = index
this.type = item.type
this.value = item.value
this.isShow = true
},
prview (url) {
uni.previewImage({
urls: [url],
current: url
})
}
}
}
</script>
<style lang="scss" scoped>
.rich {
* {
box-sizing: border-box;
}
.rich-bottom {
// position: fixed;
bottom: 0;
left: 0;
z-index: 11;
width: 100%;
border-radius: 32px 32px 0px 0px;
transition: all ease 0.4s;
overflow: hidden;
background: #fff;
.top {
display: flex;
position: relative;
align-items: center;
justify-content: center;
height: 96px;
h2 {
font-size: 28px;
color: #333333;
line-height: 40px;
}
image {
position: absolute;
top: 50%;
right: 32px;
z-index: 1;
width: 32px;
height: 32px;
transform: translateY(-50%);
}
&.active {
transform: translateY(0);
}
}
.btns {
display: flex;
align-items: center;
height: 246px;
div {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
flex: 1;
image {
width: 80px;
height: 80px;
}
span {
color: #333333;
font-size: 28px;
}
}
}
&.active {
transform: translateY(0);
}
}
.rich-item {
margin-bottom: 20rpx;
border: 2px solid transparent;
&:last-child {
margin-bottom: 0;
}
&.active {
border: 2px solid #2477F1;
}
p {
line-height: 1.3;
word-break: break-all;
text-align: justify;
font-size: 30rpx;
color: #333;
}
image {
display: block;
width: 100%;
}
}
}
</style>

View File

@@ -0,0 +1,361 @@
<template>
<div class="WorkReport" ref="report">
<div class="top" @click="linkTo">
<span v-if="isShowUnit">{{ unit || '请输入汇报单位' }}</span>
<span v-if="isShowDate">{{ date || '请选择日期' }}</span>
</div>
<div class="body" @click="linkTo">
<h2 v-if="isShowTitle">{{ title }}</h2>
<div class="subtitle" v-if="isShowSubTitle">{{ subTitle || '请输入标题' }}</div>
<div class="partition">
<div><i></i></div>
</div>
</div>
<div class="bottom">
<div class="bottom-item__wrapper">
<div class="bottom-item" v-if="isShowReporter" @click="linkTo">
<label>汇报人{{ reporter || '请输入汇报人姓名' }}</label>
</div>
<div class="bottom-item" v-if="isShowRemark" @click="linkTo">
<span>备注{{ remark }}</span>
</div>
<RenderContent :richList="richList" @onLongpress="onLongpress"></RenderContent>
</div>
<div class="add" data-html2canvas-ignore ref="add">
<div class="add-btn" @click.stop="addPhoto">
<span>添加图片</span>
</div>
<div class="add-btn" @click.stop="content = '', isShowText = true">
<span>添加文字</span>
</div>
</div>
</div>
<u-modal v-model="isShowText" @confirm="confirm" title="文本" show-cancel-button>
<view class="slot-content">
<textarea placeholder="请输入文本" :maxlength="-1" v-model="content"></textarea>
</view>
</u-modal>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
import RenderContent from './RenderContent.vue'
import { mapFieldLable } from '../../config'
export default {
name: 'WorkReport',
label: '工作汇报',
props: ['config'],
components: {
RenderContent
},
data () {
return {
title: '工作汇报',
subTitle: '',
reporter: '',
date: '',
unit: '',
remark: '',
isShowTitle: true,
isShowSubTitle: true,
isShowDate: true,
isShowReporter: true,
isShowUnit: true,
isShowRemark: false,
imgs: [],
configList: [],
richList: [],
isShowText: false,
content: '',
currIndex: -1
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const title = v.filter(v => v.type === '17')[0]
const subTitle = v.filter(v => v.type === '18')[0]
const reporter = v.filter(v => v.type === '19')[0]
const date = v.filter(v => v.type === '1')[0]
const unit = v.filter(v => v.type === '20')[0]
const remark = v.filter(v => v.type === '4')[0]
this.isShowTitle = title.status === '1'
this.isShowRemark = remark.status === '1'
this.isShowUnit = unit.status === '1'
this.isShowReporter = reporter.status === '1'
this.isShowDate = date.status === '1'
this.isShowSubTitle = subTitle.status === '1'
this.title = title.defaultValue || ''
this.subTitle = subTitle.defaultValue || ''
this.reporter = reporter.defaultValue || ''
this.date = date.defaultValue || this.$dayjs(new Date).format('YYYY-MM-DD')
this.unit = unit.defaultValue || ''
this.remark = remark.defaultValue || ''
}
},
deep: true
},
},
mounted () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
}
return v
})
uni.$on('change', e => {
this.configList = e
})
},
methods: {
screenshot () {
for (let i = 0; i < this.configList.length; i ++) {
if (['2', '3', '4', '5'].indexOf(this.configList[i].fieldType) === -1 && this.configList[i].fieldType && !this.configList[i].defaultValue && this.configList[i].status === '1') {
this.$u.toast(`请输入${mapFieldLable(this.config[i].type)}`)
return false
}
}
const height = this.$refs.report.offsetHeight - this.$refs.add.offsetHeight
return html2canvas(this.$refs.report, {
allowTaint: true,
useCORS: true,
height
})
},
onLongpress (e) {
if (e.action === 'remove') {
this.richList.splice(e.index, 1)
} else if (e.action === 'edit') {
this.currIndex = e.index
this.content = e.value
this.isShowText = true
} else {
console.log(e)
this.richList[e.index].value = e.value
}
},
addPhoto () {
uni.chooseImage({
count: 9,
sizeType: ['compressed'],
success: res => {
res.tempFilePaths.forEach(v => {
this.richList.push({
type: 'img',
value: v
})
})
}
})
},
confirm () {
if (this.currIndex >= 0) {
if (!this.content) {
this.richList.splice(this.currIndex, 1)
} else {
this.richList[this.currIndex].value = this.content
}
} else {
if (this.content) {
this.richList.push({
type: 'text',
value: this.content
})
}
}
this.isShowText = false
this.content = ''
this.currIndex = -1
},
linkTo () {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url: './WatermarkConfig'
})
}
}
}
</script>
<style lang="scss" scoped>
.WorkReport {
padding: 40px 32px 0;
background: #F6F4F0;
* {
box-sizing: border-box;
}
.slot-content {
margin-top: 20px;
padding: 0 30px;
textarea {
width: 100%;
}
}
& > image {
position: fixed;
top: 0;
left: 0;
z-index: 111;
width: 100%;
height: 100vh;
}
.imgs {
margin-top: 20px;
image {
display: block;
width: 100%;
margin-bottom: 10px;
&:last-child {
margin-bottom: 20px;
}
}
}
.top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
color: #333333;
font-size: 32px;
border-bottom: 4px solid #E3464B;
}
.body {
margin-top: 8px;
h2 {
font-size: 112px;
color: #E3464B;
font-weight: 600;
text-align: center;
border-top: 2px solid #E3464B;
}
.subtitle {
margin-top: 8px;
margin-bottom: 10px;
height: 60px;
line-height: 60px;
border-radius: 30px;
color: #E3464B;
font-size: 32px;
text-align: center;
border: 3px solid #E3464B;
}
.partition {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
div {
position: relative;
z-index: 1;
padding: 0 6px;
background: #F6F4F0;
i {
display: block;
width: 10px;
height: 10px;
border-radius: 50%;
background: #E3464B;
}
}
&::after {
position: absolute;
left: 0;
top: 50%;
width: 100%;
height: 2px;
background: #E3464B;
transform: translateY(-50%);
content: '';
}
}
}
.bottom {
margin-top: 6px;
padding-top: 16px;
border-top: 4px solid #E3464B;
.bottom-item__wrapper {
.bottom-item {
display: flex;
line-height: 44px;
margin-bottom: 16px;
color: #333333;
font-size: 32px;
span {
flex: 1;
text-align: justify;
}
&:last-child {
margin-bottom: 0;
}
}
}
.add {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
height: 480px;
margin-top: 32px;
background: #FFFFFF;
border-radius: 8px;
.add-btn {
display: flex;
align-items: center;
justify-content: center;
width: 232px;
height: 80px;
color: #FFFFFF;
font-size: 32px;
background: #408EF6;
border-radius: 40px;
&:last-child {
margin-top: 48px;
color: #408EF6;
background: #E7F5FE;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,197 @@
<template>
<div class="Watermark1" @click.stop="linkTo('./WatermarkConfig')">
<div class="top">
<h2>打卡记录</h2>
<p>{{ time }}</p>
</div>
<div class="info">
<p>{{ date }} {{ weekCn }}</p>
<p>{{ address }}</p>
<p v-if="isShowWeather">{{ weather }}</p>
</div>
<div class="text" v-if="isShowRemark">{{ remark }}</div>
</div>
</template>
<script>
export default {
props: ['config', 'addressInfo'],
data () {
return {
date: '',
time: '',
week: '',
weather: '',
remark: '',
address: '',
timer: null,
configList: [],
isShowWeather: false,
isShowRemark: false
}
},
computed: {
weekCn() {
if (this.week === 1) {
return '星期一'
}
if (this.week === 2) {
return '星期二'
}
if (this.week === 3) {
return '星期三'
}
if (this.week === 4) {
return '星期四'
}
if (this.week === 5) {
return '星期五'
}
if (this.week === 6) {
return '星期六'
}
return '星期天'
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const weather = v.filter(v => v.type === '2')[0]
const remark = v.filter(v => v.type === '4')[0]
this.isShowWeather = weather.status === '1'
this.isShowRemark = remark.status === '1'
this.remark = remark.defaultValue || ''
this.address = uni.getStorageSync('address').address || ''
this.weather = uni.getStorageSync('address').weather || ''
}
},
deep: true
},
addressInfo: {
handler: function (v) {
if (v.address) {
this.address = uni.getStorageSync('address').address || ''
this.weather = uni.getStorageSync('address').weather || ''
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '3') {
v.defaultValue = uni.getStorageSync('address').address || ''
}
if (v.fieldType === '2') {
v.defaultValue = uni.getStorageSync('address').weather || ''
}
return v
})
}
},
deep: true
}
},
created () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '3') {
v.defaultValue = uni.getStorageSync('address').address || ''
}
if (v.fieldType === '2') {
v.defaultValue = uni.getStorageSync('address').weather || ''
}
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
this.week = new Date().getDay()
}
if (v.fieldType === '6') {
v.defaultValue = this.$dayjs().format('HH:mm')
}
return v
})
this.date = this.$dayjs(new Date).format('YYYY-MM-DD')
this.time = this.$dayjs().format('HH:mm')
this.timer = setInterval(() => {
this.date = this.$dayjs().format('YYYY-MM-DD')
this.time = this.$dayjs().format('HH:mm')
this.week = new Date().getDay()
}, 1000)
uni.$on('change', e => {
this.configList = e
})
},
destroyed () {
clearInterval(this.timer)
},
methods: {
linkTo (url) {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss" scoped>
.Watermark1 {
* {
box-sizing: border-box;
}
.text {
min-width: 274px;
height: 48px;
line-height: 48px;
margin-top: 32px;
padding: 0 16px;
font-size: 28px;
background: linear-gradient(270deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.2) 100%);
}
.top {
width: 184px;
background: #FEFFFE;
border-radius: 16px;
text-align: center;
overflow: hidden;
h2 {
height: 64px;
line-height: 64px;
background: #1ABDA6;
font-size: 34px;
font-weight: normal;
}
p {
height: 72px;
line-height: 72px;
font-weight: 600;
color: #333333;
font-size: 48px;
}
}
.info {
line-height: 40px;
margin: 32px 0 0;
padding-left: 22px;
border-left: 6px solid #F8BC58;
p:nth-of-type(2) {
margin: 8px 0;
}
}
}
</style>

View File

@@ -0,0 +1,208 @@
<template>
<div class="Watermark3" @click.stop="linkTo('./WatermarkConfig')">
<div class="top">
<h2 v-if="isShowTitle">{{ title }}</h2>
<span v-if="isShowName">{{ name }}</span>
</div>
<div class="middle">
<h2 v-if="isShowTime">{{ time }}</h2>
<span v-if="isShowWeather">{{ weather }}</span>
</div>
<p v-if="isShowDate">{{ date }} {{ weekCn }}</p>
<div class="text" v-if="isShowMatters && matters">
<span>{{ matters }}</span>
<image src="./../../images/quotes.png" />
</div>
</div>
</template>
<script>
export default {
props: ['config'],
data () {
return {
date: '',
time: '',
week: '',
timer: null,
name: '',
weather: '',
title: '巡检水印',
configList: [],
matters: '',
isShowWeather: false,
isShowDate: false,
isShowTitle: false,
isShowTime: false,
isShowName: false,
isShowMatters: false
}
},
computed: {
weekCn() {
if (this.week === 1) {
return '星期一'
}
if (this.week === 2) {
return '星期二'
}
if (this.week === 3) {
return '星期三'
}
if (this.week === 4) {
return '星期四'
}
if (this.week === 5) {
return '星期五'
}
if (this.week === 6) {
return '星期六'
}
return '星期天'
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const weather = v.filter(v => v.type === '2')[0]
const date = v.filter(v => v.type === '1')[0]
const time = v.filter(v => v.type === '0')[0]
const title = v.filter(v => v.type === '5')[0]
const name = v.filter(v => v.type === '6')[0]
const matters = v.filter(v => v.type === '7')[0]
this.isShowWeather = weather.status === '1'
this.isShowDate = date.status === '1'
this.isShowTitle = title.status === '1'
this.isShowTime = time.status === '1'
this.isShowName = name.status === '1'
this.isShowMatters = matters.status === '1'
this.title = title.defaultValue || ''
this.name = name.defaultValue || ''
this.date = date.defaultValue || this.$dayjs(new Date).format('YYYY-MM-DD')
this.time = time.defaultValue || this.$dayjs().format('HH:mm')
this.weather = uni.getStorageSync('address').weather || ''
this.matters = matters.defaultValue || ''
this.week = date.defaultValue ? this.$dayjs(date.defaultValue).day() : new Date().getDay()
}
},
deep: true
},
},
created () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
this.week = new Date().getDay()
}
if (v.fieldType === '6') {
v.defaultValue = this.$dayjs().format('HH:mm')
}
if (v.fieldType === '2') {
v.defaultValue = uni.getStorageSync('address').weather || ''
}
return v
})
uni.$on('change', e => {
this.configList = e
})
},
destroyed () {
clearInterval(this.timer)
},
methods: {
linkTo (url) {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss" scoped>
.Watermark3 {
width: 348px;
line-height: 1;
padding: 16px;
background: rgba(56, 167, 255, 0.6);
border-radius: 4px;
* {
box-sizing: border-box;
}
.text {
position: relative;
margin-top: 20px;
padding-left: 10px;
font-size: 28px;
image {
position: absolute;
top: -6px;
left: 0;
width: 28px;
height: 24px;
}
}
.middle {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 10px;
h2 {
font-size: 68px;
font-weight: normal;
}
span {
color: #53FBFF;
font-size: 28px;
}
}
& > p {
margin-top: 16px;
font-weight: 500;
font-size: 28px;
}
.top {
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 6px 0 0 6px;
border-bottom: 4px solid #FFE97A;
h2 {
height: 56px;
line-height: 56px;
padding: 0 6px;
text-align: center;
color: #498abe;
font-size: 30px;
border-radius: 6px 6px 0 0;
background: #FFE97A;
}
span {
font-size: 28px;
}
}
}
</style>

View File

@@ -0,0 +1,199 @@
<template>
<div class="Watermark2" @click.stop="linkTo('./WatermarkConfig')">
<div class="top">
<div class="left">
<h2>{{ time }}</h2>
</div>
<div class="right">
<h2>{{ date }} </h2>
<p>{{ weekCn }}</p>
</div>
</div>
<p>{{ address }}</p>
<div class="text" v-if="isShowRemark">{{ remark }}</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
props: ['config'],
data () {
return {
date: '',
time: '',
week: '',
timer: null,
address: '',
remark: '',
configList: [],
isShowRemark: false
}
},
computed: {
weekCn() {
if (this.week === 1) {
return '星期一'
}
if (this.week === 2) {
return '星期二'
}
if (this.week === 3) {
return '星期三'
}
if (this.week === 4) {
return '星期四'
}
if (this.week === 5) {
return '星期五'
}
if (this.week === 6) {
return '星期六'
}
return '星期天'
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const remark = v.filter(v => v.type === '4')[0]
this.isShowRemark = remark.status === '1'
this.remark = remark.defaultValue || ''
this.address = uni.getStorageSync('address').address || ''
}
},
deep: true
},
},
created () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '3') {
v.defaultValue = uni.getStorageSync('address').address || ''
}
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
this.week = new Date().getDay()
}
if (v.fieldType === '6') {
v.defaultValue = this.$dayjs().format('HH:mm')
}
return v
})
this.date = this.$dayjs(new Date).format('YYYY-MM-DD')
this.time = this.$dayjs().format('HH:mm')
this.timer = setInterval(() => {
this.date = this.$dayjs().format('YYYY-MM-DD')
this.time = this.$dayjs().format('HH:mm')
this.week = new Date().getDay()
}, 1000)
uni.$on('change', e => {
this.configList = e
})
},
destroyed () {
clearInterval(this.timer)
},
methods: {
...mapActions(['injectJWeixin']),
linkTo (url) {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss" scoped>
.Watermark2 {
* {
box-sizing: border-box;
}
.text {
min-width: 274px;
height: 48px;
line-height: 48px;
padding: 0 16px;
font-size: 28px;
background: linear-gradient(270deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.7) 100%);
}
.top {
display: flex;
align-items: center;
.left {
position: relative;
margin-right: 38px;
&:after {
position: absolute;
top: 50%;
right: -16px;
z-index: 1;
width: 6px;
height: 72px;
background: #F8BC58;
transform: translateY(-50%);
content: '';
}
h2 {
font-size: 68px;
font-weight: 500;
color: #FFFFFF;
line-height: 80px;
}
}
.right {
font-size: 24px;
font-weight: 500;
color: #FFFFFF;
h2 {
margin-bottom: 8px;
font-weight: 500;
font-size: 24px;
}
}
}
& > p {
margin: 20px 0 16px;
font-weight: 600;
color: #fff;
font-size: 24px;
}
.info {
line-height: 40px;
margin: 32px 0;
padding-left: 22px;
border-left: 6px solid #F8BC58;
p:nth-of-type(2) {
margin: 8px 0;
}
}
}
</style>

View File

@@ -0,0 +1,204 @@
<template>
<div class="Watermark6" @click.stop="linkTo('./WatermarkConfig')">
<div class="title">
<h2>{{ title }}</h2>
</div>
<div class="info">
<div class="info-item">
<label>时间</label>
<span>{{ date }} {{ weekCn}} {{ time }}</span>
</div>
<div class="info-item">
<label>地点</label>
<span>{{ address }}</span>
</div>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
props: ['config'],
data () {
return {
date: '',
timer: null,
week: '',
title: '定格在这一刻',
address: '',
configList: []
}
},
computed: {
weekCn() {
if (this.week === 1) {
return '星期一'
}
if (this.week === 2) {
return '星期二'
}
if (this.week === 3) {
return '星期三'
}
if (this.week === 4) {
return '星期四'
}
if (this.week === 5) {
return '星期五'
}
if (this.week === 6) {
return '星期六'
}
return '星期天'
}
},
watch: {
configList: {
handler: function (v) {
if (v && v.length) {
const date = v.filter(v => v.type === '1')[0]
const time = v.filter(v => v.type === '0')[0]
const title = v.filter(v => v.type === '5')[0]
this.title = title.defaultValue || ''
this.date = date.defaultValue || this.$dayjs(new Date).format('YYYY-MM-DD')
this.time = time.defaultValue || this.$dayjs().format('HH:mm')
this.week = date.defaultValue ? this.$dayjs(date.defaultValue).day() : new Date().getDay()
this.address = uni.getStorageSync('address').address || ''
}
},
deep: true
},
},
created () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '3') {
v.defaultValue = uni.getStorageSync('address').address || ''
this.address = uni.getStorageSync('address').address || ''
}
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
this.week = new Date().getDay()
}
if (v.fieldType === '6') {
v.defaultValue = this.$dayjs().format('HH:mm')
}
return v
})
this.date = this.$dayjs(new Date).format('YYYY-MM-DD')
this.time = this.$dayjs().format('HH:mm')
this.week = new Date().getDay()
uni.$on('change', e => {
this.configList = e
})
},
destroyed () {
clearInterval(this.timer)
},
methods: {
...mapActions(['injectJWeixin']),
linkTo (url) {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss" scoped>
.Watermark6 {
width: 450px;
box-sizing: border-box;
h2 {
font-weight: normal;
}
* {
box-sizing: border-box;
}
.info {
padding: 24px;
background: rgba(255, 255, 255, 0.7);
.info-item {
display: flex;
line-height: 1.3;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
label {
color: #333;
font-size: 28px;
}
span {
flex: 1;
text-align: justify;
color: #000000;
font-size: 28px;
}
}
}
.title {
position: relative;
height: 60px;
line-height: 60px;
text-align: center;
color: #fff;
background: rgba(23, 91, 255, 0.7);
h2 {
font-size: 32px;
}
&::after {
position: absolute;
left: 16px;
top: 50%;
z-index: 1;
width: 12px;
height: 12px;
border-radius: 50%;
background: #FFCA32;
content: ' ';
transform: translateY(-50%);
}
&::before {
position: absolute;
right: 16px;
top: 50%;
z-index: 1;
width: 12px;
height: 12px;
border-radius: 50%;
background: #FFCA32;
content: ' ';
transform: translateY(-50%);
}
}
}
</style>

View File

@@ -0,0 +1,206 @@
<template>
<div class="Watermark4" @click.stop="linkTo('./WatermarkConfig')">
<div class="top">
<image src="./../../images/fangyishuiyin.png" />
<h2>{{ title }}</h2>
</div>
<div class="Watermark4-body">
<h2 v-if="isShowTime">{{ time }}</h2>
<p v-if="isShowDate">{{ date }} {{ weekCn }}</p>
<div class="info">
<div class="info-item" v-if="isShowAddress">
<label>地点</label>
<span>{{ address }}</span>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
props: ['config'],
data () {
return {
date: '',
time: '',
week: '',
timer: null,
title: '日常消杀',
address: '',
configList: [],
isShowAddress: true,
isShowDate: true,
isShowTime: true
}
},
computed: {
weekCn() {
if (this.week === 1) {
return '星期一'
}
if (this.week === 2) {
return '星期二'
}
if (this.week === 3) {
return '星期三'
}
if (this.week === 4) {
return '星期四'
}
if (this.week === 5) {
return '星期五'
}
if (this.week === 6) {
return '星期六'
}
return '星期天'
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const title = v.filter(v => v.type === '5')[0]
const address = v.filter(v => v.type === '3')[0]
const date = v.filter(v => v.type === '1')[0]
const time = v.filter(v => v.type === '0')[0]
this.isShowAddress = address.status === '1'
this.isShowDate = date.status === '1'
this.isShowTime = time.status === '1'
this.title = title.defaultValue || ''
this.date = date.defaultValue || this.$dayjs(new Date).format('YYYY-MM-DD')
this.time = time.defaultValue || this.$dayjs().format('HH:mm')
this.week = date.defaultValue ? this.$dayjs(date.defaultValue).day() : new Date().getDay()
this.address = address.defaultValue || ''
}
},
deep: true
},
},
created () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '3') {
v.defaultValue = uni.getStorageSync('address').address || ''
}
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
this.week = new Date().getDay()
}
if (v.fieldType === '6') {
v.defaultValue = this.$dayjs().format('HH:mm')
}
return v
})
this.date = this.$dayjs(new Date).format('YYYY-MM-DD')
this.time = this.$dayjs().format('HH:mm')
this.week = new Date().getDay()
uni.$on('change', e => {
this.configList = e
})
},
destroyed () {
clearInterval(this.timer)
},
methods: {
...mapActions(['injectJWeixin']),
linkTo (url) {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss" scoped>
.Watermark4 {
width: 400px;
line-height: 1;
border-radius: 4px;
* {
box-sizing: border-box;
}
.top {
position: relative;
width: 400px;
height: 60px;
line-height: 60px;
padding-left: 60px;
background: linear-gradient(270deg, rgba(67, 60, 255, 0) 0%, rgba(60, 163, 255, 0.8) 50%, #3B92FF 100%);
image {
position: absolute;
left: -32px;
top: -16px;
z-index: 1;
width: 92px;
height: 112px;
}
h2 {
font-weight: 500;
font-size: 32px;
color: #fff;
}
}
.Watermark4-body {
padding: 24px 20px;
background: linear-gradient(270deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.5) 50%, rgba(0, 0, 0, 0.5) 100%);
& > h2 {
line-height: 56px;
font-size: 48px;
font-weight: bold;
color: #FFFFFF;
}
& > p {
line-height: 36px;
margin-bottom: 16px;
font-size: 26px;
color: #FFFFFF;
}
.info {
.info-item {
display: flex;
line-height: 1.4;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
label {
color: #BADCFF;
font-size: 28px;
}
span {
flex: 1;
font-size: 28px;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,262 @@
<template>
<div class="Watermark5" @click.stop="linkTo('./WatermarkConfig')">
<div class="top">
<h2>{{ title }}</h2>
<div class="right">
<h2>{{ time }}</h2>
<p>{{ date }}</p>
</div>
</div>
<div class="info">
<div class="info-item">
<label>网格员</label>
<span>{{ gridUserName }}</span>
</div>
<div class="info-item" v-if="isShowGridName">
<label>网格</label>
<span>{{ gridName }}</span>
</div>
<div class="info-item" v-if="isShowAddress">
<label>地点</label>
<span>{{ address }}</span>
</div>
<div class="info-item" v-if="isServiceName">
<label>服务对象</label>
<span>{{ serviceName }}</span>
</div>
</div>
<div class="bottom" v-if="isShowText">
<span>工作纪实</span>
<i>{{ text }}</i>
</div>
<div class="line"></div>
</div>
</template>
<script>
import {mapActions} from 'vuex'
export default {
props: ['config'],
data () {
return {
date: '',
time: '',
week: '',
address: '',
title: '',
timer: null,
gridUserName: '',
gridName: '',
isShowAddress: true,
isShowDate: true,
isShowTime: true,
isShowGridName: true,
serviceName: '',
isServiceName: false,
text: '',
isShowText: '',
configList: []
}
},
computed: {
weekCn() {
if (this.week === 1) {
return '星期一'
}
if (this.week === 2) {
return '星期二'
}
if (this.week === 3) {
return '星期三'
}
if (this.week === 4) {
return '星期四'
}
if (this.week === 5) {
return '星期五'
}
if (this.week === 6) {
return '星期六'
}
return '星期天'
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const address = v.filter(v => v.type === '3')[0]
const gridUserName = v.filter(v => v.type === '9')[0]
const gridName = v.filter(v => v.type === '10')[0]
const title = v.filter(v => v.type === '8')[0]
const serviceName = v.filter(v => v.type === '11')[0]
const text = v.filter(v => v.type === '12')[0]
this.isShowAddress = address.status === '1'
this.isShowGridName = gridName.status === '1'
this.isServiceName = serviceName.status === '1'
this.isShowText = text.status === '1'
this.title = title.defaultValue || ''
this.gridUserName = gridUserName.defaultValue || ''
this.gridName = gridName.defaultValue || ''
this.serviceName = serviceName.defaultValue || ''
this.text = text.defaultValue || ''
this.address = address.defaultValue || ''
}
},
deep: true
},
},
created () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '3') {
v.defaultValue = uni.getStorageSync('address').address || ''
this.address = uni.getStorageSync('address').address || ''
}
return v
})
uni.$on('change', e => {
this.configList = e
})
this.date = this.$dayjs(new Date).format('YYYY-MM-DD')
this.time = this.$dayjs().format('HH:mm')
this.timer = setInterval(() => {
this.date = this.$dayjs().format('YYYY-MM-DD')
this.time = this.$dayjs().format('HH:mm')
this.week = new Date().getDay()
}, 1000)
},
destroyed () {
clearInterval(this.timer)
uni.$off('change')
},
methods: {
...mapActions(['injectJWeixin']),
linkTo (url) {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss" scoped>
.Watermark5 {
width: 440px;
padding: 0 16px 22px;
color: #000;
box-sizing: border-box;
background: #fff;
h2 {
font-weight: normal;
}
* {
box-sizing: border-box;
}
.line {
margin-top: 4px;
height: 4px;
background: #2145C4;
}
.bottom {
display: flex;
align-items: center;
border: 3px solid #2145C4;
span {
width: 120px;
height: 48px;
line-height: 48px;
text-align: center;
color: #fff;
font-size: 26px;
background: #2145C4;
}
i {
flex: 1;
color: #2145C4;
font-size: 26px;
font-style: normal;
text-align: center;
}
}
.info {
margin-bottom: 16px;
.info-item {
display: flex;
line-height: 1.3;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
label {
color: #333;
font-size: 26px;
}
span {
flex: 1;
color: #000000;
font-size: 26px;
font-weight: 600;
}
}
}
.top {
display: flex;
align-items: center;
justify-content: space-between;
height: 90px;
margin-bottom: 20px;
color: #2145C4;
border-bottom: 4px solid #2145C4;
& > h2 {
font-size: 32px;
font-weight: 600;
}
.right {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
h2 {
width: 96px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 30px;
background: #2145C4;
}
p {
font-size: 24px;
}
}
}
}
</style>

View File

@@ -0,0 +1,183 @@
<template>
<div class="Watermark7" @click.stop="linkTo('./WatermarkConfig')">
<image src="../../images/hjws.png" />
<h2 v-if="isShowTitle">{{ title }}</h2>
<div class="middle">
<div class="top">
<h2>{{ time }}</h2>
<span>{{ weather }}</span>
</div>
<div class="bottom">{{ date }} {{ weekCn }}</div>
</div>
<div class="bottom" v-if="isShowAddress">{{ address }}</div>
</div>
</template>
<script>
import {mapActions} from 'vuex'
export default {
props: ['config'],
data () {
return {
date: '',
time: '',
title: '',
week: '',
weather: '',
address: '',
timer: null,
isShowTitle: true,
isShowAddress: true,
configList: []
}
},
computed: {
weekCn() {
if (this.week === 1) {
return '星期一'
}
if (this.week === 2) {
return '星期二'
}
if (this.week === 3) {
return '星期三'
}
if (this.week === 4) {
return '星期四'
}
if (this.week === 5) {
return '星期五'
}
if (this.week === 6) {
return '星期六'
}
return '星期天'
}
},
watch: {
configList: {
handler: function (v) {
if (v.length) {
const address = v.filter(v => v.type === '3')[0]
const title = v.filter(v => v.type === '5')[0]
this.isShowAddress = address.status === '1'
this.isShowTitle = title.status === '1'
this.title = title.defaultValue || ''
this.address = address.defaultValue || ''
}
},
deep: true
},
},
created () {
this.configList = JSON.parse(JSON.stringify(this.config)).map(v => {
if (v.fieldType === '3') {
v.defaultValue = uni.getStorageSync('address').address || ''
}
if (v.fieldType === '2') {
v.defaultValue = uni.getStorageSync('address').weather || ''
}
if (v.fieldType === '7') {
v.defaultValue = this.$dayjs().format('YYYY-MM-DD')
this.week = new Date().getDay()
}
if (v.fieldType === '6') {
v.defaultValue = this.$dayjs().format('HH:mm')
}
return v
})
this.date = this.$dayjs(new Date).format('YYYY-MM-DD')
this.time = this.$dayjs().format('HH:mm')
this.week = new Date().getDay()
uni.$on('change', e => {
this.configList = e
})
},
destroyed () {
clearInterval(this.timer)
},
methods: {
linkTo (url) {
uni.setStorageSync('waterConfig', this.configList)
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss" scoped>
.Watermark7 {
width: 400px;
font-size: 0;
box-sizing: border-box;
h2 {
font-weight: normal;
}
* {
box-sizing: border-box;
}
& > image {
width: 100%;
height: 64px;
}
& > .bottom {
line-height: 1.3;
padding: 10px 16px;
font-size: 26px;
text-align: justify;
background: rgba(27, 120, 65, 0.8);
}
.middle {
line-height: 1;
padding: 16px;
background: rgba(0, 0, 0, 0.5);
.top {
display: flex;
align-items: center;
margin-bottom: 6px;
h2 {
margin-right: 16px;
color: #FFFFFF;
font-size: 48px;
}
span {
color: #62CD8B;
font-size: 26px;
}
}
.bottom {
font-size: 26px;
}
}
& > h2 {
height: 64px;
line-height: 64px;
text-align: center;
color: #fff;
font-size: 32px;
background: #1B7841;
}
}
</style>

View File

@@ -0,0 +1,102 @@
<template>
<div class="Watermark8">
<h2>{{ date }}</h2>
<div>{{ day }}</div>
<p>{{ lunar }} {{ weekCn }}</p>
</div>
</template>
<script>
import lunar from '../../config/calendar'
export default {
data () {
return {
date: '',
week: '',
day: '',
lunar: '',
timer: null
}
},
computed: {
weekCn() {
if (this.week === 1) {
return '星期一'
}
if (this.week === 2) {
return '星期二'
}
if (this.week === 3) {
return '星期三'
}
if (this.week === 4) {
return '星期四'
}
if (this.week === 5) {
return '星期五'
}
if (this.week === 6) {
return '星期六'
}
return '星期天'
}
},
created () {
const date = this.$dayjs(new Date)
const result = lunar.solarToLunar(date.format('YYYY'), date.format('MM'), date.format('DD'))
this.date = date.format('YYYY年MM月')
this.day = date.format('DD')
this.lunar = `${result.monthStr}${result.dayStr}`
this.week = new Date().getDay()
},
destroyed () {
clearInterval(this.timer)
},
methods: {
linkTo (url) {
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss" scoped>
.Watermark8 {
width: 292px;
height: 376px;
color: #FF5643;
box-sizing: border-box;
text-align: center;
background-image: url(../../images/rili.png);
background-size: 100% 100%;
h2 {
height: 68px;
padding-top: 106px;
text-align: center;
font-size: 32px;
color: #fff;
font-weight: normal;
}
div {
line-height: 1;
margin: 10px 0 8px;
font-size: 100px;
font-weight: 600;
}
p {
font-size: 26px;
}
}
</style>