乡村相册迁移位置
@@ -1,287 +0,0 @@
|
||||
<template>
|
||||
<div class="AddAlbum">
|
||||
<div class="form-group">
|
||||
<div class="form-group__item">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>相册名称</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<input placeholder="请输入相册名称" :maxlength="15" v-model="albumName" placeholder-style="color: #999" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>拍摄人</span>
|
||||
</div>
|
||||
<div class="right" @click="linkTo('./PersonnelSetting?id=' + id)">
|
||||
<span>{{ albumUserList.length ? '已选择' : '不限' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item" @click="linkTo('./SourceSetting?value=' + photoSource)">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>照片来源</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<span>{{ photoSource == 1 ? '仅限工作相册拍摄' : '不限' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button v-if="id && id !== '1'" @click="remove" class="form-btn form-btn__remove" hover-class="text-hover">删除相册</button>
|
||||
<button :loading="isLoading" @click="save" class="form-btn" hover-class="text-hover">保存</button>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'AddAlbum',
|
||||
|
||||
appName: '新增相册',
|
||||
|
||||
data () {
|
||||
return {
|
||||
albumName: '',
|
||||
createUserId: '',
|
||||
photoSource: 0,
|
||||
watermarkId: '',
|
||||
isLoading: false,
|
||||
id: '',
|
||||
info: {},
|
||||
albumUserList: []
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.id = query.id || ''
|
||||
|
||||
if (query.id) {
|
||||
this.getInfo(query.id)
|
||||
}
|
||||
|
||||
uni.$on('watermarkChange', e => {
|
||||
if (e.type === 'photoSource') {
|
||||
this.photoSource = e.value
|
||||
}
|
||||
|
||||
if (e.type === 'personnel') {
|
||||
this.albumUserList = e.value
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
linkTo (url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
|
||||
remove () {
|
||||
this.$confirm('确定删除该相册?相册删除后,相册内的照片会同步删除!').then(() => {
|
||||
this.$http.post(`/api/appalbum/delete?ids=${this.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$u.toast('删除成功')
|
||||
uni.$emit('update')
|
||||
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: './AppCountryAlbum'
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
|
||||
getInfo (id) {
|
||||
this.$http.post(`/api/appalbum/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = res.data
|
||||
this.albumName = res.data.albumName
|
||||
this.photoSource = res.data.photoSource || 0
|
||||
this.albumUserList = res.data.albumUserList || []
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
save () {
|
||||
if (!this.albumName) {
|
||||
return this.$u.toast('请输入相册名称')
|
||||
}
|
||||
|
||||
this.$loading()
|
||||
|
||||
this.$http.post('/api/appalbum/addOrUpdate', {
|
||||
albumName: this.albumName,
|
||||
photoSource: this.photoSource,
|
||||
watermarkId: '',
|
||||
albumUserList: this.albumUserList,
|
||||
id: this.id || ''
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$u.toast(this.id ? '编辑成功' : '新建成功')
|
||||
|
||||
if (this.id) {
|
||||
uni.$emit('change')
|
||||
} else {
|
||||
uni.$emit('update')
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}, 500)
|
||||
} else {
|
||||
this.$hideLoading()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AddAlbum {
|
||||
padding-bottom: 130px;
|
||||
|
||||
* {
|
||||
line-height: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
background: #1365DD;
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&.form-btn__remove {
|
||||
bottom: 140rpx;
|
||||
background: #FF4466;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
padding: 0 32px;
|
||||
background: #fff;
|
||||
|
||||
.form-group__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 112px;
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
&.form-group__checked {
|
||||
height: auto;
|
||||
padding: 32px 0;
|
||||
|
||||
.left {
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
&.left-add {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
position: relative;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 16px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: #1088F9;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background: #fff;
|
||||
content: ' ';
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 24px;
|
||||
height: 4px;
|
||||
background: #fff;
|
||||
content: ' ';
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #999999;
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: right;
|
||||
color: #999;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,234 +0,0 @@
|
||||
<template>
|
||||
<div class="report">
|
||||
<components class="report-item" ref="reportItem" :config="currConfig" v-if="currConfig.length" :is="component"></components>
|
||||
<div class="report-list" data-html2canvas-ignore>
|
||||
<div class="report-btns">
|
||||
<span @click="back">返回</span>
|
||||
<h2>拼图模板</h2>
|
||||
<span @click="save">保存</span>
|
||||
</div>
|
||||
<div class="report-wrapper">
|
||||
<div
|
||||
class="report-item"
|
||||
:key="index"
|
||||
v-for="(item, index) in configList"
|
||||
:class="[currIndex === index ? 'active' : '']"
|
||||
@click="changeComponent(item, index)">
|
||||
<image class="img" :src="item.thum" />
|
||||
<image class="checked" v-if="currIndex === index" src="./images/xuanzhong.png" />
|
||||
<span @click="toEdit">编辑</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Daily from './components/report/Daily'
|
||||
import WorkReport from './components/report/WorkReport'
|
||||
import InspectLog from './components/report/InspectLog'
|
||||
import MeetingMminutes from './components/report/MeetingMminutes'
|
||||
|
||||
export default {
|
||||
name: 'Report',
|
||||
|
||||
appName: '拼图汇报',
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'WorkReport',
|
||||
configList: [],
|
||||
currIndex: 0,
|
||||
albumId: ''
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
Daily,
|
||||
InspectLog,
|
||||
WorkReport,
|
||||
MeetingMminutes
|
||||
},
|
||||
|
||||
computed: {
|
||||
currConfig () {
|
||||
if (this.currIndex < 0 || !this.configList.length) return []
|
||||
|
||||
return this.configList[this.currIndex].itemList
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.albumId = query.id || ''
|
||||
this.getConfig()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getConfig () {
|
||||
this.$http.post(`/api/appalbumtemplate/list?size=100&templateType=1&status=1`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.configList = res.data.records
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
back () {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
|
||||
toEdit () {
|
||||
this.$refs.reportItem.linkTo()
|
||||
},
|
||||
|
||||
save () {
|
||||
this.$loading()
|
||||
this.$refs.reportItem.screenshot() && this.$refs.reportItem.screenshot().then(canvas => {
|
||||
let dataURL = canvas.toDataURL('image/png')
|
||||
const file = this.dataURLtoFile(dataURL, 'photo.png')
|
||||
let formData = new FormData()
|
||||
formData.append('file', file)
|
||||
this.$http.post('/admin/file/add2?type=image', formData).then(res => {
|
||||
if (res.code === 0) {
|
||||
const data = this.configList[this.currIndex]
|
||||
uni.navigateTo({
|
||||
url: `./ReportImg?albumId=${this.albumId}&img=${res.data.url}&fileId=${res.data.id}&type=${data.watermarkType}&templateId=${data.id}`
|
||||
})
|
||||
}
|
||||
|
||||
uni.hideLoading()
|
||||
})
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
},
|
||||
|
||||
dataURLtoFile (dataurl, filename) {
|
||||
let arr = dataurl.split(',')
|
||||
let mime = arr[0].match(/:(.*?);/)[1]
|
||||
let bstr = atob(arr[1])
|
||||
let n = bstr.length
|
||||
let u8arr = new Uint8Array(n)
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n)
|
||||
}
|
||||
return new File([u8arr], filename, { type: mime })
|
||||
},
|
||||
|
||||
changeComponent (e, index) {
|
||||
this.currIndex = index
|
||||
this.component = this.mapComponent(e.watermarkType)
|
||||
},
|
||||
|
||||
mapComponent (type) {
|
||||
return {
|
||||
'9': 'WorkReport',
|
||||
'10': 'Daily',
|
||||
'11': 'InspectLog',
|
||||
'12': 'MeetingMminutes'
|
||||
}[type]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.report {
|
||||
position: relative;
|
||||
padding-bottom: 330px;
|
||||
|
||||
.report-btns {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 96px;
|
||||
padding: 0 32px;
|
||||
|
||||
span {
|
||||
color: #222222;
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.report-item {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.report-list {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding-bottom: 16px;
|
||||
background: #FFFFFF;
|
||||
|
||||
.report-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.report-item {
|
||||
position: relative;
|
||||
width: 176px;
|
||||
height: 208px;
|
||||
border: 4px solid transparent;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 208px;
|
||||
}
|
||||
|
||||
span {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 128px;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
border-radius: 8px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.checked {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
.img {
|
||||
border: 4px solid #408EF6;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,471 +0,0 @@
|
||||
<template>
|
||||
<div class="photo" v-if="pageShow">
|
||||
<div class="photo-header">
|
||||
<h2>{{ info.albumName }}</h2>
|
||||
<div
|
||||
class="right"
|
||||
@click="linkTo('./AddAlbum?id=' + id)"
|
||||
hover-class="text-hover"
|
||||
v-if="info.albumName !== '系统相册' && info.createUserId === user.openId">
|
||||
<image src="./images/setting.png" />
|
||||
<span>相册设置</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="photo-info">
|
||||
<div class="photo-info__item">
|
||||
<h2>{{ totalInfo.all || 0 }}</h2>
|
||||
<span>照片</span>
|
||||
</div>
|
||||
<div class="photo-info__item">
|
||||
<h2>{{ totalInfo.today || 0 }}</h2>
|
||||
<span>今日</span>
|
||||
</div>
|
||||
<div class="photo-info__item">
|
||||
<h2>{{ totalInfo.benyue || 0 }}</h2>
|
||||
<span>本月</span>
|
||||
</div>
|
||||
<div class="photo-info__item">
|
||||
<h2>{{ totalInfo.bennian || 0 }}</h2>
|
||||
<span>今年</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="photo-list">
|
||||
<div class="photo-title">
|
||||
<div class="left">
|
||||
<picker mode="date" @change="onChange">
|
||||
<div class="left-item">
|
||||
<span>{{ date || '所有日期' }}</span>
|
||||
<image src="./images/down.png" />
|
||||
</div>
|
||||
</picker>
|
||||
<div class="left-item" style="margin-right: 0;" @click="toChoose">
|
||||
<span v-if="userId"><AiOpenData v-if="userId" type="userName" :openid="userId"></AiOpenData></span>
|
||||
<span v-else>拍摄人</span>
|
||||
<image src="./images/down.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="right" hover-class="text-hover" @click="toEdit">
|
||||
<image src="./images/edit.png" />
|
||||
<span>编辑照片</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="photo-item__wrapper">
|
||||
<div class="photo-item" @click="linkTo('./Photo?id=' + item.id)" v-for="(item, index) in list" :key="index">
|
||||
<!-- <image :src="item.photoUrl" mode="aspectFill" /> -->
|
||||
<u-lazy-load :image="item.photoUrl" :height="328" :loading-img="$cdn + 'watermark/loading.png'" img-mode="aspectFill"></u-lazy-load>
|
||||
<div class="photo-item__text">
|
||||
<h2><AiOpenData v-if="item.createUserId" type="userName" :openid="item.createUserId"></AiOpenData></h2>
|
||||
<p>{{ item.createTime }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="!list.length"></AiEmpty>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-wrapper">
|
||||
<div class="btn" @click="linkTo('./AddReport?id=' + id)">上传拼图汇报</div>
|
||||
<div class="btn" @click="toAddImg" hover-class="text-hover">上传照片</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapActions } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'AlbumDetail',
|
||||
appName: '工作相册',
|
||||
|
||||
data () {
|
||||
return {
|
||||
list: [],
|
||||
type: '',
|
||||
info: {},
|
||||
name: '',
|
||||
date: '',
|
||||
imgList: [],
|
||||
hideStatus: false,
|
||||
pageShow: false,
|
||||
id: '',
|
||||
current: 1,
|
||||
totalInfo: {},
|
||||
isMore: false,
|
||||
userId: ''
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user'])
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.id = query.id
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getTotalInfo(query.id)
|
||||
this.getInfo(query.id)
|
||||
this.getList()
|
||||
})
|
||||
|
||||
uni.$on('change', () => {
|
||||
this.isMore = false
|
||||
this.current = 1
|
||||
this.getInfo(query.id)
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
})
|
||||
|
||||
uni.$on('update', () => {
|
||||
this.isMore = false
|
||||
this.current = 1
|
||||
this.getTotalInfo(query.id)
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
onUnload () {
|
||||
uni.$off('change')
|
||||
uni.$off('update')
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions(['selectPrivilegedContact']),
|
||||
|
||||
linkTo (url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
|
||||
toChoose () {
|
||||
this.$loading()
|
||||
this.selectPrivilegedContact({
|
||||
fromDepartmentId: 0,
|
||||
mode: 'single',
|
||||
selectedOpenUserIds: this.userId ? [this.userId] : ''
|
||||
}).then(res => {
|
||||
console.log(res)
|
||||
uni.hideLoading()
|
||||
if (res.userList && res.userList) {
|
||||
this.userId = res.userList[0].openUserId
|
||||
} else {
|
||||
this.$u.toast('该用户未授权')
|
||||
}
|
||||
|
||||
this.isMore = false
|
||||
this.current = 1
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
}).catch(() => {
|
||||
uni.hideLoading()
|
||||
})
|
||||
},
|
||||
|
||||
toEdit () {
|
||||
if (!this.list.length) {
|
||||
return this.$u.toast('相册无照片,请上传照片')
|
||||
}
|
||||
|
||||
this.linkTo(`./EditAlbum?id=${this.id}`)
|
||||
},
|
||||
|
||||
onChange (e) {
|
||||
this.date = e.detail.value
|
||||
this.isMore = false
|
||||
this.current = 1
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
getInfo (id) {
|
||||
this.$loading()
|
||||
this.$http.post(`/api/appalbum/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = res.data
|
||||
}
|
||||
|
||||
this.pageShow = true
|
||||
})
|
||||
},
|
||||
|
||||
getTotalInfo (id) {
|
||||
this.$http.post(`/api/appalbumphoto/photoDetail?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.totalInfo = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toAddImg () {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: this.info.photoSource === '1' ? ['camera'] : ['album', 'camera'],
|
||||
success: res => {
|
||||
this.linkTo(`./Watermark?url=${encodeURIComponent(res.tempFilePaths[0])}&albumId=${this.id}`)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getList () {
|
||||
if (this.isMore) return
|
||||
|
||||
this.$loading()
|
||||
this.$http.post(`/api/appalbumphoto/DetailByAlbumID`, null, {
|
||||
params: {
|
||||
albumId: this.id,
|
||||
pageSize: 10,
|
||||
queryTime: this.date,
|
||||
userId: this.userId,
|
||||
pageNum: this.current
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
if (this.current > 1) {
|
||||
this.list = [...this.list, ...res.data.records]
|
||||
} else {
|
||||
this.list = []
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.list = res.data.records
|
||||
})
|
||||
}
|
||||
|
||||
if (res.data.records.length < 10) {
|
||||
this.isMore = true
|
||||
uni.hideLoading()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
this.current = this.current + 1
|
||||
}
|
||||
|
||||
uni.hideLoading()
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onReachBottom () {
|
||||
this.getList()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" socped>
|
||||
.photo {
|
||||
min-height: 100vh;
|
||||
padding-bottom: 130px;
|
||||
box-sizing: border-box;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.photo-list {
|
||||
padding: 32px;
|
||||
|
||||
.photo-item__wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.photo-item {
|
||||
position: relative;
|
||||
width: 328px;
|
||||
height: 328px;
|
||||
margin-bottom: 32px;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.photo-item__text {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 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%);
|
||||
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-of-type(2n) {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 44px 0;
|
||||
|
||||
& > h2 {
|
||||
color: #333333;
|
||||
font-size: 38px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.left-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 32px;
|
||||
|
||||
span {
|
||||
color: #666666;
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 26px;
|
||||
color: #333;
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 148px;
|
||||
padding: 0 32rpx;
|
||||
color: #Fff;
|
||||
background: #3975C6;
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 216px;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
border-radius: 28px;
|
||||
font-size: 28px;
|
||||
background: #285DA4;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
flex: 1;
|
||||
margin-right: 20px;
|
||||
color: #fff;
|
||||
font-size: 38px;
|
||||
}
|
||||
}
|
||||
|
||||
.photo-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 168px;
|
||||
background: #3975C6;
|
||||
|
||||
& > div {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 10px;
|
||||
font-weight: 600;
|
||||
font-size: 44px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #C3D5EE;
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-wrapper {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
|
||||
.btn {
|
||||
&:active, &.hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:first-child {
|
||||
flex: 1;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
background: #FFFFFF;
|
||||
box-shadow: inset 0px 1px 0px 0px #DDDDDD;
|
||||
color: #333333;
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.btn:last-child {
|
||||
flex: 1;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
background: #1365DD;
|
||||
box-shadow: inset 0px 1px 0px 0px #DDDDDD;
|
||||
color: #fff;
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<div class="form">
|
||||
<component ref="TabPage" :is="component" @change="onChange" :params="params"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Tabbar from './components/Tabbar.vue'
|
||||
import { mapActions, mapState } from "vuex"
|
||||
|
||||
export default {
|
||||
name: 'AppCountryAlbum',
|
||||
appName: '工作相册',
|
||||
|
||||
data() {
|
||||
return {
|
||||
component: 'Tabbar',
|
||||
params: {}
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
Tabbar
|
||||
},
|
||||
|
||||
onLoad () {
|
||||
uni.setStorageSync('address', {
|
||||
lat: '',
|
||||
lng: '',
|
||||
address: '',
|
||||
weather: '',
|
||||
cityCode: ``
|
||||
})
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
this.getLocation()
|
||||
}, 600)
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.$refs?.TabPage?.show()
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['wxwork'])
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions(['injectJWeixin', 'agentSign']),
|
||||
|
||||
onChange(e) {
|
||||
this.params = e.params
|
||||
this.component = e.type
|
||||
},
|
||||
|
||||
getLocation () {
|
||||
this.injectJWeixin(['getLocation']).then(() => {
|
||||
wx.getLocation({
|
||||
type: 'wgs84',
|
||||
success: res => {
|
||||
var lat = res.latitude
|
||||
var lng = res.longitude
|
||||
this.$http.post('/api/appdvcpconfig/apiForward', `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=3RZBZ-LZUCF-CT6J5-NWKZH-FCWOQ-UUFKY&get_poi=1`).then(res => {
|
||||
if (res.code === 0) {
|
||||
const data = res.data.result
|
||||
uni.setStorageSync('address', {
|
||||
lat,
|
||||
lng,
|
||||
address: data.address,
|
||||
cityCode: `${data.ad_info.adcode}`
|
||||
})
|
||||
|
||||
this.getWeather(`${data.ad_info.adcode}`)
|
||||
}
|
||||
})
|
||||
},
|
||||
error: res => {
|
||||
console.log(res)
|
||||
}
|
||||
})
|
||||
}).catch(e => {
|
||||
})
|
||||
},
|
||||
|
||||
getWeather (code) {
|
||||
this.$http.post(`/api/bdweather/wdata?districtId=${code}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
const data = res.data.result.now
|
||||
|
||||
uni.setStorageSync('address', {
|
||||
...uni.getStorageSync('address'),
|
||||
weather: `${data.text} ${data.temp}°` || ''
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -1,331 +0,0 @@
|
||||
<template>
|
||||
<div class="Attendance">
|
||||
<div class="Attendance-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-tab">
|
||||
<div class="left">
|
||||
<span @click="changeTab(0)" :class="[currIndex === 0 ? 'active' : '']">全部 {{ attendanceCount.all || 0 }}</span>
|
||||
<span @click="changeTab(1)" :class="[currIndex === 1 ? 'active' : '']">已出勤 {{ attendanceCount.hasIn || 0 }}</span>
|
||||
<span @click="changeTab(2)" :class="[currIndex === 2 ? 'active' : '']">未出勤 {{ attendanceCount.hasOut || 0 }}</span>
|
||||
</div>
|
||||
<div class="right" @click="linkTo('./AttendanceSetting')" v-if="isAdmin">考勤设置</div>
|
||||
</div>
|
||||
<div class="info-table">
|
||||
<div class="table-header">
|
||||
<span>人员</span>
|
||||
<span>上下班时间</span>
|
||||
<span>工作时长</span>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div class="table-row" v-for="(item, index) in list" :key="index">
|
||||
<div class="table-row__left">
|
||||
<h2><AiOpenData v-if="item.userId" type="userName" :openid="item.userId"></AiOpenData></h2>
|
||||
<p>已上传{{ item.photoCount || 0 }}张</p>
|
||||
</div>
|
||||
<span>{{ item.workInTime }}-{{ item.workOutTime || '' }}</span>
|
||||
<span>{{ item.workHours || 0 }}小时</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<u-calendar v-model="isShow" mode="date" @change="onDateChange"></u-calendar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Attendance',
|
||||
|
||||
appName: '考勤统计',
|
||||
|
||||
data () {
|
||||
return {
|
||||
date: '',
|
||||
currIndex: 0,
|
||||
list: [],
|
||||
attendanceCount: {},
|
||||
all: '1',
|
||||
hasIn: '',
|
||||
hasOut: '',
|
||||
yyyyMM: '',
|
||||
DD: '',
|
||||
isShow: false,
|
||||
isAdmin: false
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.isAdmin = !!this.$store.state.user.adminAuthType
|
||||
|
||||
if (query.date) {
|
||||
this.date = this.$dayjs(query.date).format('YYYY年MM月DD')
|
||||
this.yyyyMM = this.$dayjs(query.date).format('YYYY年MM月')
|
||||
this.DD = this.$dayjs(query.date).format('DD')
|
||||
} else {
|
||||
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.getList()
|
||||
this.getTotal()
|
||||
},
|
||||
|
||||
methods: {
|
||||
linkTo (url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
|
||||
changeTab (index) {
|
||||
if (index === 0) {
|
||||
this.all = '1'
|
||||
this.hasIn = ''
|
||||
this.hasOut = ''
|
||||
} else if (index === 1) {
|
||||
this.all = ''
|
||||
this.hasIn = '1'
|
||||
this.hasOut = ''
|
||||
} else {
|
||||
this.all = ''
|
||||
this.hasIn = ''
|
||||
this.hasOut = '1'
|
||||
}
|
||||
|
||||
this.currIndex = index
|
||||
|
||||
this.getList()
|
||||
},
|
||||
|
||||
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.getList()
|
||||
this.getTotal()
|
||||
})
|
||||
},
|
||||
|
||||
getTotal () {
|
||||
this.$http.post(`/api/appattendancerecord/attendanceCount?queryTime=${this.date.replace(/年|月/g, '-')}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.attendanceCount = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getList () {
|
||||
this.$loading()
|
||||
this.$http.post(`/api/appattendancerecord/alldetail?all=${this.all}&hasIn=${this.hasIn}&hasOut=${this.hasOut}&queryTime=${this.date.replace(/年|月/g, '-')}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.list = res.data.map(v => {
|
||||
return {
|
||||
...v,
|
||||
workInTime: v.workInTime ? this.$dayjs(v.workInTime).format('HH:mm') : '',
|
||||
workOutTime: v.workOutTime ? this.$dayjs(v.workOutTime).format('HH:mm') : ''
|
||||
}
|
||||
})
|
||||
|
||||
this.$hideLoading()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.Attendance {
|
||||
padding: 0 0 0;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
i, em {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.info-table {
|
||||
margin-top: 32px;
|
||||
padding: 0 32px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 96px;
|
||||
background: #F4F9FD;
|
||||
border-radius: 8px;
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
.table-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 160px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
|
||||
&:nth-of-type(2n) {
|
||||
background: #F4F9FD;
|
||||
}
|
||||
|
||||
div {
|
||||
h2 {
|
||||
margin-bottom: 16px;
|
||||
color: #333333;
|
||||
font-size: 34px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
div, span {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #333;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
position: relative;
|
||||
top: -116px;
|
||||
margin: 0 32px;
|
||||
padding: 0 0 86px 0;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.02);
|
||||
border-radius: 16px;
|
||||
|
||||
.info-tab {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 108px;
|
||||
padding: 0 32px 0 16px;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
span {
|
||||
width: 124px;
|
||||
height: 108px;
|
||||
line-height: 108px;
|
||||
margin-right: 32px;
|
||||
text-align: center;
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #1365DD;
|
||||
border-bottom: 2px solid #1365DD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #3975C6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.Attendance-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>
|
||||
@@ -1,413 +0,0 @@
|
||||
<template>
|
||||
<div class="AttendanceFiexdTime">
|
||||
<div class="form-group">
|
||||
<div class="form-group__item">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>上班打卡时间</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'workInTime')">
|
||||
<div class="right">
|
||||
<span>{{ form.workInTime || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
<div class="form-group__item">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>下班打卡时间</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'workOutTime')">
|
||||
<div class="right">
|
||||
<span>{{ form.workOutTime || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group__item form-group__checked">
|
||||
<div class="left">
|
||||
<h2>是否开启休息时间</h2>
|
||||
<p>若开启休息时间,则休息时间不计入工作时长</p>
|
||||
</div>
|
||||
<div class="right">
|
||||
<switch color="#1088F9" :checked="form.openRestTime === '1'" @change="onOpenRestChange" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item" v-if="form.openRestTime === '1'">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>休息开始</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'restTimeBegin')">
|
||||
<div class="right">
|
||||
<span>{{ form.restTimeBegin || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
<div class="form-group__item" v-if="form.openRestTime === '1'">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>休息结束</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'restTimeEnd')">
|
||||
<div class="right">
|
||||
<span>{{ form.restTimeEnd || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group__item form-group__checked">
|
||||
<div class="left">
|
||||
<h2>允许打卡时间范围</h2>
|
||||
<p>超过打卡时间则记为迟到,提前打卡则记为早退</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>上班打卡</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'workInFrom')">
|
||||
<div class="right">
|
||||
<span>{{ form.workInFrom || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
<div class="form-group__item">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>下班打卡</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'workOutEnd')">
|
||||
<div class="right">
|
||||
<span>{{ form.workOutEnd || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group__item form-group__checked">
|
||||
<div class="left">
|
||||
<h2>是否开启固定打卡点</h2>
|
||||
<p>若开启,不在固定范围内打卡将不计入考勤</p>
|
||||
</div>
|
||||
<div class="right">
|
||||
<switch color="#1088F9" :checked="form.openWorkPoint === '1'" @change="onWorkPointChange" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item form-item__address form-group__checked" v-if="form.openWorkPoint === '1' && address.address">
|
||||
<div class="left">
|
||||
<h2>{{ address.title }}</h2>
|
||||
<p>{{ address.address }}</p>
|
||||
<p style="margin-top: 8px;">允许打卡范围{{ address.distance }}米</p>
|
||||
</div>
|
||||
<div class="right" @click="address = {}">
|
||||
<image src="./images/remove.png" />
|
||||
<span>删除</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item form-group__checked" v-if="form.openWorkPoint === '1' && !address.address">
|
||||
<div class="left left-add" @click="linkTo('./ChooseAddess')">
|
||||
<div class="add-btn"></div>
|
||||
<h2 style="color: #1088F9;">添加打卡点</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-btn" hover-class="text-hover" @click="save">保存</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'AttendanceFiexdTime',
|
||||
|
||||
appName: '固定时间打卡设置',
|
||||
|
||||
data () {
|
||||
return {
|
||||
form: {
|
||||
openRestTime: '1',
|
||||
openWorkPoint: '0',
|
||||
workInTime: '',
|
||||
restTimeBegin: '',
|
||||
restTimeEnd: '',
|
||||
workOutTime: '',
|
||||
workInFrom: '',
|
||||
workOutEnd: ''
|
||||
},
|
||||
address: {}
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
uni.$on('address', e => {
|
||||
this.address = e
|
||||
})
|
||||
|
||||
if (query.id) {
|
||||
this.id = query.id
|
||||
|
||||
this.getInfo(query.id)
|
||||
}
|
||||
},
|
||||
|
||||
onUnload () {
|
||||
uni.$off('address')
|
||||
},
|
||||
|
||||
methods: {
|
||||
linkTo (url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
|
||||
getInfo (id) {
|
||||
this.$http.post(`/api/appattendanceconfig/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.address = JSON.parse(res.data.workPointDesc)
|
||||
this.form = {
|
||||
...this.form,
|
||||
...res.data
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onTimeChange (e, type) {
|
||||
this.form[type] = e.detail.value + ':00'
|
||||
},
|
||||
|
||||
onOpenRestChange (e) {
|
||||
this.form.restTimeBegin = ''
|
||||
this.form.restTimeEnd = ''
|
||||
this.form.openRestTime = e.detail.value ? '1' : '0'
|
||||
},
|
||||
|
||||
onWorkPointChange (e) {
|
||||
this.form.openWorkPoint = e.detail.value ? '1' : '0'
|
||||
this.form.workPointDesc = {}
|
||||
this.address = {}
|
||||
},
|
||||
|
||||
save () {
|
||||
if (!this.form.workInTime) {
|
||||
return this.$u.toast('请选择上班打卡时间')
|
||||
}
|
||||
|
||||
if (!this.form.workOutTime) {
|
||||
return this.$u.toast('请选择下班打卡时间')
|
||||
}
|
||||
|
||||
if (this.$dayjs('2020-06-01 ' + this.form.workOutTime).valueOf() <= this.$dayjs('2020-06-01 ' + this.form.workInTime).valueOf()) {
|
||||
return this.$u.toast('下班时间不能早于上班时间')
|
||||
}
|
||||
|
||||
if (this.form.openRestTime === '1') {
|
||||
if (!this.form.restTimeBegin) {
|
||||
return this.$u.toast('请选择休息开始时间')
|
||||
}
|
||||
|
||||
if (!this.form.restTimeEnd) {
|
||||
return this.$u.toast('请选择休息结束时间')
|
||||
}
|
||||
|
||||
if (this.$dayjs('2020-06-01 ' + this.form.restTimeEnd).valueOf() <= this.$dayjs('2020-06-01 ' + this.form.restTimeBegin).valueOf()) {
|
||||
return this.$u.toast('休息结束时间不能早于休息开始时间')
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.form.workInFrom) {
|
||||
return this.$u.toast('请选择上班打卡最早时间')
|
||||
}
|
||||
|
||||
if (!this.form.workOutEnd) {
|
||||
return this.$u.toast('请选择下班打卡最晚时间')
|
||||
}
|
||||
|
||||
if (this.$dayjs('2020-06-01 ' + this.form.workOutEnd).valueOf() <= this.$dayjs('2020-06-01 ' + this.form.workInFrom).valueOf()) {
|
||||
return this.$u.toast('下班打卡最晚时间不能早于上班打卡最早时间')
|
||||
}
|
||||
|
||||
if (this.form.openWorkPoint === '1' && !this.address.address) {
|
||||
return this.$u.toast('请选择固定打卡点')
|
||||
}
|
||||
|
||||
this.$loading()
|
||||
this.$http.post('/api/appattendanceconfig/addOrUpdate', {
|
||||
openRestTime: this.form.openRestTime,
|
||||
openWorkPoint: this.form.openWorkPoint,
|
||||
workInFrom: `${this.form.workInFrom}`,
|
||||
workOutEnd: `${this.form.workOutEnd}`,
|
||||
workInTime: `${this.form.workInTime}`,
|
||||
workOutTime: `${this.form.workOutTime}`,
|
||||
restTimeBegin: `${this.form.restTimeBegin}`,
|
||||
restTimeEnd: `${this.form.restTimeEnd}`,
|
||||
type: 0,
|
||||
workPointDesc: JSON.stringify(this.address),
|
||||
id: this.id || ''
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$u.toast('提交成功')
|
||||
|
||||
setTimeout(() => {
|
||||
uni.$emit('update')
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AttendanceFiexdTime {
|
||||
padding-bottom: 130px;
|
||||
|
||||
* {
|
||||
line-height: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
background: #1365DD;
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
padding: 0 32px;
|
||||
background: #fff;
|
||||
|
||||
.form-group__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 112px;
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
&.form-group__checked {
|
||||
height: auto;
|
||||
padding: 32px 0;
|
||||
|
||||
.left {
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
&.left-add {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
position: relative;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 16px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: #1088F9;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background: #fff;
|
||||
content: ' ';
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 24px;
|
||||
height: 4px;
|
||||
background: #fff;
|
||||
content: ' ';
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #999999;
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-item__address {
|
||||
.left {
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
|
||||
p {
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
span {
|
||||
margin-left: 10px;
|
||||
color: #1088F9;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,398 +0,0 @@
|
||||
<template>
|
||||
<div class="AttendanceFiexdTime">
|
||||
<div class="form-group">
|
||||
<div class="form-group__item">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>最早允许打卡时间</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'workInFrom')">
|
||||
<div class="right">
|
||||
<span>{{ form.workInFrom || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
<div class="form-group__item">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>最晚允许打卡时间</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'workOutEnd')">
|
||||
<div class="right">
|
||||
<span>{{ form.workOutEnd || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group__item form-group__checked">
|
||||
<div class="left">
|
||||
<h2>是否开启休息时间</h2>
|
||||
<p>若开启休息时间,则休息时间不计入工作时长</p>
|
||||
</div>
|
||||
<div class="right">
|
||||
<switch color="#1088F9" :checked="form.openRestTime === '1'" @change="onOpenRestChange" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item" v-if="form.openRestTime === '1'">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>休息开始</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'restTimeBegin')">
|
||||
<div class="right">
|
||||
<span>{{ form.restTimeBegin || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
<div class="form-group__item" v-if="form.openRestTime === '1'">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>休息结束</span>
|
||||
</div>
|
||||
<picker mode="time" @change="e => onTimeChange(e, 'restTimeEnd')">
|
||||
<div class="right">
|
||||
<span>{{ form.restTimeEnd || '请设置时间' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group__item form-group__checked">
|
||||
<div class="left">
|
||||
<h2>工作时长要求</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item">
|
||||
<div class="left">
|
||||
<label>*</label>
|
||||
<span>时长要求</span>
|
||||
</div>
|
||||
<picker :range="hours" mode="selector" @change="e => form.workHoursLimit = hours[e.detail.value]">
|
||||
<div class="right">
|
||||
<span>{{ form.workHoursLimit ? form.workHoursLimit + '小时' : '请选择工作时长' }}</span>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group__item form-group__checked">
|
||||
<div class="left">
|
||||
<h2>是否开启固定打卡点</h2>
|
||||
<p>若开启,不在固定范围内打卡将不计入考勤</p>
|
||||
</div>
|
||||
<div class="right">
|
||||
<switch color="#1088F9" :checked="form.openWorkPoint === '1'" @change="onWorkPointChange" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item form-group__checked form-item__address" v-if="form.openWorkPoint === '1' && address.address">
|
||||
<div class="left">
|
||||
<h2>{{ address.title }}</h2>
|
||||
<p>{{ address.address }}</p>
|
||||
<p style="margin-top: 8px;">允许打卡范围{{ address.distance }}米</p>
|
||||
</div>
|
||||
<div class="right" @click="address = {}">
|
||||
<image src="./images/remove.png" />
|
||||
<span>删除</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group__item form-group__checked" v-if="form.openWorkPoint === '1' && !address.address">
|
||||
<div class="left left-add" @click="linkTo('./ChooseAddess')">
|
||||
<div class="add-btn"></div>
|
||||
<h2 style="color: #1088F9;">添加打卡点</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-btn" hover-class="text-hover" @click="save">保存</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'AttendanceFlexibleTime',
|
||||
|
||||
appName: '灵活时间打卡设置',
|
||||
data () {
|
||||
return {
|
||||
hours: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17'],
|
||||
form: {
|
||||
openRestTime: '1',
|
||||
openWorkPoint: '0',
|
||||
workHoursLimit: '',
|
||||
restTimeBegin: '',
|
||||
restTimeEnd: '',
|
||||
workInFrom: '',
|
||||
workOutEnd: ''
|
||||
},
|
||||
address: {},
|
||||
id: ''
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
uni.$on('address', e => {
|
||||
this.address = e
|
||||
})
|
||||
|
||||
if (query.id) {
|
||||
this.id = query.id
|
||||
|
||||
this.getInfo(query.id)
|
||||
}
|
||||
},
|
||||
|
||||
onUnload () {
|
||||
uni.$off('address')
|
||||
},
|
||||
|
||||
methods: {
|
||||
linkTo (url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
|
||||
getInfo (id) {
|
||||
this.$http.post(`/api/appattendanceconfig/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.address = JSON.parse(res.data.workPointDesc)
|
||||
this.form = {
|
||||
...this.form,
|
||||
...res.data
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onTimeChange (e, type) {
|
||||
this.form[type] = e.detail.value + ':00'
|
||||
},
|
||||
|
||||
onOpenRestChange (e) {
|
||||
this.form.restTimeBegin = ''
|
||||
this.form.restTimeEnd = ''
|
||||
this.form.openRestTime = e.detail.value ? '1' : '0'
|
||||
},
|
||||
|
||||
onWorkPointChange (e) {
|
||||
this.form.openWorkPoint = e.detail.value ? '1' : '0'
|
||||
this.form.workPointDesc = {}
|
||||
this.address = {}
|
||||
},
|
||||
|
||||
save () {
|
||||
if (!this.form.workInFrom) {
|
||||
return this.$u.toast('请选择最早打卡时间')
|
||||
}
|
||||
|
||||
if (!this.form.workOutEnd) {
|
||||
return this.$u.toast('请选择最晚打卡时间')
|
||||
}
|
||||
|
||||
if (this.$dayjs('2020-06-01 ' + this.form.workOutEnd).valueOf() <= this.$dayjs('2020-06-01 ' + this.form.workInFrom).valueOf()) {
|
||||
return this.$u.toast('最晚打卡时间不能最早打卡时间')
|
||||
}
|
||||
|
||||
if (this.form.openRestTime === '1') {
|
||||
if (!this.form.restTimeBegin) {
|
||||
return this.$u.toast('请选择休息时间')
|
||||
}
|
||||
|
||||
if (!this.form.restTimeEnd) {
|
||||
return this.$u.toast('请选择休息结束时间')
|
||||
}
|
||||
|
||||
if (this.$dayjs('2020-06-01 ' + this.form.restTimeEnd).valueOf() <= this.$dayjs('2020-06-01 ' + this.form.restTimeBegin).valueOf()) {
|
||||
return this.$u.toast('休息结束时间不能早于休息开始时间')
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.form.workHoursLimit) {
|
||||
return this.$u.toast('请选择工作时长')
|
||||
}
|
||||
|
||||
if (this.form.openWorkPoint === '1' && !this.address.address) {
|
||||
return this.$u.toast('请选择固定打卡点')
|
||||
}
|
||||
|
||||
this.$loading()
|
||||
this.$http.post('/api/appattendanceconfig/addOrUpdate', {
|
||||
openRestTime: this.form.openRestTime,
|
||||
workHoursLimit: this.form.workHoursLimit,
|
||||
openWorkPoint: this.form.openWorkPoint,
|
||||
workInFrom: `${this.form.workInFrom}`,
|
||||
workOutEnd: `${this.form.workOutEnd}`,
|
||||
restTimeBegin: `${this.form.restTimeBegin}`,
|
||||
restTimeEnd: `${this.form.restTimeEnd}`,
|
||||
type: 1,
|
||||
workPointDesc: JSON.stringify(this.address),
|
||||
id: this.id || ''
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$u.toast('提交成功')
|
||||
|
||||
setTimeout(() => {
|
||||
uni.$emit('update')
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AttendanceFiexdTime {
|
||||
padding-bottom: 130px;
|
||||
|
||||
* {
|
||||
line-height: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
background: #1365DD;
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
padding: 0 32px;
|
||||
background: #fff;
|
||||
|
||||
.form-group__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 112px;
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
&.form-group__checked {
|
||||
height: auto;
|
||||
padding: 32px 0;
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
&.left-add {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
position: relative;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 16px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: #1088F9;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background: #fff;
|
||||
content: ' ';
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 24px;
|
||||
height: 4px;
|
||||
background: #fff;
|
||||
content: ' ';
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #999999;
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-item__address {
|
||||
.left {
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
|
||||
p {
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
span {
|
||||
margin-left: 10px;
|
||||
color: #1088F9;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,244 +0,0 @@
|
||||
<template>
|
||||
<div class="AttendanceSetting" v-if="pageShow">
|
||||
<div class="cell-group" v-if="!list.length">
|
||||
<div class="cell-item" hover-class="bg-hover" @click="linkTo('./AttendanceFiexdTime')">
|
||||
<div class="cell-item__left">
|
||||
<h2>固定时间上下班</h2>
|
||||
<p>有固定的上下班时间,考核迟到早退</p>
|
||||
</div>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
<div class="cell-item" hover-class="bg-hover" @click="linkTo('./AttendanceFlexibleTime')">
|
||||
<div class="cell-item__left">
|
||||
<h2>灵活时间上下班</h2>
|
||||
<p>上下班时间不固定,考核工时时长</p>
|
||||
</div>
|
||||
<image src="./images/right.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="list.length">
|
||||
<div class="config" v-for="(item, index) in list" :key="index">
|
||||
<h2>当前配置:{{ item.title }}</h2>
|
||||
<div class="config-wrapper">
|
||||
<div class="config-item" v-if="item.type === '0'">
|
||||
<label>上班时间:</label>
|
||||
<span>{{ item.type === '0' ? item.workInTime : item.workInFrom }} - {{ item.type === '0' ? item.workOutTime : item.workOutEnd }}</span>
|
||||
</div>
|
||||
<div class="config-item" v-if="item.type === '1'">
|
||||
<label>工作时长:</label>
|
||||
<span>{{ item.workHoursLimit }}小时</span>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<label>休息时间:</label>
|
||||
<span v-if="item.openRestTime === '0'">未开启</span>
|
||||
<span v-else>{{ item.restTimeBegin }} - {{ item.restTimeEnd }}</span>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<label>打卡时间范围:</label>
|
||||
<!-- <span>上班前2小时,下班后2小时打卡生效</span> -->
|
||||
<span>{{ item.workInFrom }} - {{ item.workOutEnd }}</span>
|
||||
</div>
|
||||
<div class="config-item config-item__line" v-if="item.openWorkPoint === '1'">
|
||||
<label>固定打卡点:</label>
|
||||
<span>{{ item.workPointDesc.address }}</span>
|
||||
</div>
|
||||
<div class="config-item" v-else>
|
||||
<label>固定打卡点:</label>
|
||||
<span>未固定打卡点</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-footer">
|
||||
<div @click="toEdit(item)">修改规则</div>
|
||||
<div @click="remove(item.id)">删除规则</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tips">
|
||||
<span v-if="!list.length">当前考勤时间为00:00~24:00,若新增考勤规则则以
|
||||
新增规则为准;</span>
|
||||
工作时长=(最晚拍照时间)-(最早拍照时间);
|
||||
若员工“最早”或者“最晚”拍照时间缺失,对应工作时长为空;
|
||||
上班时间=最早拍照时间;
|
||||
下班时间=最晚拍照时间。
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AttendanceSetting',
|
||||
|
||||
appName: '考勤设置',
|
||||
|
||||
data () {
|
||||
return {
|
||||
list: [],
|
||||
pageShow: false
|
||||
}
|
||||
},
|
||||
|
||||
onLoad () {
|
||||
this.$loading()
|
||||
this.getConfigList()
|
||||
|
||||
uni.$on('update', () => {
|
||||
this.getConfigList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
linkTo (url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
|
||||
toEdit (item) {
|
||||
if (item.type === '0') {
|
||||
this.linkTo(`./AttendanceFiexdTime?id=${item.id}`)
|
||||
} else {
|
||||
this.linkTo(`./AttendanceFlexibleTime?id=${item.id}`)
|
||||
}
|
||||
},
|
||||
|
||||
remove (id) {
|
||||
this.$confirm('确定删除该数据?').then(() => {
|
||||
this.$http.post(`/app/appattendanceconfig/delete?ids=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$u.toast('删除成功')
|
||||
this.getConfigList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
getConfigList () {
|
||||
this.$http.post(`/api/appattendanceconfig/list?size=1`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.list = res.data.records.map(v => {
|
||||
return {
|
||||
...v,
|
||||
title: v.type === '0' ? '固定时间上下班' : '灵活时间上下班',
|
||||
workPointDesc: JSON.parse(v.workPointDesc)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.pageShow = true
|
||||
uni.hideLoading()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.text-hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.bg-hover {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.AttendanceSetting {
|
||||
.tips {
|
||||
line-height: 44px;
|
||||
margin: 32px;
|
||||
font-size: 28px;
|
||||
color: #999999;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.config {
|
||||
padding: 32rpx 32rpx 0;
|
||||
background: #fff;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 24px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.config-wrapper {
|
||||
padding-bottom: 32px;
|
||||
|
||||
.config-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 40px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 28px;
|
||||
color: #333333;
|
||||
|
||||
label {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
&.config-item__line {
|
||||
display: block;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.config-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 108px;
|
||||
border-top: 1px solid #DDDDDD;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
font-size: 32px;
|
||||
color: #1365DD;
|
||||
text-align: center;
|
||||
|
||||
&:last-child {
|
||||
color: #FF4466;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cell-group {
|
||||
.cell-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 156px;
|
||||
margin-bottom: 16px;
|
||||
padding: 0 32px;
|
||||
background: #FFFFFF;
|
||||
|
||||
&:active {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,427 +0,0 @@
|
||||
<template>
|
||||
<div class="Attendance-address">
|
||||
<AiTMap
|
||||
:map.sync="map"
|
||||
:lib.sync="lib"
|
||||
:ops="ops"
|
||||
:libraries="['service', 'tools']">
|
||||
</AiTMap>
|
||||
<u-popup v-model="isShow" :closeable="false" border-radius="32" height="70%" mode="bottom">
|
||||
<div class="wrapper">
|
||||
<div class="top">
|
||||
<span @click="isShow = false">取消</span>
|
||||
<span @click="confirm">确定</span>
|
||||
</div>
|
||||
<div class="address-search">
|
||||
<div class="address-search__wrapper">
|
||||
<image src="./images/search.png" />
|
||||
<input placeholder-style="color: #98A6B6" placeholder="搜索地点" v-model="address" @input="onChange">
|
||||
</div>
|
||||
</div>
|
||||
<scroll-view scroll-y scroll-into-view="address-item1">
|
||||
<div class="address-item" :id="'address-item' + index" v-for="(item, index) in addressList" :key="index" @click="chooseAddress(index)">
|
||||
<div class="left">
|
||||
<h2>{{ item.title }}</h2>
|
||||
<p>{{ item._distance >= 0 ? item._distance + 'm内' : '未知' }} | {{ item.address }}</p>
|
||||
</div>
|
||||
<div class="right" :class="[currIndex === index ? 'active' : '']"></div>
|
||||
</div>
|
||||
</scroll-view>
|
||||
<div class="address-btn" v-if="!isChooseAddress">
|
||||
<span>打卡有效范围</span>
|
||||
<div class="right" @click="isShowScope = true">
|
||||
<i>{{ distance[chooseIndex] }}米</i>
|
||||
<image src="./images/w-right.png" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</u-popup>
|
||||
<u-popup v-model="isShowScope" :closeable="false" :z-index="11111" border-radius="16" mode="bottom">
|
||||
<div class="ActionSheet">
|
||||
<div class="ActionSheet-list">
|
||||
<div
|
||||
@click="chooseDistance(index)"
|
||||
v-for="(item, index) in distance"
|
||||
:key="index"
|
||||
:class="[chooseIndex === index ? 'active' : '']">
|
||||
{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="cancel-btn" @click="isShowScope = false">取消</div>
|
||||
</div>
|
||||
</u-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapActions } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'ChooseAddess',
|
||||
|
||||
appName: '选择打卡点',
|
||||
|
||||
data () {
|
||||
return {
|
||||
latitude: '',
|
||||
longitude: '',
|
||||
isShow: false,
|
||||
address: '',
|
||||
currIndex: 0,
|
||||
chooseIndex: 0,
|
||||
isShowScope: false,
|
||||
map: null,
|
||||
ops: {},
|
||||
lib: null,
|
||||
map: null,
|
||||
latLng: null,
|
||||
distance: ['100', '200', '300', '400', '500'],
|
||||
addressList: [],
|
||||
page: 1,
|
||||
marker: null,
|
||||
timeout: null,
|
||||
isChooseAddress: false
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
map (v) {
|
||||
if (v) {
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user',])
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
if (query.type === 'address') {
|
||||
this.isChooseAddress = true
|
||||
|
||||
uni.setNavigationBarTitle({
|
||||
title: '选择地点'
|
||||
})
|
||||
}
|
||||
|
||||
this.getLocation()
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions(['injectJWeixin']),
|
||||
|
||||
chooseDistance (index) {
|
||||
this.chooseIndex = index
|
||||
this.isShowScope = false
|
||||
},
|
||||
|
||||
getLocation () {
|
||||
this.injectJWeixin(['getLocation']).then(res => {
|
||||
wx.getLocation({
|
||||
type: 'wgs84',
|
||||
success: res => {
|
||||
this.longitude = res.longitude
|
||||
this.latitude = res.latitude
|
||||
},
|
||||
error: res => {
|
||||
console.log(res)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
init () {
|
||||
this.map.setZoom(19)
|
||||
this.addMarker(this.map.getCenter())
|
||||
this.map.on('click', e => {
|
||||
this.addressList = []
|
||||
this.latLng = e.latLng
|
||||
this.isShow = true
|
||||
|
||||
this.addMarker(e.latLng)
|
||||
this.getAddress()
|
||||
})
|
||||
},
|
||||
|
||||
confirm () {
|
||||
const address = this.addressList[this.currIndex]
|
||||
if (this.isChooseAddress) {
|
||||
uni.$emit('filedChange', {
|
||||
...uni.getStorageSync('formConfig'),
|
||||
defaultValue: address.title
|
||||
})
|
||||
} else {
|
||||
uni.$emit('address', {
|
||||
address: address.address,
|
||||
title: address.title,
|
||||
lat: address.location.lat,
|
||||
lng: address.location.lng,
|
||||
distance: this.distance[this.chooseIndex]
|
||||
})
|
||||
}
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
|
||||
chooseAddress (index) {
|
||||
this.addMarker(this.addressList[index].location)
|
||||
this.currIndex = index
|
||||
},
|
||||
|
||||
addMarker (position) {
|
||||
if (this.marker) {
|
||||
this.marker.setMap(null)
|
||||
this.marker = null
|
||||
}
|
||||
this.marker = new this.lib.MultiMarker({
|
||||
id: 'marker-layer',
|
||||
map: this.map,
|
||||
styles: {
|
||||
marker: new this.lib.MarkerStyle({
|
||||
width: 30,
|
||||
height: 45,
|
||||
anchor: { x: 10, y: 30 }
|
||||
}),
|
||||
},
|
||||
geometries: [{
|
||||
id: 'marker',
|
||||
styleId: 'marker',
|
||||
position: position,
|
||||
properties: {
|
||||
title: 'marker'
|
||||
}
|
||||
}]
|
||||
})
|
||||
this.easeTo(position)
|
||||
},
|
||||
|
||||
easeTo (position) {
|
||||
this.map.easeTo({
|
||||
center: position,
|
||||
zoom: 17
|
||||
},
|
||||
{ duration: 500 })
|
||||
},
|
||||
|
||||
onChange () {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout)
|
||||
}
|
||||
this.timeout = setTimeout(() => {
|
||||
this.currIndex = -1
|
||||
new this.lib.service.Suggestion({
|
||||
pageSize: 20
|
||||
}).getSuggestions({
|
||||
keyword: this.address
|
||||
}).then(res => {
|
||||
this.addressList = []
|
||||
if (res.data.length) {
|
||||
this.addressList = res.data
|
||||
}
|
||||
})
|
||||
}, 500)
|
||||
},
|
||||
|
||||
getAddress () {
|
||||
this.currIndex = 0
|
||||
new this.lib.service.Search({
|
||||
pageSize: 20
|
||||
}).explore({
|
||||
center: this.latLng,
|
||||
radius: 2000,
|
||||
orderBy: '_distance'
|
||||
}).then(res => {
|
||||
this.addressList = []
|
||||
if (res.data.length) {
|
||||
this.addressList = res.data
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.Attendance-address {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
|
||||
.ActionSheet {
|
||||
background: #F5F6F6;
|
||||
|
||||
.ActionSheet-list {
|
||||
margin-bottom: 8px;
|
||||
background: #fff;
|
||||
|
||||
div {
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
border-bottom: 1px solid #D8DDE6;
|
||||
|
||||
&.active {
|
||||
color: #1365DD;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
background: #fff;
|
||||
|
||||
&:active {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
line-height: 1;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
scroll-view {
|
||||
height: calc(100% - 308px);
|
||||
padding: 0 32px;
|
||||
|
||||
.address-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 32px 0;
|
||||
border-bottom: 1px solid #EEEEEE;
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.right {
|
||||
flex-shrink: 1;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
border: 4px solid #CCCCCC;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&.active {
|
||||
border: 10px solid #1365DD;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 20px;
|
||||
color: #222222;
|
||||
font-weight: 600;
|
||||
font-size: 34px;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.2;
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100px;
|
||||
padding: 0 32px;
|
||||
|
||||
.address-search__wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 72px;
|
||||
padding: 0 32px;
|
||||
background: #F6F7F9;
|
||||
border-radius: 36px;
|
||||
|
||||
image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
font-size: 26px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
padding: 0 32px;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
font-size: 32px;
|
||||
background: #1365DD;
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 96px;
|
||||
padding: 0 32px;
|
||||
font-size: 32px;
|
||||
color: #999;
|
||||
font-weight: 600;
|
||||
|
||||
span:last-child {
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,189 +0,0 @@
|
||||
<template>
|
||||
<div class="Clipping">
|
||||
<div class="photo-wrapper">
|
||||
<!-- <image mode="widthFix" :src="img" /> -->
|
||||
<kspCropper mode="free" ref="Cropper" :url="img" @ok="onOk"></kspCropper>
|
||||
</div>
|
||||
<div class="photo-footer">
|
||||
<div class="title">
|
||||
<span @click="back">返回</span>
|
||||
<h2>剪裁</h2>
|
||||
<span class="save-btn" @click="save">保存</span>
|
||||
</div>
|
||||
<scroll-view class="photo-bottom" scroll-x >
|
||||
<!-- <div class="clipping-item" @click="currIndex = 0" :class="[currIndex === 0 ? 'active' : '']">
|
||||
<image src="./images/clipping/yuantu.png" />
|
||||
<span>原图</span>
|
||||
</div> -->
|
||||
<div class="clipping-item" @click="currIndex = 1" :class="[currIndex === 1 ? 'active' : '']">
|
||||
<image src="./images/clipping/clipping5.png" />
|
||||
<span>自由缩放</span>
|
||||
</div>
|
||||
<!-- <div class="clipping-item" @click="currIndex = 2" :class="[currIndex === 2 ? 'active' : '']">
|
||||
<image src="./images/clipping/clipping4.png" />
|
||||
<span>正方形</span>
|
||||
</div>
|
||||
<div class="clipping-item" @click="currIndex = 3" :class="[currIndex === 3 ? 'active' : '']">
|
||||
<image src="./images/clipping/clipping3.png" />
|
||||
<span>2:3</span>
|
||||
</div>
|
||||
<div class="clipping-item" @click="currIndex = 4" :class="[currIndex === 4 ? 'active' : '']">
|
||||
<image src="./images/clipping/clipping2.png" />
|
||||
<span>3:2</span>
|
||||
</div>
|
||||
<div class="clipping-item" @click="currIndex = 5" :class="[currIndex === 5 ? 'active' : '']">
|
||||
<image src="./images/clipping/clipping1.png" />
|
||||
<span>3:4</span>
|
||||
</div> -->
|
||||
</scroll-view>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import kspCropper from './components/ksp-cropper.vue'
|
||||
export default {
|
||||
name: 'Clipping',
|
||||
|
||||
appName: '图片剪裁',
|
||||
|
||||
components: {
|
||||
kspCropper
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
img: '',
|
||||
currIndex: 1
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.img = decodeURIComponent(query.url)
|
||||
this.type = query.type
|
||||
},
|
||||
|
||||
methods: {
|
||||
back () {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
|
||||
save () {
|
||||
this.$refs.Cropper.cropAppH5().then(res => {
|
||||
console.log(res)
|
||||
})
|
||||
},
|
||||
|
||||
onOk (e) {
|
||||
uni.$emit('cropper', e.path)
|
||||
|
||||
this.back()
|
||||
},
|
||||
|
||||
rotateAngle () {
|
||||
this.$refs.Cropper.rotateAngle()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.Clipping {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
background: #000;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.photo-footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
background: #FFFFFF;
|
||||
border-radius: 32px 32px 0px 0px;
|
||||
border: 1px solid #DDDDDD;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 96px;
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 32px;
|
||||
z-index: 1;
|
||||
color: #222;
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
left: initial;
|
||||
right: 32px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #333;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.photo-bottom {
|
||||
padding: 48px 48px;
|
||||
font-size: 0;
|
||||
white-space: nowrap;
|
||||
|
||||
.clipping-item {
|
||||
display: inline-block;
|
||||
margin-right: 48px;
|
||||
text-align: center;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
color: #333;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
span {
|
||||
color: #3975C6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: calc(100vh - 312px);
|
||||
|
||||
& > image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,401 +0,0 @@
|
||||
<template>
|
||||
<div class="EditAlbum" v-if="pageShow">
|
||||
<div class="img-item" v-for="(item, index) in list" :key="index" @click="choose(index)">
|
||||
<u-lazy-load class="img" :height="182" :loading-img="$cdn + 'watermark/loading.png'" :image="item.photoUrl" img-mode="scaleToFill"></u-lazy-load>
|
||||
<span class="icon" v-if="!item.checked"></span>
|
||||
<image class="icon" v-else src="./images/img-choose.png" />
|
||||
</div>
|
||||
<span class="empty" v-if="!list.length">该相册暂无可编辑内容</span>
|
||||
<div class="EditAlbum-footer">
|
||||
<div @click="move">移动至</div>
|
||||
<div @click="remove">删除</div>
|
||||
</div>
|
||||
<u-popup v-model="isShow" :closeable="false" border-radius="32" height="70%" mode="bottom">
|
||||
<div class="album">
|
||||
<div class="top">
|
||||
<span @click="isShow = false">取消</span>
|
||||
<span @click="confirm">确定</span>
|
||||
</div>
|
||||
<scroll-view scroll-y class="album-list__wrapper">
|
||||
<div
|
||||
class="item"
|
||||
@click="currIndex = index"
|
||||
v-for="(item, index) in albumList"
|
||||
:key="index"
|
||||
:class="[currIndex === index ? 'active' : '']">
|
||||
<image class="checked" v-if="currIndex === index" src="./images/xuanzhong.png" />
|
||||
<image class="icon" v-if="!item.lastPhotoUrl" src="./images/icon.png" />
|
||||
<image class="img" v-if="item.lastPhotoUrl" :src="item.lastPhotoUrl" mode="aspectFill" />
|
||||
<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 || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</scroll-view>
|
||||
</div>
|
||||
</u-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
appName: '相片编辑',
|
||||
|
||||
data () {
|
||||
return {
|
||||
id: '',
|
||||
isShow: false,
|
||||
list: [],
|
||||
currIndex: 0,
|
||||
albumList: [],
|
||||
pageShow: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
chooseImg () {
|
||||
if (!this.list.length) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return this.list.filter(v => v.checked).map(v => v.id).join(',')
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.$loading()
|
||||
this.id = query.id
|
||||
this.getAlbumList()
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.$http.post(`/api/appalbumphoto/DetailByAlbumID`, null, {
|
||||
params: {
|
||||
albumId: this.id,
|
||||
pageSize: 100000,
|
||||
userId: this.$store.state.user.openId
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.list = res.data.records.map(v => {
|
||||
return {
|
||||
...v,
|
||||
checked: false
|
||||
}
|
||||
})
|
||||
|
||||
this.pageShow = true
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
confirm () {
|
||||
this.$http.post(`/api/appalbumphoto/move?ids=${this.chooseImg}&targetId=${this.albumList[this.currIndex].id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$u.toast('移入成功')
|
||||
this.getAlbumList()
|
||||
this.getList()
|
||||
|
||||
this.isShow = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
remove () {
|
||||
if (!this.chooseImg) {
|
||||
return this.$u.toast('请选择相片')
|
||||
}
|
||||
|
||||
this.$confirm('确定删除这些图片?').then(() => {
|
||||
this.$http.post(`/api/appalbumphoto/delete?ids=${this.chooseImg}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$u.toast('删除成功')
|
||||
this.getAlbumList()
|
||||
this.getList()
|
||||
uni.$emit('update')
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
|
||||
move () {
|
||||
if (!this.chooseImg) {
|
||||
return this.$u.toast('请选择相片')
|
||||
}
|
||||
|
||||
this.isShow = true
|
||||
},
|
||||
|
||||
getAlbumList () {
|
||||
this.$http.post('/api/appalbum/list', null, {
|
||||
parmas: {
|
||||
size: 1000
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.albumList = res.data.records
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
choose (index) {
|
||||
this.$set(this.list[index], 'checked', !this.list[index].checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.EditAlbum {
|
||||
min-height: 100vh;
|
||||
padding: 16px 4px 130px;
|
||||
font-size: 0;
|
||||
box-sizing: border-box;
|
||||
background: #1E1E21;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.empty {
|
||||
position: absolute;
|
||||
top: 160px;
|
||||
left: 50%;
|
||||
color: #8e8e90;
|
||||
font-size: 28px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.album {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.album-list__wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 328px;
|
||||
height: 328px;
|
||||
margin-bottom: 32px;
|
||||
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
background: #EFF5FA;
|
||||
|
||||
&:nth-of-type(2n) {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border: 4px solid #2477F1;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
span {
|
||||
color: #c6c5c4;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
i {
|
||||
padding: 0 3px;
|
||||
color: #fff;
|
||||
font-size: 28px;
|
||||
font-style: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > 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;
|
||||
}
|
||||
|
||||
.checked {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scroll-view {
|
||||
height: calc(100% - 96px);
|
||||
padding: 0 32px;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 96px;
|
||||
padding: 0 32px;
|
||||
font-size: 32px;
|
||||
color: #999;
|
||||
font-weight: 600;
|
||||
|
||||
span:last-child {
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.EditAlbum-footer {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
align-items: center;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
text-align: center;
|
||||
background: #343437;
|
||||
box-shadow: inset 0px 1px 0px 0px #666666, inset -1px 0px 0px 0px #666666;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
line-height: 112px;
|
||||
color: #fff;
|
||||
font-size: 36px;
|
||||
|
||||
&:last-child {
|
||||
border-left: 1px solid #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.img-item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 182px;
|
||||
height: 182px;
|
||||
margin-right: 4px;
|
||||
margin-bottom: 4px;
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
z-index: 1;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
content: ' ';
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 182px;
|
||||
height: 182px;
|
||||
}
|
||||
|
||||
span {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border-radius: 16px;
|
||||
border: 3px solid #FFFFFF;
|
||||
}
|
||||
|
||||
&:nth-of-type(4n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,153 +0,0 @@
|
||||
<template>
|
||||
<div class="form">
|
||||
<div class="form-group">
|
||||
<div class="form-item" :class="[config.fieldType === '1' ? 'textarea' : '']">
|
||||
<span>{{ mapFieldLable(config.type) }}</span>
|
||||
<div class="form-item__right" v-if="config.fieldType === '0'">
|
||||
<input :placeholder="'请输入' + mapFieldLable(config.type)" :maxlength="10" v-model="config.defaultValue">
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="form-item__right" v-if="config.fieldType === 'date'" @click="isShowDate = true">
|
||||
<span :style="{color: config.defaultValue ? '#333' : '#999'}">{{ config.defaultValue || '请选择' + mapFieldLable(config.type) }}</span>
|
||||
<u-icon name="arrow-right" color="#E1E2E3" size="#E1E2E3"></u-icon>
|
||||
</div>
|
||||
<div class="form-item__right" v-if="config.fieldType === '1'">
|
||||
<textarea :placeholder="'请输入' + mapFieldLable(config.type)" v-model="config.defaultValue" :maxlength="-1"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-btn" hover-class="text-hover" @click="save">保存</div>
|
||||
<u-picker mode="time" v-model="isShowDate" :params="params" @confirm="onChange"></u-picker>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapFieldLable } from './config'
|
||||
export default {
|
||||
appName: '相册相册',
|
||||
|
||||
data () {
|
||||
return {
|
||||
list: [],
|
||||
mapFieldLable,
|
||||
isShowDate: false,
|
||||
params: {
|
||||
year: true,
|
||||
month: true,
|
||||
day: true
|
||||
},
|
||||
currIndex: 0,
|
||||
config: {
|
||||
type: '',
|
||||
fieldType: '',
|
||||
defaultValue: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onLoad () {
|
||||
this.config = {
|
||||
...this.config,
|
||||
...uni.getStorageSync('formConfig')
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (e) {
|
||||
this.$set(config, 'value', `${e.year}-${e.month}-${e.day}`)
|
||||
},
|
||||
|
||||
save () {
|
||||
uni.$emit('filedChange', this.config)
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form {
|
||||
padding-bottom: 130px;
|
||||
|
||||
* {
|
||||
line-height: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
background: #1365DD;
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
padding: 0 32px;
|
||||
background: #fff;
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 120px;
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
& > span {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
&.textarea {
|
||||
display: block;
|
||||
height: auto;
|
||||
padding: 32px 0;
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.form-item__right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
text-align: right;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
|
||||
span {
|
||||
font-size: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: right;
|
||||
font-size: 30px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,157 +0,0 @@
|
||||
<template>
|
||||
<div class="message">
|
||||
<div class="message-item" v-for="(item, index) in list" :key="index">
|
||||
<h2>{{ item.createTime }}</h2>
|
||||
<div v-if="item.channel !== '0'">{{ item.msg }}</div>
|
||||
<div v-else>
|
||||
<i v-for="(item, index) in item.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>
|
||||
<AiEmpty v-if="!list.length && isMore"></AiEmpty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Message',
|
||||
appName: '工作相册',
|
||||
|
||||
data () {
|
||||
return {
|
||||
size: 15,
|
||||
current: 1,
|
||||
isMore: false,
|
||||
list: []
|
||||
}
|
||||
},
|
||||
|
||||
onLoad () {
|
||||
this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
mapType (type) {
|
||||
return {
|
||||
'0': '照片查看',
|
||||
'1': '照片上传',
|
||||
'2': '打卡统计'
|
||||
}[type]
|
||||
},
|
||||
|
||||
getList () {
|
||||
if (this.isMore) return
|
||||
|
||||
this.$loading()
|
||||
this.$http.post(`/api/sysmessage/list`, null, {
|
||||
params: {
|
||||
size: 10,
|
||||
current: this.current
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
if (this.current > 1) {
|
||||
this.list = [...this.list, ...res.data.records].map(v => {
|
||||
let msg = v.content
|
||||
if (v.channel === '0') {
|
||||
if (v.content.split('$').length === 3) {
|
||||
msg = v.content.split('$').map((v, index) => {
|
||||
if (index === 1) {
|
||||
return {
|
||||
type: 1,
|
||||
value: v.split('=')[1]
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: 0,
|
||||
value: v
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
...v,
|
||||
msg,
|
||||
typeName: this.mapType(v.channel)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.list = res.data.records.map(v => {
|
||||
let msg = v.content
|
||||
if (v.channel === '0') {
|
||||
if (v.content.split('$').length === 3) {
|
||||
msg = v.content.split('$').map((v, index) => {
|
||||
if (index === 1) {
|
||||
return {
|
||||
type: 1,
|
||||
value: v.split('=')[1]
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: 0,
|
||||
value: v
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
...v,
|
||||
msg,
|
||||
typeName: this.mapType(v.channel)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (res.data.records.length < 10) {
|
||||
this.isMore = true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
this.current = this.current + 1
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onReachBottom () {
|
||||
this.getList()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.message {
|
||||
padding-bottom: 60px;
|
||||
|
||||
.message-item {
|
||||
h2 {
|
||||
padding: 48px 0 32px;
|
||||
color: #666666;
|
||||
font-size: 32px;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
i {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
& > div {
|
||||
margin: 0 32px;
|
||||
padding: 32px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.02);
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
line-height: 44px;
|
||||
text-align: justify;
|
||||
border-radius: 16px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,31 +0,0 @@
|
||||
<template>
|
||||
<div class="MovePhoto">
|
||||
<image src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/64f71761d2b04746ad640a43706a92e4~tplv-k3u1fbpfcp-zoom-crop-mark:1304:1304:1304:734.awebp?" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MovePhoto',
|
||||
|
||||
appName: '移动相片',
|
||||
|
||||
data () {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
onLoad () {
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,238 +0,0 @@
|
||||
<template>
|
||||
<div class="PersonnelSetting">
|
||||
<div class="title">
|
||||
<h2>拍摄人</h2>
|
||||
<span>*选择拍摄人后,相册只能上传该拍摄人照片</span>
|
||||
</div>
|
||||
<div class="cell-group">
|
||||
<div class="cell-item" hover-class="bg-hover" @click="userList = [], currIndex = 0">
|
||||
<div class="cell-item__left">
|
||||
<h2>不限</h2>
|
||||
</div>
|
||||
<div class="cell-item__check" :class="[currIndex === 0 ? 'active' : '']"></div>
|
||||
</div>
|
||||
<div class="cell-item" hover-class="bg-hover" @click="toChoose">
|
||||
<div class="cell-item__left">
|
||||
<h2>根据条件选择</h2>
|
||||
</div>
|
||||
<div class="cell-item__check" :class="[currIndex === 1 ? 'active' : '']"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-wrapper" v-if="userList.length">
|
||||
<div class="user" v-for="(item, index) in userList" :key="index">
|
||||
<h2 class="user-left">
|
||||
<AiOpenData v-if="item" type="userName" :openid="item"></AiOpenData>
|
||||
</h2>
|
||||
<image src="./images/remove.png" @click="remove(index)" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="tips">注:如选中人员未展示,可能是未授权该成员应用权限,需要先对这些成员进行应用授权。 </div>
|
||||
<div class="form-btn" hover-class="text-hover" @click="save">保存</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex'
|
||||
export default {
|
||||
name: 'PersonnelSetting',
|
||||
|
||||
appName: '拍摄人选择',
|
||||
|
||||
data () {
|
||||
return {
|
||||
currIndex: 0,
|
||||
userList: [],
|
||||
ticket: '',
|
||||
count: 0
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.getInfo(query.id)
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions(['selectPrivilegedContact']),
|
||||
|
||||
linkTo (url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
|
||||
remove (index) {
|
||||
this.userList.splice(index, 1)
|
||||
},
|
||||
|
||||
save () {
|
||||
if (this.currIndex === 1 && !this.userList.length) {
|
||||
return this.$u.toast('请选择人员')
|
||||
}
|
||||
|
||||
uni.$emit('watermarkChange', {
|
||||
type: 'personnel',
|
||||
value: this.userList.length ? this.userList : []
|
||||
})
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
|
||||
getInfo (id) {
|
||||
this.$http.post(`/api/appalbum/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.userList = res.data.albumUserList || []
|
||||
this.currIndex = (res.data.albumUserList && res.data.albumUserList.length) ? 1 : 0
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toChoose () {
|
||||
this.$loading()
|
||||
this.currIndex = 1
|
||||
this.selectPrivilegedContact({
|
||||
fromDepartmentId: 0,
|
||||
selectedTickets: this.ticket ? [this.ticket] : [],
|
||||
selectedOpenUserIds: this.userList
|
||||
}).then(res => {
|
||||
uni.hideLoading()
|
||||
this.userList = res.userList.map(e => e.openUserId) || []
|
||||
this.ticket = res.selectedTicket || ''
|
||||
|
||||
console.log(res)
|
||||
}).catch(() => {
|
||||
uni.hideLoading()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.PersonnelSetting {
|
||||
padding-bottom: 130px;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.user-wrapper {
|
||||
background: #fff;
|
||||
|
||||
.user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 88px;
|
||||
padding: 0 32px;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
.user-left {
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
background: #1365DD;
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
line-height: 44px;
|
||||
margin: 32px;
|
||||
font-size: 28px;
|
||||
color: #999999;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
padding: 20px 32px;
|
||||
line-height: 1.3;
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
color: #666666;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
margin-left: 16px;
|
||||
color: #999999;
|
||||
font-size: 30px;
|
||||
text-align: justify;
|
||||
}
|
||||
}
|
||||
|
||||
.cell-group {
|
||||
.cell-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 108px;
|
||||
margin-bottom: 16px;
|
||||
padding: 0 32px;
|
||||
background: #FFFFFF;
|
||||
|
||||
&:active {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.cell-item__check {
|
||||
flex-shrink: 1;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
border: 4px solid #CCCCCC;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&.active {
|
||||
border: 10px solid #1365DD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,181 +0,0 @@
|
||||
<template>
|
||||
<div class="photo" v-if="pageShow" @click="isShow = !isShow">
|
||||
<div class="photo-wrapper">
|
||||
<image mode="widthFix" :src="img" />
|
||||
</div>
|
||||
<div class="photo-bottom" :class="[isShow ? 'active' : '']">
|
||||
<div class="top">
|
||||
<h2>查看图片</h2>
|
||||
<p>长按图片进行分享给他人</p>
|
||||
<image @click.stop="isShow = false" src="./images/down_boldw.png" />
|
||||
</div>
|
||||
<div class="btns">
|
||||
<div class="btn-item" hover-class="bg-hover" @click="back">
|
||||
<image src="./images/fanhui-black.png" />
|
||||
<span>返回</span>
|
||||
</div>
|
||||
<div class="btn-item" hover-class="bg-hover" v-if="createUserId === user.openId" @click="remove">
|
||||
<image src="./images/remove-black.png" />
|
||||
<span>删除</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'Photo',
|
||||
|
||||
appName: '相片',
|
||||
|
||||
data () {
|
||||
return {
|
||||
img: '',
|
||||
id: '',
|
||||
isShow: true,
|
||||
pageShow: false,
|
||||
createUserId: ''
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user'])
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.id = query.id
|
||||
this.$loading()
|
||||
this.$http.post(`/api/appalbumphoto/queryDetailById?id=${query.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.img = res.data.photoUrl
|
||||
this.createUserId = res.data.createUserId
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.pageShow = true
|
||||
|
||||
this.isShow = true
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
back () {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
|
||||
remove () {
|
||||
this.$confirm('确定删除该图片?').then(() => {
|
||||
this.$http.post(`/api/appalbumphoto/delete?ids=${this.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$u.toast('删除成功')
|
||||
uni.$emit('update')
|
||||
|
||||
this.back()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.photo {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background: #000;
|
||||
overflow-y: auto;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.photo-bottom {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
transform: translateY(100%);
|
||||
background: #fff;
|
||||
border-radius: 32px 32px 0 0;
|
||||
transition: all ease 0.4s;
|
||||
|
||||
&.active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
height: 96px;
|
||||
|
||||
h2 {
|
||||
font-size: 28px;
|
||||
color: #333333;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
image {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 32px;
|
||||
z-index: 1;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.btns {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 216px;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
|
||||
& > image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<div class="photo-rank">
|
||||
<div class="info-rank">
|
||||
<div class="info-item__title">
|
||||
<h2>成员拍照排名</h2>
|
||||
</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"></AiEmpty>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PhotoRank',
|
||||
|
||||
appName: '拍照排名',
|
||||
|
||||
data () {
|
||||
return {
|
||||
list: []
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.getList(query.date)
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList (date) {
|
||||
this.$http.post(`/api/appattendancerecord/alluserphotosort?queryTime=${date}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.list = Object.keys(res.data).map(v => {
|
||||
return {
|
||||
name: v,
|
||||
num: res.data[v]
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.photo-rank {
|
||||
padding: 32px 0 40px;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.info-rank {
|
||||
margin: 0 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-item__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 108px;
|
||||
|
||||
h2 {
|
||||
font-weight: 600;
|
||||
font-size: 32px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,430 +0,0 @@
|
||||
<template>
|
||||
<div class="photo">
|
||||
<div class="photo-top">
|
||||
<div class="photo-top__middle" @click="isShow = true">
|
||||
<span>保存至:{{ albumName || '默认相册' }}</span>
|
||||
<image src="./images/to-right.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="photo-wrapper">
|
||||
<image mode="widthFix" :src="img" />
|
||||
</div>
|
||||
<div class="photo-footer">
|
||||
<div class="item" @click="back">
|
||||
<image src="./images/fanhui.png" />
|
||||
<span>返回</span>
|
||||
</div>
|
||||
<div class="item" @click="upload">
|
||||
<image src="./images/shangchuan.png" />
|
||||
<span>上传</span>
|
||||
</div>
|
||||
</div>
|
||||
<u-popup v-model="isShow" :closeable="false" border-radius="32" height="70%" mode="bottom">
|
||||
<div class="album">
|
||||
<div class="top">
|
||||
<span @click="isShow = false">取消</span>
|
||||
<span @click="onConfirm">确定</span>
|
||||
</div>
|
||||
<scroll-view scroll-y class="album-list__wrapper">
|
||||
<div
|
||||
class="item"
|
||||
@click="currIndex = index"
|
||||
v-for="(item, index) in albumList"
|
||||
:key="index"
|
||||
:class="[currIndex === index ? 'active' : '']">
|
||||
<image class="checked" v-if="currIndex === index" src="./images/xuanzhong.png" />
|
||||
<image class="icon" v-if="!item.lastPhotoUrl" src="./images/icon.png" />
|
||||
<image class="img" v-if="item.lastPhotoUrl" :src="item.lastPhotoUrl" mode="aspectFill" />
|
||||
<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 || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</scroll-view>
|
||||
</div>
|
||||
</u-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Photo',
|
||||
|
||||
appName: '拼图汇报',
|
||||
|
||||
data () {
|
||||
return {
|
||||
img: '',
|
||||
type: '',
|
||||
albumList: [],
|
||||
albumName: '',
|
||||
albumId: '',
|
||||
templateId: '',
|
||||
isShow: false,
|
||||
currIndex: 0,
|
||||
fileId: ''
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
defaultValue () {
|
||||
if (!this.albumList.length) {
|
||||
return [0]
|
||||
}
|
||||
|
||||
return [this.albumList.map(v => v.value).indexOf(this.albumId)]
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.img = query.img
|
||||
this.type = query.type
|
||||
this.templateId = query.templateId
|
||||
this.albumId = query.albumId
|
||||
this.fileId = query.fileId
|
||||
|
||||
this.getWatermarkList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
back () {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
|
||||
upload () {
|
||||
this.$loading()
|
||||
this.$http.post('/api/appalbumphoto/addOrUpdate', {
|
||||
albumId: this.albumId,
|
||||
photoUrl: this.img,
|
||||
watermarkType: this.type,
|
||||
fileId: this.fileId,
|
||||
templateId: this.templateId
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$u.toast('新增成功')
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: './AppCountryAlbum'
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
|
||||
uni.hideLoading()
|
||||
})
|
||||
},
|
||||
|
||||
onConfirm () {
|
||||
this.albumId = this.albumList[this.currIndex].value
|
||||
this.albumName = this.albumList[this.currIndex].label
|
||||
|
||||
this.isShow = false
|
||||
},
|
||||
|
||||
getWatermarkList () {
|
||||
this.$http.post('/api/appalbum/list', null, {
|
||||
parmas: {
|
||||
size: 1000
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.albumList = res.data.records.map(v => {
|
||||
return {
|
||||
...v,
|
||||
label: v.albumName,
|
||||
value: v.id
|
||||
}
|
||||
})
|
||||
|
||||
if (this.albumId) {
|
||||
this.albumName = this.albumList.filter((v, index) => {
|
||||
if (v.value === this.albumId) {
|
||||
this.currIndex = index
|
||||
}
|
||||
return v.value === this.albumId
|
||||
})[0].label
|
||||
} else {
|
||||
this.albumName = this.albumList[0].label
|
||||
this.albumId = this.albumList[0].value
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.photo {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
background: #000;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.album {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.album-list__wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 328px;
|
||||
height: 328px;
|
||||
margin-bottom: 32px;
|
||||
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
background: #EFF5FA;
|
||||
|
||||
&:nth-of-type(2n) {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border: 4px solid #2477F1;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
span {
|
||||
color: #c6c5c4;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
i {
|
||||
padding: 0 3px;
|
||||
color: #fff;
|
||||
font-size: 28px;
|
||||
font-style: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > 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;
|
||||
}
|
||||
|
||||
.checked {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scroll-view {
|
||||
height: calc(100% - 96px);
|
||||
padding: 0 32px;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 96px;
|
||||
padding: 0 32px;
|
||||
font-size: 32px;
|
||||
color: #999;
|
||||
font-weight: 600;
|
||||
|
||||
span:last-child {
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
padding-bottom: 216px;
|
||||
|
||||
& > image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.photo-top {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
height: 128px;
|
||||
padding: 0 32px;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
|
||||
& > image {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
& > span {
|
||||
color: #cbcbcb;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.photo-top__middle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 400px;
|
||||
height: 72px;
|
||||
line-height: 1;
|
||||
background: #0B111F;
|
||||
border-radius: 40px;
|
||||
font-size: 28px;
|
||||
color: #cbcbcb;
|
||||
|
||||
span {
|
||||
max-width: 70%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-footer {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
align-items: center;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 216px;
|
||||
background: #1E1E21;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
|
||||
image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 28px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > image {
|
||||
width: 100%;
|
||||
min-height: calc(100% - 216px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,147 +0,0 @@
|
||||
<template>
|
||||
<div class="SourceSetting">
|
||||
<div class="title">照片来源</div>
|
||||
<div class="cell-group">
|
||||
<div class="cell-item" hover-class="bg-hover" @click="currIndex = 0">
|
||||
<div class="cell-item__left">
|
||||
<h2>不限</h2>
|
||||
</div>
|
||||
<div class="cell-item__check" :class="[currIndex === 0 ? 'active' : '']"></div>
|
||||
</div>
|
||||
<div class="cell-item" hover-class="bg-hover" @click="currIndex = 1">
|
||||
<div class="cell-item__left">
|
||||
<h2>仅限工作相册拍摄</h2>
|
||||
</div>
|
||||
<div class="cell-item__check" :class="[currIndex === 1 ? 'active' : '']"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tips">
|
||||
选择不限后:
|
||||
1. 成员可以同步手机原相机、数码相机等拍摄的照片和视频;
|
||||
2. 仅工作相册拍摄的照片或者视频会计入考勤,保证考勤统计真实性。
|
||||
</div>
|
||||
<div class="form-btn" hover-class="text-hover" @click="save">保存</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SourceSetting',
|
||||
|
||||
appName: '来源设置',
|
||||
|
||||
data () {
|
||||
return {
|
||||
currIndex: 0
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.currIndex = Number(query.value)
|
||||
},
|
||||
|
||||
methods: {
|
||||
save () {
|
||||
uni.$emit('watermarkChange', {
|
||||
type: 'photoSource',
|
||||
value: this.currIndex
|
||||
})
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.SourceSetting {
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
.form-btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
background: #1365DD;
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
line-height: 44px;
|
||||
margin: 32px;
|
||||
font-size: 28px;
|
||||
color: #999999;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 96px;
|
||||
line-height: 96px;
|
||||
padding: 0 32px;
|
||||
color: #666666;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.cell-group {
|
||||
.cell-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 108px;
|
||||
margin-bottom: 16px;
|
||||
padding: 0 32px;
|
||||
background: #FFFFFF;
|
||||
|
||||
&:active {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.cell-item__check {
|
||||
flex-shrink: 1;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
border: 4px solid #CCCCCC;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&.active {
|
||||
border: 10px solid #1365DD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,904 +0,0 @@
|
||||
<template>
|
||||
<div class="photo" :class="[isHide ? 'home-active' : '']" @click="isHide = true" :style="{height: height + 'px'}">
|
||||
<div class="photo-top" data-html2canvas-ignore>
|
||||
<div class="photo-top__middle" @click="isShowAlbum = true">
|
||||
<span>保存至:{{ albumName || '系统相册' }}</span>
|
||||
<image src="./images/to-right.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="photo-wrapper">
|
||||
<div ref="waterMarker" class="waterMarker-wrapper" :style="{height: canvasHeight + 'px'}">
|
||||
<img class="waterMarker-img" :src="img" mode="widthFix" @load="onImgLoad" />
|
||||
<div
|
||||
class="watermark"
|
||||
v-if="currIndex > -1 && currWatermarkConfig.length"
|
||||
:style="{left: x + 'px', top: y + 'px', transform: 'scale(' + watermarkScale + ')', transformOrigin: 'left' }"
|
||||
@touchstart="onTouchstart"
|
||||
@touchmove="onTouchmove">
|
||||
<component ref="WatermarkItem" :addressInfo="address" :is="'Watermark' + (currIndex + 1)" :config="currWatermarkConfig"></component>
|
||||
<div v-if="!isHide" @click.stop="currIndex = -1" class="watermark-close" data-html2canvas-ignore>
|
||||
<image src="./images/close-b.png" />
|
||||
</div>
|
||||
<span v-if="!isHide" class="watermark-edit" @click.stop="toEdit" data-html2canvas-ignore>编辑</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="photo-bottom" data-html2canvas-ignore>
|
||||
<div class="photo-bottom__top">
|
||||
<span @click.stop="isHide = true">取消</span>
|
||||
<h2>水印</h2>
|
||||
<span @click.stop="isHide = true">确定</span>
|
||||
</div>
|
||||
<div class="waterlist">
|
||||
<div
|
||||
class="water-item"
|
||||
:class="[currIndex === -1 ? 'active' : '']"
|
||||
key="-1"
|
||||
@click.stop="currIndex = -1">
|
||||
<image src="./images/clear.png" />
|
||||
<image class="checked" v-if="currIndex === -1" src="./images/xuanzhong.png" />
|
||||
<div class="water-item__bottom">不使用水印</div>
|
||||
</div>
|
||||
<div
|
||||
class="water-item"
|
||||
:class="[currIndex === index ? 'active' : '']"
|
||||
v-for="(item, index) in watermarkList"
|
||||
:key="item.id"
|
||||
@click.stop="currIndex = index">
|
||||
<image :src="item.thum" />
|
||||
<span v-show="currIndex === index" @click.stop="toEdit">编辑</span>
|
||||
<image class="checked" v-if="currIndex === index" src="./images/xuanzhong.png" />
|
||||
<div class="water-item__bottom">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="photo-tabbar" data-html2canvas-ignore>
|
||||
<h2>编辑图片</h2>
|
||||
<div class="tabbar-wrapper">
|
||||
<div class="item" @click.stop="back">
|
||||
<image src="./images/fanhui-black.png" />
|
||||
<div>返回</div>
|
||||
</div>
|
||||
<div class="item" @click.stop="isHide = false">
|
||||
<image src="./images/shuiyin-white.png" />
|
||||
<div>水印</div>
|
||||
</div>
|
||||
<div class="item" @click.stop="toClipping">
|
||||
<image src="./images/jiancai.png" />
|
||||
<div>剪裁</div>
|
||||
</div>
|
||||
<div class="item" @click.stop="save">
|
||||
<image src="./images/shangchuan-black.png" />
|
||||
<div>上传</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<u-popup v-model="isShowAlbum" :closeable="false" border-radius="32" height="70%" mode="bottom">
|
||||
<div class="album">
|
||||
<div class="top">
|
||||
<span @click="isShowAlbum = false">取消</span>
|
||||
<span @click="onConfirm">确定</span>
|
||||
</div>
|
||||
<scroll-view scroll-y class="album-list__wrapper">
|
||||
<div
|
||||
class="item"
|
||||
@click="albumIndex = index"
|
||||
v-for="(item, index) in albumList"
|
||||
:key="index"
|
||||
:class="[albumIndex === index ? 'active' : '']">
|
||||
<image class="checked" v-if="albumIndex === index" src="./images/xuanzhong.png" />
|
||||
<image class="icon" v-if="!item.lastPhotoUrl" src="./images/icon.png" />
|
||||
<image class="img" v-if="item.lastPhotoUrl" :src="item.lastPhotoUrl" mode="aspectFill" />
|
||||
<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 || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</scroll-view>
|
||||
</div>
|
||||
</u-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import html2canvas from 'html2canvas'
|
||||
import Watermark1 from './components/watermark/Watermark1'
|
||||
import Watermark2 from './components/watermark/Watermark2'
|
||||
import Watermark3 from './components/watermark/Watermark3'
|
||||
import Watermark4 from './components/watermark/Watermark4'
|
||||
import Watermark5 from './components/watermark/Watermark5'
|
||||
import Watermark6 from './components/watermark/Watermark6'
|
||||
import Watermark7 from './components/watermark/Watermark7'
|
||||
import Watermark8 from './components/watermark/Watermark8'
|
||||
import { mapActions, mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'Watermark',
|
||||
|
||||
appName: '水印相机',
|
||||
|
||||
components: {
|
||||
Watermark1,
|
||||
Watermark2,
|
||||
Watermark3,
|
||||
Watermark4,
|
||||
Watermark5,
|
||||
Watermark6,
|
||||
Watermark7,
|
||||
Watermark8
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
img: '',
|
||||
currIndex: 0,
|
||||
isHide: true,
|
||||
height: '100%',
|
||||
waterSrc: '',
|
||||
albumId: '',
|
||||
albumName: '',
|
||||
albumIndex: 0,
|
||||
watermarkList: [],
|
||||
isShowAlbum: false,
|
||||
albumList: [],
|
||||
address: {},
|
||||
x: 32,
|
||||
y: 24,
|
||||
startX: 0,
|
||||
watermarkScale: 1,
|
||||
startY: 0,
|
||||
canvasHeight: 0
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
defaultValue () {
|
||||
if (!this.albumList.length) {
|
||||
return [0]
|
||||
}
|
||||
|
||||
return [this.albumList.map(v => v.value).indexOf(this.albumId)]
|
||||
},
|
||||
|
||||
currWatermarkConfig () {
|
||||
if (this.currIndex < 0 || !this.watermarkList.length) return []
|
||||
|
||||
return this.watermarkList[this.currIndex].itemList
|
||||
},
|
||||
...mapState(['wxwork'])
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
if (query.albumId) {
|
||||
this.albumId = query.albumId
|
||||
}
|
||||
|
||||
this.img = decodeURIComponent(query.url)
|
||||
this.height = uni.getSystemInfoSync().windowHeight
|
||||
|
||||
this.getLocation()
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getWatermarkList()
|
||||
})
|
||||
uni.$on('cropper', e => {
|
||||
this.img = e
|
||||
this.x = 32
|
||||
this.y = 200
|
||||
})
|
||||
},
|
||||
|
||||
mounted () {
|
||||
// this.$nextTick(() => {
|
||||
// document.body.addEventListener('touchmove', this.bindEvent, { passive: false })
|
||||
// })
|
||||
},
|
||||
|
||||
onUnload () {
|
||||
uni.$off('cropper')
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions(['injectJWeixin', 'agentSign']),
|
||||
|
||||
toClipping () {
|
||||
uni.navigateTo({
|
||||
url: `./Clipping?url=${encodeURIComponent(this.img)}`
|
||||
})
|
||||
},
|
||||
|
||||
bindEvent (e) {
|
||||
e.preventDefault()
|
||||
},
|
||||
|
||||
onImgLoad () {
|
||||
const img = document.querySelector('.waterMarker-img')
|
||||
|
||||
this.canvasHeight = img.clientHeight
|
||||
this.watermarkScale = img.clientWidth / uni.getSystemInfoSync().windowWidth
|
||||
},
|
||||
|
||||
onTouchstart (e) {
|
||||
const isMobile = e.type !== 'mousemove'
|
||||
const watermark = document.querySelector('.watermark')
|
||||
if (isMobile) {
|
||||
this.startX = e.touches[0].clientX - Number((watermark.style.left).replace('px', ''))
|
||||
this.startY = e.touches[0].clientY - Number((watermark.style.top).replace('px', ''))
|
||||
} else {
|
||||
this.startX = e.clientX - Number((watermark.style.left).replace('px', ''))
|
||||
this.startY = e.clientY -Number((watermark.style.top).replace('px', ''))
|
||||
}
|
||||
},
|
||||
|
||||
onTouchmove (e) {
|
||||
const isMobile = e.type !== 'mousemove'
|
||||
if (isMobile) {
|
||||
this.x = e.touches[0].clientX - this.startX
|
||||
this.y = e.touches[0].clientY - this.startY
|
||||
} else {
|
||||
this.x = e.clientX - this.startX
|
||||
this.y = e.clientY - this.startY
|
||||
}
|
||||
},
|
||||
|
||||
toEdit () {
|
||||
this.$refs.WatermarkItem.linkTo('./WatermarkConfig')
|
||||
},
|
||||
|
||||
save () {
|
||||
this.$loading()
|
||||
this.isHide = true
|
||||
this.$nextTick(() => {
|
||||
html2canvas(this.$refs.waterMarker, {
|
||||
allowTaint: true,
|
||||
useCORS: true
|
||||
}).then((canvas) => {
|
||||
let dataURL = canvas.toDataURL('image/png')
|
||||
const file = this.dataURLtoFile(dataURL, 'photo.png')
|
||||
let formData = new FormData()
|
||||
formData.append('file', file)
|
||||
this.$http.post('/admin/file/add2?type=image', formData).then(res => {
|
||||
if (res.code === 0) {
|
||||
let info = {}
|
||||
if (this.currIndex > -1) {
|
||||
info = this.watermarkList[this.currIndex]
|
||||
}
|
||||
this.$http.post('/api/appalbumphoto/addOrUpdate', {
|
||||
albumId: this.albumId,
|
||||
photoUrl: res.data.url,
|
||||
fileId: res.data.id,
|
||||
watermarkType: this.currIndex > -1 ? info.watermarkType : '',
|
||||
templateId: this.currIndex > -1 ? info.id : ''
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
uni.$emit('update')
|
||||
this.$u.toast('新增成功')
|
||||
|
||||
setTimeout(() => {
|
||||
this.back()
|
||||
}, 500)
|
||||
} else {
|
||||
this.$u.toast(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
getWeather (code) {
|
||||
this.$http.post(`/api/bdweather/wdata?districtId=${code}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
const data = res.data.result.now
|
||||
|
||||
uni.setStorageSync('address', {
|
||||
...uni.getStorageSync('address'),
|
||||
weather: `${data.text} ${data.temp}°` || ''
|
||||
})
|
||||
|
||||
this.address = {
|
||||
...uni.getStorageSync('address'),
|
||||
weather: `${data.text} ${data.temp}°` || ''
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getLocation () {
|
||||
this.agentSign({
|
||||
corpId: this.wxwork.config.corpId,
|
||||
suiteId: this.wxwork.config.suiteId
|
||||
}).then(() => {
|
||||
this.injectJWeixin(['getLocation']).then(() => {
|
||||
wx.getLocation({
|
||||
type: 'wgs84',
|
||||
success: res => {
|
||||
var lat = res.latitude
|
||||
var lng = res.longitude
|
||||
this.$http.post('/api/appdvcpconfig/apiForward', `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=3RZBZ-LZUCF-CT6J5-NWKZH-FCWOQ-UUFKY&get_poi=1`).then(res => {
|
||||
if (res.code === 0) {
|
||||
const data = res.data.result
|
||||
uni.setStorageSync('address', {
|
||||
lat,
|
||||
lng,
|
||||
address: data.address,
|
||||
cityCode: `${data.ad_info.adcode}`
|
||||
})
|
||||
|
||||
this.address = {
|
||||
...uni.getStorageSync('address')
|
||||
}
|
||||
|
||||
this.getWeather(`${data.ad_info.adcode}`)
|
||||
}
|
||||
})
|
||||
},
|
||||
error: res => {
|
||||
console.log(res)
|
||||
}
|
||||
})
|
||||
}).catch(e => {
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
dataURLtoFile (dataurl, filename) {
|
||||
let arr = dataurl.split(',')
|
||||
let mime = arr[0].match(/:(.*?);/)[1]
|
||||
let bstr = atob(arr[1])
|
||||
let n = bstr.length
|
||||
let u8arr = new Uint8Array(n)
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n)
|
||||
}
|
||||
return new File([u8arr], filename, { type: mime })
|
||||
},
|
||||
|
||||
onConfirm () {
|
||||
this.albumId = this.albumList[this.albumIndex].value
|
||||
this.albumName = this.albumList[this.albumIndex].label
|
||||
|
||||
this.isShowAlbum = false
|
||||
},
|
||||
|
||||
getWatermarkList () {
|
||||
this.$http.post(`/api/appalbumtemplate/list?size=100&templateType=0`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.watermarkList = res.data.records
|
||||
}
|
||||
})
|
||||
|
||||
this.$http.post('/api/appalbum/list', null, {
|
||||
params: {
|
||||
size: 1000
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.albumList = res.data.records.map(v => {
|
||||
return {
|
||||
...v,
|
||||
label: v.albumName,
|
||||
value: v.id
|
||||
}
|
||||
})
|
||||
|
||||
this.albumList.some((v, index) => {
|
||||
if (this.albumId) {
|
||||
if (v.value === this.albumId) {
|
||||
this.albumIndex = index
|
||||
this.albumName = v.label
|
||||
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if (v.label === '系统相册') {
|
||||
this.albumIndex = index
|
||||
this.albumId = v.value
|
||||
this.albumName = '系统相册'
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
back () {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.photo {
|
||||
width: 100%;
|
||||
background: #333;
|
||||
overflow: hidden;
|
||||
|
||||
.photo-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 128px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(100vh - 321px - 128px);
|
||||
}
|
||||
|
||||
.newImg {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 11111;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.album {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.album-list__wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 328px;
|
||||
height: 328px;
|
||||
margin-bottom: 32px;
|
||||
box-shadow: 0px 4px 8px 0px rgba(17, 67, 110, 0.1);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
background: #EFF5FA;
|
||||
|
||||
&:nth-of-type(2n) {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border: 4px solid #2477F1;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
span {
|
||||
color: #c6c5c4;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
i {
|
||||
padding: 0 3px;
|
||||
color: #fff;
|
||||
font-size: 28px;
|
||||
font-style: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > 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;
|
||||
}
|
||||
|
||||
.checked {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scroll-view {
|
||||
height: calc(100% - 96px);
|
||||
padding: 0 32px;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 96px;
|
||||
padding: 0 32px;
|
||||
font-size: 32px;
|
||||
color: #999;
|
||||
font-weight: 600;
|
||||
|
||||
span:last-child {
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.waterMarker-wrapper {
|
||||
position: relative;
|
||||
max-height: calc(100vh - 321px - 128px);
|
||||
overflow: hidden;
|
||||
|
||||
.waterMarker-img {
|
||||
max-width: 100%;
|
||||
object-fit: cover;
|
||||
max-height: calc(100vh - 321px - 128px);
|
||||
}
|
||||
|
||||
.watermark {
|
||||
position: absolute;
|
||||
left: 32px;
|
||||
z-index: 11;
|
||||
padding: 8px;
|
||||
color: #FFFFFF;
|
||||
font-size: 28px;
|
||||
border: 2px solid #FFFFFF;
|
||||
|
||||
.watermark-edit {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
width: 80px;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
text-align: center;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
|
||||
border-radius: 24px;
|
||||
color: #222222;
|
||||
font-size: 24px;
|
||||
transform: translate(50%, -50%);
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.watermark-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.photo-tabbar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
height: 321px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 32px 32px 0px 0px;
|
||||
border: 1px solid #DDDDDD;
|
||||
overflow: hidden;
|
||||
|
||||
h2 {
|
||||
width: 750px;
|
||||
height: 96px;
|
||||
line-height: 96px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
& > div {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
|
||||
image {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
div {
|
||||
font-size: 28px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-bottom {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 111;
|
||||
width: 100%;
|
||||
height: 474px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 32px 32px 0px 0px;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
.waterlist {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: calc(100% - 96px);
|
||||
padding: 18px 16px;
|
||||
overflow-y: auto;
|
||||
|
||||
.water-item {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 352px;
|
||||
height: 240px;
|
||||
margin-bottom: 16px;
|
||||
background: #2A3540;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
|
||||
&.active {
|
||||
border: 6px solid #408EF6;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 236px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
z-index: 1;
|
||||
width: 128px;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
border-radius: 8px;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
flex-direction: column;
|
||||
background: #E4E7EB;
|
||||
|
||||
& > image {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.water-item__bottom {
|
||||
position: relative;
|
||||
color: #8A93A4;
|
||||
font-size: 28px;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.checked {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.water-item__bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-size: 28px;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-bottom__top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 96px;
|
||||
padding: 0 32px;
|
||||
|
||||
image {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 28px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 32px;
|
||||
color: #222;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-top {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
height: 128px;
|
||||
padding: 0 32px;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
|
||||
& > image {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
& > span {
|
||||
color: #cbcbcb;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.photo-top__middle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 400px;
|
||||
height: 72px;
|
||||
line-height: 1;
|
||||
background: #0B111F;
|
||||
border-radius: 40px;
|
||||
font-size: 28px;
|
||||
color: #cbcbcb;
|
||||
|
||||
span {
|
||||
max-width: 70%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.home-active {
|
||||
.photo-bottom {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.watermark {
|
||||
border-color: transparent;
|
||||
// bottom: 38px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,212 +0,0 @@
|
||||
<template>
|
||||
<div class="AttendanceFiexdTime">
|
||||
<div class="form-group">
|
||||
<div class="form-group__item" @click.stop="onClick(item.editEnable)" hover-class="bg-hover" v-if="item.fieldType" v-for="(item, index) in config" :key="index">
|
||||
<div class="left">
|
||||
<switch @click.stop="onSwitchClick(item.editEnable)" :color="item.editEnable === '0' ? '#B7DBFD' : '#1088F9'" :checked="item.status === '1'" :disabled="item.editEnable === '0'" @change="e => onChange(e, index)" />
|
||||
</div>
|
||||
<div class="right" @click="toInput(item)" v-if="['6', '7'].indexOf(item.fieldType) === -1">
|
||||
<div class="right-left">
|
||||
<h2>{{ mapFieldLable(item.type) }}</h2>
|
||||
<p :style="{color: item.defaultValue ? '#333' : '#999'}">{{ item.defaultValue || mapType(item.fieldType) }}</p>
|
||||
</div>
|
||||
<u-icon name="arrow-right" color="#E1E2E3" v-if="item.editEnable !== '0'"></u-icon>
|
||||
</div>
|
||||
<picker mode="date" :disabled="item.editEnable === '0'" style="flex: 1;" v-if="item.fieldType === '7'" :value="item.defaultValue" @change="e => onDateChange(e, index)">
|
||||
<div class="right">
|
||||
<div class="right-left">
|
||||
<h2>{{ mapFieldLable(item.type) }}</h2>
|
||||
<p>{{ item.defaultValue || '' }}</p>
|
||||
</div>
|
||||
<u-icon name="arrow-right" color="#E1E2E3" v-if="item.editEnable !== '0'"></u-icon>
|
||||
</div>
|
||||
</picker>
|
||||
<picker mode="time" style="flex: 1;" :disabled="item.editEnable === '0'" v-if="item.fieldType === '6'" :value="item.defaultValue" @change="e => onDateChange(e, index)">
|
||||
<div class="right">
|
||||
<div class="right-left">
|
||||
<h2>{{ mapFieldLable(item.type) }}</h2>
|
||||
<p>{{ item.defaultValue || '' }}</p>
|
||||
</div>
|
||||
<u-icon name="arrow-right" color="#E1E2E3" v-if="item.editEnable !== '0'"></u-icon>
|
||||
</div>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-btn" hover-class="text-hover" @click="save">保存</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapFieldLable } from './config'
|
||||
|
||||
export default {
|
||||
appName: '表单配置',
|
||||
|
||||
data () {
|
||||
return {
|
||||
config: [],
|
||||
mapFieldLable
|
||||
}
|
||||
},
|
||||
|
||||
onLoad () {
|
||||
this.config = uni.getStorageSync('waterConfig')
|
||||
|
||||
uni.$on('filedChange', e => {
|
||||
this.config.forEach((v, index) => {
|
||||
if (v.type === e.type) {
|
||||
this.$set(this.config[index], 'defaultValue', e.defaultValue)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
linkTo (url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
|
||||
mapType (type) {
|
||||
return {
|
||||
'0': '请输入内容',
|
||||
'1': '请输入内容',
|
||||
'2': '请选择天气',
|
||||
'3': '请选择地址',
|
||||
'4': '请选择定位',
|
||||
'5': '请选择经纬度',
|
||||
'6': '请选择时间',
|
||||
'7': '请选择日期'
|
||||
}[type]
|
||||
},
|
||||
|
||||
onDateChange (e, index) {
|
||||
this.$set(this.config[index], 'defaultValue', e.detail.value)
|
||||
},
|
||||
|
||||
onChange (e, index) {
|
||||
this.$set(this.config[index], 'status', e.detail.value ? '1' : '0')
|
||||
},
|
||||
|
||||
onSwitchClick (status) {
|
||||
if (status === '0') {
|
||||
return this.$u.toast('该选项不允许关闭')
|
||||
}
|
||||
},
|
||||
|
||||
onClick (status) {
|
||||
if (status === '0') {
|
||||
return this.$u.toast('该选项不允许修改内容')
|
||||
}
|
||||
},
|
||||
|
||||
toInput (e) {
|
||||
if (e.editEnable === '0') return
|
||||
|
||||
if (e.fieldType === '2') return
|
||||
|
||||
if (e.fieldType === '3') {
|
||||
uni.setStorageSync('formConfig', e)
|
||||
this.linkTo('./ChooseAddess?type=address')
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
uni.setStorageSync('formConfig', e)
|
||||
this.linkTo('./Form')
|
||||
},
|
||||
|
||||
save () {
|
||||
for (let i = 0; i < this.config.length; i ++) {
|
||||
if (['2', '3', '4', '5'].indexOf(this.config[i].fieldType) === -1 && this.config[i].fieldType && !this.config[i].defaultValue && this.config[i].status === '1') {
|
||||
return this.$u.toast(`请输入${this.mapFieldLable(this.config[i].type)}`)
|
||||
}
|
||||
}
|
||||
|
||||
uni.$emit('change', this.config)
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AttendanceFiexdTime {
|
||||
padding-bottom: 130px;
|
||||
|
||||
* {
|
||||
line-height: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
background: #1365DD;
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
padding: 0 32px;
|
||||
background: #fff;
|
||||
|
||||
.form-group__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 32rpx 0;
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
margin-left: 36px;
|
||||
|
||||
.right-left {
|
||||
flex: 1;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.3;
|
||||
font-size: 34px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,236 +0,0 @@
|
||||
<template>
|
||||
<div class="WatermarkSetting" v-if="pageShow">
|
||||
<div class="title">
|
||||
<h2>水印选择</h2>
|
||||
<span>*选择水印后,相册只能上传该水印照片</span>
|
||||
</div>
|
||||
<div class="cell-group">
|
||||
<div class="cell-item" hover-class="bg-hover" @click="currIndex = 0, chooseIndex = -1">
|
||||
<div class="cell-item__left">
|
||||
<h2>不限</h2>
|
||||
</div>
|
||||
<div class="cell-item__check" :class="[currIndex === 0 ? 'active' : '']"></div>
|
||||
</div>
|
||||
<div class="cell-item" hover-class="bg-hover" @click="currIndex = 1">
|
||||
<div class="cell-item__left">
|
||||
<h2>从库中选择水印</h2>
|
||||
</div>
|
||||
<div class="cell-item__check" :class="[currIndex === 1 ? 'active' : '']"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title" v-if="currIndex === 1">
|
||||
<h2>水印库</h2>
|
||||
</div>
|
||||
<div class="watermark-list" v-if="currIndex === 1">
|
||||
<div class="item" @click="chooseIndex = index" v-for="(item, index) in list" :key="index" :class="[chooseIndex === index ? 'active' : '']">
|
||||
<image class="checked" v-if="chooseIndex === index" src="./images/xuanzhong.png" />
|
||||
<image class="watermark" :src="item.thum" mode="scaleToFill" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-btn" hover-class="text-hover" @click="save">保存</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { config } from './config'
|
||||
export default {
|
||||
name: 'WatermarkSetting',
|
||||
|
||||
appName: '水印选择',
|
||||
|
||||
data () {
|
||||
return {
|
||||
currIndex: 0,
|
||||
config,
|
||||
list: [],
|
||||
chooseIndex: -1,
|
||||
id: '',
|
||||
pageShow: false
|
||||
}
|
||||
},
|
||||
|
||||
onLoad (query) {
|
||||
this.id = query.value
|
||||
|
||||
this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.$loading()
|
||||
this.$http.post(`/api/appalbumtemplate/list?size=1000&status=1`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.list = res.data.records
|
||||
}
|
||||
|
||||
if (this.id) {
|
||||
this.chooseIndex = this.list.map(v => v.id).indexOf(this.id)
|
||||
this.currIndex = 1
|
||||
}
|
||||
|
||||
this.pageShow = true
|
||||
|
||||
this.$hideLoading()
|
||||
})
|
||||
},
|
||||
|
||||
save () {
|
||||
uni.$emit('watermarkChange', {
|
||||
type: 'watermark',
|
||||
value: this.chooseIndex > -1 ? this.list[this.chooseIndex].id : ''
|
||||
})
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.WatermarkSetting {
|
||||
padding-bottom: 130px;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.watermark-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16px;
|
||||
width: 352px;
|
||||
height: 240px;
|
||||
border-radius: 8px;
|
||||
font-size: 0;
|
||||
background: #2A3540;
|
||||
|
||||
&.active {
|
||||
border: 4px solid #2477F1;
|
||||
}
|
||||
|
||||
.checked {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.watermark {
|
||||
width: 236px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
&:nth-of-type(2n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
background: #1365DD;
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
line-height: 44px;
|
||||
margin: 32px;
|
||||
font-size: 28px;
|
||||
color: #999999;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 96px;
|
||||
padding: 0 32px;
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
color: #666666;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-left: 16px;
|
||||
color: #999999;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.cell-group {
|
||||
.cell-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 108px;
|
||||
margin-bottom: 16px;
|
||||
padding: 0 32px;
|
||||
background: #FFFFFF;
|
||||
|
||||
&:active {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.cell-item__check {
|
||||
flex-shrink: 1;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
border: 4px solid #CCCCCC;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&.active {
|
||||
border: 10px solid #1365DD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,600 +0,0 @@
|
||||
<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>
|
||||
@@ -1,391 +0,0 @@
|
||||
<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>
|
||||
@@ -1,64 +0,0 @@
|
||||
<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>
|
||||
@@ -1,954 +0,0 @@
|
||||
<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>
|
||||
@@ -1,307 +0,0 @@
|
||||
<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>
|
||||
@@ -1,330 +0,0 @@
|
||||
<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>
|
||||
@@ -1,302 +0,0 @@
|
||||
<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>
|
||||
@@ -1,225 +0,0 @@
|
||||
<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>
|
||||
@@ -1,361 +0,0 @@
|
||||
<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>
|
||||
@@ -1,197 +0,0 @@
|
||||
<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>
|
||||
@@ -1,208 +0,0 @@
|
||||
<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>
|
||||
@@ -1,199 +0,0 @@
|
||||
<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>
|
||||
@@ -1,204 +0,0 @@
|
||||
<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>
|
||||
@@ -1,206 +0,0 @@
|
||||
<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>
|
||||
@@ -1,262 +0,0 @@
|
||||
<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>
|
||||
@@ -1,183 +0,0 @@
|
||||
<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>
|
||||
@@ -1,102 +0,0 @@
|
||||
<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>
|
||||
@@ -1,327 +0,0 @@
|
||||
/*
|
||||
* 农历数据表
|
||||
*
|
||||
* 农历分大小月,大月30天,小月29天,但一年中哪个月为大月,哪个月为小月,是无规律的。
|
||||
* 农历每十年有4个闰年,但哪一年为闰年也是不确定的。
|
||||
* 而闰月中,哪个闰月为大月,哪个为小月也是不确定的。
|
||||
*
|
||||
* 下面共20行,每行10个数据。每个数据代表一年,从阳历1900.1.31日起,为第一个数据年的开始,即阳历1900.1.31=农历0.1.1。
|
||||
* 200个数据可推200年的农历,因此目前最大只能推算到2100年
|
||||
*
|
||||
* 对于每一个数据项,5个十六进制数 = 20个二进制位
|
||||
* 前4位,即0在这一年是闰年时才有意义,它代表这年闰月的大小月,为1则闰大月,为0则闰小月。
|
||||
* 中间12位,即4bd,每位代表一个月,为1则为大月,为0则为小月。
|
||||
* 最后4位,即8,代表这一年的闰月月份,为0则不闰。首4位要与末4位搭配使用。
|
||||
*/
|
||||
const lunarInfo = new Array(
|
||||
0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900年~1909年
|
||||
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910年~1919年
|
||||
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920年~1929年
|
||||
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930年~1939年
|
||||
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940年~1949年
|
||||
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950年~1959年
|
||||
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960年~1969年
|
||||
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, // 1970年~1979年
|
||||
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980年~1989年
|
||||
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, // 1990年~1999年
|
||||
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000年~2009年
|
||||
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010年~2019年
|
||||
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020年~2029年
|
||||
0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030年~2039年
|
||||
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040年~2049年
|
||||
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050年~2059年
|
||||
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060年~2069年
|
||||
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070年~2079年
|
||||
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080年~2089年
|
||||
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090年~2099年
|
||||
0x0d520 // 2100年
|
||||
);
|
||||
|
||||
const minYear = 1900; // 能计算的最小年份
|
||||
const maxYear = 2100; // 能计算的最大年份
|
||||
|
||||
// 阳历每月天数,遇到闰年2月需加1天
|
||||
const solarMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
|
||||
|
||||
// 农历月份别称
|
||||
const monthName = new Array('正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '冬月', '腊月');
|
||||
|
||||
// 二十四节气
|
||||
const solarTerm = new Array(
|
||||
'小寒', '大寒', '立春', '雨水', '惊蛰', '春分',
|
||||
'清明', '谷雨', '立夏', '小满', '芒种', '夏至',
|
||||
'小暑', '大暑', '立秋', '处暑', '白露', '秋分',
|
||||
'寒露', '霜降', '立冬', '小雪', '大雪', '冬至'
|
||||
);
|
||||
|
||||
// 二十节气相关系数
|
||||
const termInfo = new Array(
|
||||
0, 21208, 42467, 63836, 85337, 107014,
|
||||
128867, 150921, 173149, 195551, 218072, 240693,
|
||||
263343, 285989, 308563, 331033, 353350, 375494,
|
||||
397447, 419210, 440795, 462224, 483532, 504758);
|
||||
|
||||
/**
|
||||
* 检查年份是否输入正确
|
||||
* @param year int 年份
|
||||
*/
|
||||
function _checkYear(year) {
|
||||
if (year < minYear) {
|
||||
throw new RangeError('年份不能小于' + minYear + '年');
|
||||
} else if (year > maxYear) {
|
||||
throw new RangeError('年份不能大于' + maxYear + '年');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查月份是否输入正确
|
||||
* @param month int 月份
|
||||
*/
|
||||
function _checkMonth(month) {
|
||||
if (month < 1) {
|
||||
throw new RangeError('月份不能小于1');
|
||||
} else if (month > 12) {
|
||||
throw new RangeError('月份不能大于12');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查日期是否输入正确
|
||||
* @param day int 日期
|
||||
*/
|
||||
function _checkDay(day) {
|
||||
if (day < 1) {
|
||||
throw new RangeError('日期不能小于1');
|
||||
} else if (day > 31) {
|
||||
throw new RangeError('日期不能大于31');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回农历year年中哪个月是闰月,没有闰月返回0
|
||||
* @param year int 年份
|
||||
*/
|
||||
function getLunarLeapMonth(year) {
|
||||
if (_checkYear(year)) {
|
||||
return lunarInfo[year - minYear] & 0xf; // 最后4位,代表这一年的闰月月份,为0则今年没有闰月
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回农历year年闰月的天数(如果没有闰月则返回0)
|
||||
* @param year int 年份
|
||||
*/
|
||||
function getLeapMonthDaysCount(year) {
|
||||
if (getLunarLeapMonth(year)) {
|
||||
return lunarInfo[year - minYear] & 0x10000 ? 30 : 29; // 前4位,即0在这一年是闰年时才有意义,它代表这年闰月的大小月
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回农历year年的总天数
|
||||
* @param year int 年份
|
||||
*/
|
||||
function getLunarYearDaysCount(year) {
|
||||
if (_checkYear(year)) {
|
||||
let sum = 348; // 29天 * 12个月 = 348日
|
||||
for (let i = 0x8000; i > 0x8; i >>= 1) {
|
||||
sum += (lunarInfo[year - minYear] & i ? 1 : 0);
|
||||
}
|
||||
return sum + getLeapMonthDaysCount(year);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回农历year年month月的天数
|
||||
* @param year int 年份
|
||||
* @param month int 月份 1~12
|
||||
*/
|
||||
function getLunarYearMonthDaysCount(year, month) {
|
||||
if (_checkYear(year) && _checkMonth(month)) {
|
||||
return lunarInfo[year - minYear] & (0x10000 >> month) ? 30 : 29;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 农历日期的中文字符串
|
||||
* @param day int 日期
|
||||
*/
|
||||
function getLunarDayString(day) {
|
||||
if (_checkDay(day)) {
|
||||
const nStr1 = new Array('日', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
|
||||
const nStr2 = new Array('初', '十', '廿', '卅');
|
||||
let str = '';
|
||||
switch (day) {
|
||||
case 10:
|
||||
str = '初十';
|
||||
break;
|
||||
case 20:
|
||||
str = '二十';
|
||||
break;
|
||||
case 30:
|
||||
str = '三十';
|
||||
break;
|
||||
default:
|
||||
str = nStr2[Math.floor(day / 10)];
|
||||
str += nStr1[day % 10];
|
||||
break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回某年的第n个节气为几日(从0小寒起算)
|
||||
* @param year int 年份
|
||||
* @param n 节气编号 0~23
|
||||
*/
|
||||
function getLunarTermDay(year, n) {
|
||||
if (_checkYear(year) && n <= 23 && n >= 0) {
|
||||
const sTermInfo = new Array(0, 21208, 42467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758);
|
||||
const offDate = new Date((31556925974.7 * (year - minYear) + sTermInfo[n] * 60000) + Date.UTC(minYear, 0, 6, 2, 5));
|
||||
return offDate.getUTCDate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 阳历日期转农历日期
|
||||
* @param year int 年份
|
||||
* @param month int 月份 1~12
|
||||
* @param day int 日期 1~31
|
||||
*/
|
||||
function solarToLunar(year, month, day) {
|
||||
if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
|
||||
const baseDate = new Date(minYear, 0, 31); // 基础日期1900年1月31日
|
||||
const objDate = new Date(year, month - 1, day); // 目标日期
|
||||
let offset = parseInt((objDate - baseDate) / 86400000); // 偏移天数 60 * 60 * 24 * 1000 = 86400000,1天的毫秒数
|
||||
let temp = 0;
|
||||
let i = 0;
|
||||
|
||||
for (i = minYear; i < maxYear && offset > 0; i++) {
|
||||
temp = getLunarYearDaysCount(i); // 农历year年的总天数
|
||||
if (offset < temp) {
|
||||
break;
|
||||
} else {
|
||||
offset -= temp;
|
||||
}
|
||||
}
|
||||
|
||||
const lunarYear = i; // 农历年份
|
||||
const leap = getLunarLeapMonth(lunarYear); // 当年闰月是哪个月
|
||||
let isLeapMonth = false; // 当前农历月份是否是闰月
|
||||
for (i = 1; i <= 12 && offset > 0; i++) {
|
||||
if (leap > 0 && i == (leap + 1) && !isLeapMonth) {
|
||||
--i;
|
||||
isLeapMonth = true;
|
||||
temp = getLeapMonthDaysCount(lunarYear);
|
||||
} else {
|
||||
isLeapMonth = false;
|
||||
temp = getLunarYearMonthDaysCount(lunarYear, i);
|
||||
}
|
||||
|
||||
if (offset < temp) {
|
||||
break;
|
||||
} else {
|
||||
offset -= temp;
|
||||
}
|
||||
}
|
||||
const lunarMonth = i; // 农历月份
|
||||
const lunarDay = offset + 1; // 农历日期
|
||||
|
||||
let monthStr = '';
|
||||
if (isLeapMonth) {
|
||||
monthStr = '闰' + monthName[lunarMonth - 1];
|
||||
} else {
|
||||
monthStr = monthName[lunarMonth - 1];
|
||||
}
|
||||
|
||||
return {
|
||||
year: lunarYear, // 农历年份
|
||||
month: lunarMonth, // 农历月份
|
||||
day: lunarDay, // 农历日期
|
||||
isLeap: isLeapMonth, // 是否闰月
|
||||
monthStr: monthStr, // 月份字符串
|
||||
dayStr: getLunarDayString(lunarDay) // 日期字符串
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 阳历某个月份天数
|
||||
* @param year int 年份
|
||||
* @param month int 月份 1~12
|
||||
*/
|
||||
function getSolarMonthDaysCount(year, month) {
|
||||
if (_checkYear(year) && _checkMonth(month)) {
|
||||
if (month == 2) {
|
||||
return (((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)) ? 29 : 28);
|
||||
} else {
|
||||
return solarMonth[month - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期是阳历年中的第几天
|
||||
* @param year int 年份
|
||||
* @param month int 月份 1-12
|
||||
* @param day int 日期
|
||||
*/
|
||||
function getSolarDayNumber(year, month, day) {
|
||||
if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
|
||||
const date = new Date(year, month - 1, day);
|
||||
const d = date.getDate(); // 本月第几天
|
||||
const m = month - 1;
|
||||
let sum = d;
|
||||
for (let i = 0; i < m; i++) {
|
||||
sum += solarMonth[i];
|
||||
}
|
||||
|
||||
if (m > 1 && (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
|
||||
sum += 1;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算指定日期是否属于24节气
|
||||
* @param year int 年份
|
||||
* @param month int 月份 1~12
|
||||
* @param day int 日期 1~31
|
||||
*/
|
||||
function getLunar24Days(year, month, day) {
|
||||
if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
|
||||
const baseDate = new Date(1900, 0, 6, 2, 5, 0);
|
||||
let str = false;
|
||||
for (let i = 1; i <= 24; i++) {
|
||||
const num = 525948.76 * (year - 1900) + termInfo[i];
|
||||
const timestamp = baseDate.getTime() + num * 60 * 1000;
|
||||
const newDate = new Date(timestamp);
|
||||
if (getSolarDayNumber(newDate.getFullYear(), newDate.getMonth() + 1, newDate.getDate()) ==
|
||||
getSolarDayNumber(year, month, day)) {
|
||||
str = solarTerm[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getLunarLeapMonth, // 返回农历year年中哪个月是闰月,没有闰月返回0
|
||||
getLeapMonthDaysCount, // 返回农历year年闰月的天数(如果没有闰月则返回0)
|
||||
getLunarYearDaysCount, // 返回农历year年的总天数
|
||||
getLunarYearMonthDaysCount, // 返回农历year年month月的天数
|
||||
getLunarDayString, // 农历日期的中文字符串
|
||||
getLunarTermDay, // 返回某年的第n个节气为第几日
|
||||
getSolarMonthDaysCount, // 获取阳历某个月份有多少天
|
||||
getSolarDayNumber, // 获取指定日期是阳历年中的第几天
|
||||
getLunar24Days, // 计算指定日期是否属于24节气
|
||||
solarToLunar, // 阳历日期转农历日期
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
export const config = [
|
||||
{
|
||||
name: '打卡水印',
|
||||
type: '0',
|
||||
thum: 'https://cdn.cunwuyun.cn/dvcp/h5/watermark/1.png'
|
||||
},
|
||||
{
|
||||
name: '巡查水印',
|
||||
type: '1',
|
||||
thum: 'https://cdn.cunwuyun.cn/dvcp/h5/watermark/3.png'
|
||||
},
|
||||
{
|
||||
name: '时间地点水印',
|
||||
type: '2',
|
||||
thum: 'https://cdn.cunwuyun.cn/dvcp/h5/watermark/2.png'
|
||||
},
|
||||
{
|
||||
name: '标题水印',
|
||||
type: '3',
|
||||
thum: 'https://cdn.cunwuyun.cn/dvcp/h5/watermark/6.png'
|
||||
},
|
||||
{
|
||||
name: '防疫水印',
|
||||
type: '4',
|
||||
thum: 'https://cdn.cunwuyun.cn/dvcp/h5/watermark/4.png'
|
||||
},
|
||||
{
|
||||
name: '网格化水印',
|
||||
type: '5',
|
||||
thum: 'https://cdn.cunwuyun.cn/dvcp/h5/watermark/5.png'
|
||||
},
|
||||
{
|
||||
name: '环境卫生水印',
|
||||
type: '6',
|
||||
thum: 'https://cdn.cunwuyun.cn/dvcp/h5/watermark/7.png'
|
||||
},
|
||||
{
|
||||
name: '日历水印',
|
||||
type: '7',
|
||||
thum: 'https://cdn.cunwuyun.cn/dvcp/h5/watermark/8.png'
|
||||
},
|
||||
// {
|
||||
// name: '自定义水印',
|
||||
// type: '9',
|
||||
// thum: 'https://cdn.cunwuyun.cn/dvcp/h5/watermark/1.png'
|
||||
// }
|
||||
]
|
||||
|
||||
export const mapFieldLable = type => {
|
||||
return {
|
||||
0: '时间',
|
||||
1: '日期',
|
||||
2: '天气',
|
||||
3: '地点',
|
||||
4: '备注',
|
||||
5: '标题',
|
||||
6: '巡检人',
|
||||
7: '巡查事项',
|
||||
8: '工作主题',
|
||||
9: '网格员',
|
||||
10: '网格名称',
|
||||
11: '服务对象',
|
||||
12: '工作纪实',
|
||||
13: '日历',
|
||||
14: '拍摄人',
|
||||
15: '经纬度',
|
||||
16: '自定义文字',
|
||||
17: '大标题',
|
||||
18: '小标题',
|
||||
19: '汇报人',
|
||||
20: '汇报单位',
|
||||
21: '颜色设置',
|
||||
22: '工作单位',
|
||||
23: '巡查地点',
|
||||
24: '巡查人',
|
||||
25: '巡查情况',
|
||||
26: '主持人',
|
||||
27: '记录人',
|
||||
28: '参与人',
|
||||
29: '会议地点',
|
||||
30: '会议主题',
|
||||
31: '会议内容',
|
||||
32: '总结',
|
||||
}[type]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 667 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 288 B |
|
Before Width: | Height: | Size: 290 B |
|
Before Width: | Height: | Size: 288 B |
|
Before Width: | Height: | Size: 291 B |
|
Before Width: | Height: | Size: 543 B |
|
Before Width: | Height: | Size: 531 B |
|
Before Width: | Height: | Size: 685 B |
|
Before Width: | Height: | Size: 480 B |
|
Before Width: | Height: | Size: 267 B |
|
Before Width: | Height: | Size: 293 B |
|
Before Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 796 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 972 B |
|
Before Width: | Height: | Size: 733 B |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1001 B |
|
Before Width: | Height: | Size: 243 B |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 804 B |
|
Before Width: | Height: | Size: 427 B |
|
Before Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 334 B |
|
Before Width: | Height: | Size: 560 B |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 288 B |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 854 B |
|
Before Width: | Height: | Size: 428 B |
|
Before Width: | Height: | Size: 715 B |
|
Before Width: | Height: | Size: 458 B |
|
Before Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 699 B |
|
Before Width: | Height: | Size: 248 B |
|
Before Width: | Height: | Size: 254 B |