调整工程目录

This commit is contained in:
aixianling
2021-12-15 14:37:20 +08:00
parent 76b0abe1ea
commit dd1aef6fb3
107 changed files with 17044 additions and 16746 deletions

View File

@@ -0,0 +1,271 @@
<template>
<div class="meeting">
<AiTopFixed>
<u-grid :col="3" :border="false">
<u-grid-item v-for="(item,index) in grid" :key="index" :custom-style="{padding:'14px 0'}"
@click="handleClick(index)">
<u-icon :name="item.icon" :size="64"></u-icon>
<view class="label">{{ item.label }}</view>
</u-grid-item>
</u-grid>
</AiTopFixed>
<div class="body">
<header>待参加的会议</header>
<template v-if="meetingList.length">
<div class="card" v-for="(item,index) in meetingList" :key="index" @click="handleDetail(item)">
<header>{{ item.title }}</header>
<u-row justify="between">
<div class="time">
<span>{{ item.startTime|format }}</span>
<span>{{ item.startTime|formatDate(0) }}{{
item.startTime|formatDate(1)
}}{{ item.startTime|formatDate(2) }} {{ item.startTime|formatWeek }}</span>
</div>
<div class="arrow"></div>
<div class="time">
<span>{{ item.endTime|format }}</span>
<span>{{ item.endTime|formatDate(0) }}{{ item.endTime|formatDate(1) }}{{
item.endTime|formatDate(2)
}} {{ item.endTime|formatWeek }}</span>
</div>
</u-row>
<u-row class="info">
<span>发起人员</span>
<AiOpenData type="userName" :openid="item.createUserId"/>
</u-row>
<u-gap height="20"></u-gap>
<u-row class="info" style="align-items: start;flex-wrap: nowrap;">
<span style="flex-shrink: 0">会议地点</span>
<span>{{ item.address }}</span>
</u-row>
<div class="tag" :style="{background:'url(' + $cdn + tag(item.joinStatus) + ')'}"></div>
</div>
</template>
<template v-else>
<AiEmpty/>
</template>
</div>
<u-divider bg-color="#F5F5F5" v-if="meetingList.length">已经到底啦</u-divider>
<AiAdd @add="add"/>
</div>
</template>
<script>
import addMeeting from './addMeeting';
import belongToMe from './belongToMe';
import detail from './detail';
import meetingList from './meetingList';
export default {
name: "AppMeetingNotice",
appName: "会议通知",
components: {addMeeting, belongToMe, detail, meetingList},
data() {
return {
meetingList: [],
isList: true,
comp: "",
params: null,
}
},
computed: {
grid() {
return [
{
icon: this.$cdn + "/common/iconlshy.png",
label: "历史会议"
},
{
icon: this.$cdn + "/common/iconwfqd.png",
label: "我发起的"
},
{
icon: this.$cdn + "/common/iconcgx.png",
label: "草稿箱"
}
]
}
},
methods: {
tag(status) {
return {
"0": "common/1wqr.png",
"1": "common/1yqr.png",
"2": "common/1yqj.png",
"3": "common/toDo.png",
}[status]
},
handleDetail({id}) {
uni.navigateTo({
url: "/apps/AppMeetingNotice/detail?id=" + id
})
},
getData() {
this.$http.post("/app/appmeetinginfo/list", null, {
params: {
listType: "1",
meetingStatus: "1|2",
size: 999
}
}).then(res => {
if (res && res.data) {
this.meetingList = res.data.records
}
})
},
handleClick(index) {
let url
if (index == 0 || index == 2) {
url = "/apps/AppMeetingNotice/meetingList?index=" + index
} else if (index == 1) {
url = "/apps/AppMeetingNotice/belongToMe"
}
uni.navigateTo({url})
},
add() {
uni.navigateTo({
url: "/apps/AppMeetingNotice/addMeeting"
})
}
},
onShow() {
document.title = "会议通知";
this.$dict.load("meetingNoticeBefore", "meetingNoticeAfter");
this.getData();
},
filters: {
format(date) {
return date.split(" ")[1].substr(0, 5)
},
formatDate(date, index) {
return date.split(" ")[0].split("-")[index]
},
formatWeek(date) {
return "日一二三四五六".charAt((new Date(date.split(" ")[0]).getDay()))
}
},
}
</script>
<style lang="scss" scoped>
.meeting {
min-height: 100%;
background: #F5F5F5;
padding-bottom: 48px;
.label {
font-size: 28px;
font-weight: 400;
color: #333333;
line-height: 48px;
margin-top: 8px;
}
.body {
box-sizing: border-box;
padding: 40px 32px;
& > header {
font-size: 36px;
font-weight: 600;
color: #333333;
margin-bottom: 38px;
}
.card {
background-color: #FFFFFF;
box-sizing: border-box;
padding: 32px;
border-radius: 8px;
margin-bottom: 32px;
position: relative;
&:last-child {
margin-bottom: 0;
}
& > header {
width: 95%;
font-size: 32px;
font-weight: 600;
color: #333333;
}
.time {
display: flex;
flex-direction: column;
margin: 46px 0;
& > span:first-child {
font-size: 60px;
font-weight: 600;
color: #333333;
line-height: 84px;
}
& > span:last-child {
font-size: 22px;
color: #333333;
}
}
.arrow {
width: 28px;
height: 68px;
overflow: hidden;
position: relative;
transform: rotate(180deg);
&:before, &:after {
content: "";
width: 50px;
height: 50px;
position: absolute;
transform: scaleY(1.3) translate(30%, -40px) rotate(45deg);
}
&:before {
top: 59px;
background-color: #CCCCCC;
}
&:after {
left: 7px;
top: 59px;
background-color: #FFFFFF;
}
}
.info {
& > span:first-child {
font-size: 30px;
color: #999999;
}
& > span:last-child {
font-size: 30px;
color: #343D65;
}
}
.tag {
width: 112px;
height: 112px;
background-repeat: no-repeat !important;
background-size: 100% 100% !important;
position: absolute;
top: 0;
right: 0;
}
}
}
::v-deep .content {
padding: 0 !important;
}
}
</style>

View File

@@ -0,0 +1,428 @@
<template>
<div class="add-meeting">
<div v-if="!userSelect">
<div class="card">
<header><em>*</em>会议标题</header>
<input v-model="form.title" placeholder="请输入" :maxlength="30">
</div>
<div class="card">
<header><em>*</em>起止时间</header>
<u-row justify="between">
<div class="time" @click="pick(0)">
<span>{{ form.startTime.time }}</span>
<span>{{ form.startTime.year }}{{ form.startTime.month }}{{
form.startTime.day
}} {{ form.startTime.weekday }}</span>
</div>
<div class="arrow"></div>
<div class="time" @click="pick(1)">
<span>{{ form.endTime.time }}</span>
<span>{{ form.endTime.year }}{{ form.endTime.month }}{{ form.endTime.day }} {{
form.endTime.weekday
}}</span>
</div>
</u-row>
</div>
<div class="card">
<header><em>*</em>会议地点</header>
<input v-model="form.address" placeholder="请输入" :maxlength="30">
</div>
<div class="card">
<header>会议内容</header>
<textarea v-model="form.content" placeholder="请输入" :maxlength="500"></textarea>
</div>
<div class="card">
<AiUploader :multiple="true" type="file" :limit="9" placeholder="上传附件" @list="fileList"
:def="form.files" action="/admin/file/add2"></AiUploader>
</div>
<div class="card item-wrap">
<u-row justify="between" class="item" @click="handleSelectUser">
<header><em>*</em>参会人</header>
<div class="right">
<template v-if="!form.attendees.length">
<span>请选择</span>
</template>
<template v-else>
已选择<em>{{ form.attendees.map(e => e.name).slice(0, 2).join("、") }}</em><em>{{
form.attendees.length
}}</em>
</template>
<div class="right-arrow"></div>
</div>
</u-row>
</div>
<div class="card item-wrap" style="margin-top: 0">
<u-row justify="between" class="item">
<header>参会提醒</header>
<picker class="right" @change="beforeNoticeChange" :value="form.noticeBefore" range-key="dictName"
:range="$dict.getDict('meetingNoticeBefore')">
<span>{{
form.noticeBefore != null ? $dict.getDict('meetingNoticeBefore')[form.noticeBefore]["dictName"] : "请选择"
}}</span>
<div class="right-arrow"></div>
</picker>
</u-row>
</div>
<div class="card item-wrap" style="margin-top: 0">
<u-row justify="between" class="item">
<header>确认提醒</header>
<picker class="right" @change="afterNoticeChange" :value="form.noticeAfter" range-key="dictName"
:range="$dict.getDict('meetingNoticeAfter')">
<span>{{
form.noticeAfter != null ? $dict.getDict('meetingNoticeAfter')[form.noticeAfter]["dictName"] : "请选择"
}}</span>
<div class="right-arrow"></div>
</picker>
</u-row>
</div>
<div class="footer">
<div @click="add(0)">保存草稿</div>
<div @click="add(1)">发布会议</div>
</div>
</div>
<u-picker mode="time" v-model="show" :params="options" @confirm="confirm"></u-picker>
<AiBack ref="aiBack" v-if="!userSelect"/>
</div>
</template>
<script>
import {mapActions} from "vuex";
export default {
name: "addMeeting",
props: {
params: {
type: [Number, String]
}
},
data() {
const initTime = {
time: "",
year: "",
month: "",
day: "",
weekday: "",
timestamp: "",
}
return {
show: false,
index: 0,
list: [],
form: {
id: null,
title: "",
startTime: {...initTime},
endTime: {...initTime},
address: "",
content: "",
attendees: [],
noticeBefore: 4,
noticeAfter: 0,
files: [],
},
userSelect: false,
clickedUserSelect: false
}
},
onLoad(opt) {
if (opt.id) {
this.form.id = opt.id
this.getDetail()
}
this.$nextTick(() => {
let date = new Date();
this.form.startTime.time = date.getHours()?.toString()?.padStart(2, "0") + ":" + date.getMinutes()?.toString()?.padStart(2, "0")
this.form.startTime.year = date.getFullYear()
this.form.startTime.month = (date.getMonth() + 1)?.toString()?.padStart(2, "0")
this.form.startTime.day = date.getDate()
this.form.startTime.weekday = '日一二三四五六'.charAt(date.getDay())
this.form.endTime = {...this.form.startTime}
})
},
onShow() {
document.title = "新增会议";
this.$dict.load("meetingNoticeBefore", "meetingNoticeAfter");
},
computed: {
options() {
return {
year: true,
month: true,
day: true,
hour: true,
minute: true,
timestamp: true,
}
}
},
methods: {
...mapActions(['selectEnterpriseContact']),
handleSelectUser() {
if (this.clickedUserSelect) return this.$u.toast("正在打开人员选择器")
this.clickedUserSelect = true
this.selectEnterpriseContact({
fromDepartmentId: 0,
type: ["user"],
selectedUserIds: this.form.attendees?.map(e => e.id)
}).then(res => {
this.change(res?.userList || [])
this.clickedUserSelect = false
}).catch(() => {
this.clickedUserSelect = false
})
},
fileList(e) {
this.form.files = e
},
change(e) {
this.form.attendees = e
},
beforeNoticeChange(e) {
this.form.noticeBefore = e.detail.value
},
afterNoticeChange(e) {
this.form.noticeAfter = e.detail.value
},
getDetail() {
this.$http.post("/app/appmeetinginfo/info-id", null, {
params: {
id: this.form.id
}
}).then(res => {
if (res && res.data) {
this.form.title = res.data.title
this.form.address = res.data.address
this.form.content = res.data.content
this.form.attendees = res.data.attendees
this.form.noticeBefore = res.data.noticeBefore
this.form.noticeAfter = res.data.noticeAfter
this.form.files = res.data.files
this.form.startTime.time = res.data.startTime.split(" ")[1].substr(0, 5)
this.form.startTime.year = res.data.startTime.split(" ")[0].split("-")[0]
this.form.startTime.month = res.data.startTime.split(" ")[0].split("-")[1]
this.form.startTime.day = res.data.startTime.split(" ")[0].split("-")[2]
this.form.startTime.weekday = '日一二三四五六'.charAt(new Date(res.data.startTime.split(" ")[0]).getDay())
this.form.startTime.timestamp = new Date(res.data.startTime).getTime()
this.form.endTime.time = res.data.endTime.split(" ")[1].substr(0, 5)
this.form.endTime.year = res.data.endTime.split(" ")[0].split("-")[0]
this.form.endTime.month = res.data.endTime.split(" ")[0].split("-")[1]
this.form.endTime.day = res.data.endTime.split(" ")[0].split("-")[2]
this.form.endTime.weekday = '日一二三四五六'.charAt(new Date(res.data.endTime.split(" ")[0]).getDay())
this.form.endTime.timestamp = new Date(res.data.endTime).getTime()
}
})
},
confirm(e) {
if (new Date().getTime() / 1000 > e.timestamp) return this.$u.toast("选择时间不能小于当前时间")
if (this.index == 0) {
this.form.startTime = {...e}
this.form.startTime.time = e.hour + ":" + (e.minute.length > 1 ? e.minute : ("0" + e.minute))
this.form.startTime.weekday = '日一二三四五六'.charAt(new Date(e.timestamp * 1000).getDay())
} else {
if (this.form.startTime.timestamp >= e.timestamp) {
return this.$u.toast("结束时间不能小于开始时间");
}
this.form.endTime = {...e}
this.form.endTime.time = e.hour + ":" + (e.minute.length > 1 ? e.minute : ("0" + e.minute))
this.form.endTime.weekday = '日一二三四五六'.charAt(new Date(e.timestamp * 1000).getDay())
}
},
add(status) {
if (status == 1) {
if (!this.form.title) return this.$u.toast("请输入会议标题")
if (this.form.startTime.timestamp >= this.form.endTime.timestamp) return this.$u.toast("结束时间不能小于开始时间")
if (!this.form.address) return this.$u.toast("请输入会议地点")
// if (!this.form.content) return this.$u.toast("请输入会议内容")
if (!this.form.attendees.length) return this.$u.toast("请选择参会人")
}
this.$http.post("/app/appmeetinginfo/add-update", {
...this.form,
files: this.form.files.map(e => e.id),
status,
startTime: this.form.startTime.year + "-" + this.form.startTime.month + "-" + this.form.startTime.day + " " + this.form.startTime.time + ":00",
endTime: this.form.endTime.year + "-" + this.form.endTime.month + "-" + this.form.endTime.day + " " + this.form.endTime.time + ":00",
}).then(res => {
if (res.code == 0) {
this.$u.toast(status == 1 ? "发布成功" : "保存成功")
this.$refs["aiBack"].back()
}
})
},
pick(index) {
this.index = index
this.show = true
},
},
}
</script>
<style lang="scss" scoped>
.add-meeting {
min-height: 100%;
background: #F5F5F5;
padding-bottom: 140px;
.card {
background-color: #FFFFFF;
box-sizing: border-box;
padding: 32px;
margin-top: 16px;
header {
font-size: 32px;
font-weight: 400;
color: #333333;
em {
font-style: normal;
font-size: 32px;
color: #FF4466;
margin-right: 8px;
vertical-align: middle;
}
}
input {
margin: 32px 0 16px;
box-sizing: border-box;
padding: 0 16px;
}
textarea {
width: 100%;
height: 160px;
margin: 32px 0 16px;
box-sizing: border-box;
padding: 0 16px;
}
.u-row {
margin-top: 34px;
.time {
display: flex;
flex-direction: column;
& > span:first-child {
font-size: 60px;
font-weight: 600;
color: #333333;
line-height: 84px;
}
& > span:last-child {
font-size: 22px;
color: #333333;
}
}
.arrow {
width: 28px;
height: 68px;
overflow: hidden;
position: relative;
transform: rotate(180deg);
&:before, &:after {
content: "";
width: 50px;
height: 50px;
position: absolute;
transform: scaleY(1.3) translate(30%, -40px) rotate(45deg);
}
&:before {
top: 59px;
background-color: #CCCCCC;
}
&:after {
left: 7px;
top: 59px;
background-color: #FFFFFF;
}
}
}
.item {
height: 112px;
box-shadow: 0px -1px 0px 0px #D8DDE6;
margin-top: 0;
.right {
font-size: 28px;
color: #999999;
display: flex;
align-items: center;
em {
font-style: normal;
color: #1365DD;
}
}
.right-arrow {
width: 16px;
height: 16px;
display: inline-block;
border-top: 5px solid #CCCCCC;
border-right: 5px solid #CCCCCC;
transform: rotate(45deg);
}
}
}
.item-wrap {
padding: 0 32px;
}
.footer {
height: 112px;
width: 100%;
position: fixed;
left: 0;
bottom: 0;
background-color: #FFFFFF;
display: flex;
align-items: center;
& > div {
font-size: 36px;
color: #333333;
}
& > div:first-child {
width: 270px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
& > div:last-child {
width: calc(100% - 270px);
height: 100%;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
background-color: #1365DD;
}
}
}
</style>

View File

@@ -0,0 +1,238 @@
<template>
<div class="belong-to-me">
<AiTopFixed>
<u-tabs :list="tabs" :is-scroll="false" :current="index" bar-width="88" :height="96" @change="change"></u-tabs>
</AiTopFixed>
<div class="body">
<template v-if="list.length">
<div class="card" v-for="(item,index) in list" :key="index" @click="handleClick(item)">
<header>{{ item.title }}</header>
<u-row justify="between">
<div class="time">
<span>{{ item.startTime|formatTime }}</span>
<span>{{ item.startTime|formatDate(0) }}{{
item.startTime|formatDate(1)
}}{{ item.startTime|formatDate(2) }} {{ item.startTime|formatWeek }}</span>
</div>
<div class="arrow"></div>
<div class="time">
<span>{{ item.endTime|formatTime }}</span>
<span>{{ item.endTime|formatDate(0) }}{{ item.endTime|formatDate(1) }}{{ item.endTime|formatDate(2) }} {{
item.endTime|formatWeek
}}</span>
</div>
</u-row>
<u-row class="info">
<span>发起单位</span>
<AiOpenData type="departmentName" :openid="item.unitName"/>
</u-row>
<u-gap height="20"></u-gap>
<u-row class="info">
<span>会议地点</span>
<span>{{ item.address }}</span>
</u-row>
<div class="tag" :style="{background:'url(' + tag(item.status) + ')'}"></div>
</div>
</template>
<template v-else>
<AiEmpty/>
</template>
</div>
<AiBack/>
</div>
</template>
<script>
import {mapActions} from "vuex";
export default {
name: "belongToMe",
data() {
return {
index: 0,
current: 1,
list: [],
status: "加载更多",
}
},
computed: {
tabs() {
return [
{name: "全部"},
{name: "未开始"},
{name: "进行中"},
{name: "已取消"},
{name: "已结束"},
]
}
},
onShow() {
document.title = "我发起的";
},
created() {
this.injectJWeixin(['sendChatMessage']).then(() => {
this.getList()
})
},
onReachBottom() {
this.current++;
this.getList()
},
methods: {
...mapActions(['injectJWeixin']),
tag(status) {
return {
"1": this.$cdn + 'common/1wks.png',
"2": this.$cdn + 'common/1jxz.png',
"3": this.$cdn + 'common/1yqx.png',
"4": this.$cdn + 'common/1yjs.png'
}[status]
},
getList() {
this.$http.post("/app/appmeetinginfo/list", null, {
params: {
listType: 0,
meetingStatus: this.index == 0 ? "-1" : this.index,
size: 10,
current: this.current
}
}).then(res => {
if (res && res.data) {
if (this.current > 1 && this.current > res.data.pages) {
this.status = "已经到底啦"
}
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records
}
})
},
handleClick({id}) {
uni.navigateTo({
url: "/apps/AppMeetingNotice/detail?id=" + id
})
},
change(e) {
this.index = e
this.current = 1
this.getList()
},
},
filters: {
formatTime(date) {
return date.split(" ")[1]?.substr(0, 5)
},
formatDate(date, i) {
return date.split(" ")[0]?.split("-")[i]
},
formatWeek(date) {
return "日一二三四五六".charAt(new Date(date.split(" ")[0]).getDay())
},
}
}
</script>
<style lang="scss" scoped>
.belong-to-me {
min-height: 100%;
background-color: #F5F5F5;
::v-deep .content {
padding: 0 !important;
}
.body {
box-sizing: border-box;
padding: 40px 32px;
.card {
background-color: #FFFFFF;
box-sizing: border-box;
padding: 32px;
border-radius: 8px;
margin-bottom: 32px;
position: relative;
&:last-child {
margin-bottom: 0;
}
& > header {
width: 95%;
font-size: 32px;
font-weight: 600;
color: #333333;
}
.time {
display: flex;
flex-direction: column;
margin: 46px 0;
& > span:first-child {
font-size: 60px;
font-weight: 600;
color: #333333;
line-height: 84px;
}
& > span:last-child {
font-size: 22px;
color: #333333;
}
}
.arrow {
width: 28px;
height: 68px;
overflow: hidden;
position: relative;
transform: rotate(180deg);
&:before, &:after {
content: "";
width: 50px;
height: 50px;
position: absolute;
transform: scaleY(1.3) translate(30%, -40px) rotate(45deg);
}
&:before {
top: 59px;
background-color: #CCCCCC;
}
&:after {
left: 7px;
top: 59px;
background-color: #FFFFFF;
}
}
.info {
flex-wrap: nowrap;
& > span:first-child {
font-size: 30px;
color: #999999;
flex-shrink: 0;
}
& > span:last-child {
font-size: 30px;
color: #343D65;
}
}
.tag {
width: 112px;
height: 112px;
background-repeat: no-repeat;
background-size: 100% 100% !important;
position: absolute;
top: 0;
right: 0;
}
}
}
}
</style>

View File

@@ -0,0 +1,561 @@
<template>
<div class="detail" v-if="pageShow">
<template v-if="!list">
<div class="card">
<header>{{ detail.title }}</header>
<u-gap height="16"></u-gap>
<u-row v-if="detail.createUserId">
<!-- <u-avatar :src="$cdn + 'common/xzh.png'" v-if="false"></u-avatar>-->
<div class="u-avatar__img">
<AiOpenData type="userName" :openid="detail.createUserId"></AiOpenData>
</div>
<span class="user-name">
<AiOpenData type="userName" :openid="detail.createUserId"></AiOpenData>
</span>
</u-row>
<u-gap height="32"></u-gap>
<u-row>
<img :src="$cdn + 'common/meeting.png'" alt="">
<span :style="{color:color(detail.status)}">{{ $dict.getLabel('meetStatus', detail.status) }}</span>
</u-row>
<u-gap height="8"></u-gap>
<u-row>
<img :src="$cdn + 'common/date.png'" alt="">
<span>{{
detail.startTime && detail.startTime.substr(0, 16)
}} {{ detail.endTime && detail.endTime.substr(0, 16) }}</span>
</u-row>
<u-gap height="8"></u-gap>
<u-row style="align-items: start;flex-wrap: nowrap;">
<img :src="$cdn + 'common/location.png'" alt="">
<span>{{ detail.address }}</span>
</u-row>
</div>
<div class="card">
<span>{{ detail.content }}</span>
</div>
<div class="card" v-if="detail.files && detail.files.length">
<div class="label">相关附件</div>
<div class="file" v-for="(item,index) in detail.files" @click="preFile(item)" :key="index">
<u-row justify="between">
<label class="left">
<img :src="$cdn + 'common/appendix.png'" alt="">
<span>{{ item.fileName }}.{{ item.postfix }}</span>
</label>
<span>{{ item.fileSizeStr }}</span>
</u-row>
</div>
</div>
<div class="card item-wrap">
<u-row justify="between">
<span>参会人</span>
<label class="right" @click="list=true">
查看全部<em>{{ detail.attendees && detail.attendees.length }}</em>
<div class="right-arrow"></div>
</label>
</u-row>
</div>
<div class="footer cancel" v-if="detail.status==1 && detail.createUserId == user.id" @click="handleCancel">取消会议
</div>
<template v-else>
<div class="footer" v-if="['1','2'].includes(detail.status) && ['0','3'].includes(detail.joinStatus)">
<div class="leave" @click="updateStatus(0)">
<img :src="$cdn + 'sass/leave.png'" alt="">请假
</div>
<div @click="toDo" class="leave">
<img :src="$cdn + 'sass/toBe.png'" alt="">待定
</div>
<div @click="updateStatus(1)">确认会议</div>
</div>
<!-- <div class="footer" v-if="['1','2'].includes(detail.status) && detail.joinStatus!=0">-->
<!-- <label>{{ detail.joinStatus|transform }}</label>-->
<!-- <img :src="$cdn + tag(detail.joinStatus)" alt="">-->
<!-- </div>-->
</template>
</template>
<template v-else>
<div class="att-list">
<AiTopFixed>
<u-tabs :list="tabs" :current="current" height="96" :is-scroll="false" bar-width="192"
@change="change"></u-tabs>
</AiTopFixed>
<div v-for="(item,index) in detail.attendees && detail.attendees.filter(e=>e.joinStatus==current)" :key="index"
class="att-wrap">
<div class="left">
<u-avatar :src="item.avatar || (($cdn + 'common/xztx.png'))" size="74" mode="square"
style="margin-right: 8px"></u-avatar>
<AiOpenData type="userName" :openid="item.name"></AiOpenData>
</div>
<!-- <img :src="$cdn + 'common/phone.png'" alt="" @click="call(item)">-->
</div>
</div>
</template>
<u-modal v-model="show" title="提示" show-cancel-button content='是否要取消该会议?' @confirm="onConfirm"></u-modal>
<AiBack/>
</div>
</template>
<script>
import {mapActions, mapState} from "vuex";
export default {
name: "detail",
data() {
return {
detail: {},
list: false,
current: 0,
pageShow: false,
show: false,
id: null,
}
},
onLoad(opt) {
this.id = opt.id;
},
computed: {
...mapState(["user"]),
tabs() {
return [
{name: this.count(0) + "人未确认"},
{name: this.count(1) + "人已确认"},
{name: this.count(2) + "人已请假"},
{name: this.count(3) + "人待定"},
]
},
},
methods: {
onConfirm() {
this.$http.post("/app/appmeetinginfo/cancel", null, {
params: {
meetingId: this.id,
}
}).then(res => {
if (res.code == 0) {
this.$u.toast("取消成功");
this.getDetail();
}
})
},
handleCancel() {
this.show = true;
},
toDo() {
this.$http.post("/app/appmeetinginfo/tobeConfirm", null, {
params: {
meetingId: this.id,
}
}).then(res => {
if (res.code == 0) {
this.$u.toast("会议待定");
setTimeout(_ => {
uni.navigateBack();
}, 800)
}
})
},
count(sta) {
return this.detail.attendees ? this.detail.attendees?.filter(e => e.joinStatus == sta)?.length : 0;
},
change(index) {
this.current = index;
this.detail = {};
this.getDetail();
},
call(item) {
if (item.phone) {
uni.makePhoneCall({
phoneNumber: item.phone
});
}
},
...mapActions(['previewFile', 'injectJWeixin']),
preFile(e) {
if ([".jpg", ".png", ".gif"].includes(e.postfix.toLowerCase())) {
uni.previewImage({
current: e.url,
urls: [e.url]
})
} else {
this.previewFile({...e})
}
},
tag(status) {
return {
"1": "common/2confirmed2.png",
"2": "common/2absent2.png"
}[status]
},
updateStatus(status) {
this.$http.post(status == 0 ? "/app/appmeetinginfo/absent" : "/app/appmeetinginfo/confirm", null, {
params: {
meetingId: this.id,
reason: status == 0 ? "" : null
}
}).then(res => {
if (res.code == 0) {
this.$u.toast(status == 0 ? "请假成功" : "确认成功")
this.getDetail()
}
})
},
color(status) {
if (status == 1) {
return "#FF8822"
}
if (status == 2) {
return "#1365DD"
}
if (status == 3) {
return "#FF4466"
}
return "#343D65"
},
getDetail() {
this.$http.post("/app/appmeetinginfo/info-id", null, {
params: {id: this.id}
}).then(res => {
if (res && res.data) {
this.detail = res.data
this.pageShow = true
}
})
}
},
created() {
this.injectJWeixin(['sendChatMessage']).then(() => {
this.getDetail()
})
},
onShow() {
document.title = "会议详情";
this.$dict.load("meetStatus");
wx.hideOptionMenu();
},
filters: {
transform(status) {
if (status == 1) {
return "已确认"
}
if (status == 2) {
return "已请假"
}
}
}
}
</script>
<style lang="scss" scoped>
.detail {
min-height: 100%;
background-color: #F5F5F5;
padding-bottom: 140px;
::v-deep .AiTopFixed {
margin-bottom: 16px;
.content {
padding: 0 !important;
}
}
.att-list {
min-height: 100%;
.att-wrap {
display: flex;
height: 112px;
align-items: center;
justify-content: space-between;
background-color: #ffffff;
box-sizing: border-box;
padding: 0 50px;
border-bottom: 1px solid #E4E5E6;
.left {
display: flex;
align-items: center;
&:after {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 622px;
height: 2px;
background-color: rgba(216, 221, 230, 0.5);
}
.name {
font-size: 30px;
font-weight: 600;
color: #333333;
}
}
& > img {
width: 48px;
height: 48px;
}
}
}
.card {
background-color: #FFFFFF;
margin-bottom: 8px;
box-sizing: border-box;
padding: 16px 32px;
header {
font-size: 40px;
font-weight: 600;
color: #333333;
line-height: 64px;
letter-spacing: 1px;
}
.u-row {
& > div {
border-radius: 50%;
text-align: center;
font-size: 30px;
display: flex;
align-items: center;
justify-content: center;
/*margin-left: 8px;*/
}
& > span {
font-size: 30px;
color: #343D65;
margin-left: 16px;
}
::v-deep .u-avatar__img {
width: 56px;
height: 56px;
vertical-align: middle;
color: #ffffff;
background-color: #2266FF;
font-size: 16px;
}
.user-name {
font-size: 30px;
color: #343D65;
}
img {
width: 48px;
height: 48px;
}
}
& > span {
font-size: 32px;
color: #333333;
line-height: 48px;
letter-spacing: 1px;
display: inline-block;
box-sizing: border-box;
padding: 16px 0;
}
.label {
height: 96px;
font-size: 32px;
color: #333333;
display: flex;
align-items: center;
margin-bottom: 16px;
}
.file {
height: 128px;
background: #FFFFFF;
border-radius: 8px;
border: 1px solid #CCCCCC;
box-sizing: border-box;
padding: 0 16px;
margin-bottom: 32px;
& > .u-row {
height: 100%;
.left {
width: 522px;
display: flex;
align-items: center;
& > img {
width: 96px;
height: 96px;
}
& > span {
font-size: 32px;
color: #333333;
display: inline-block;
line-height: 44px;
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
}
}
& > span {
font-size: 28px;
color: #999999;
}
}
}
.active {
background-color: #F3F6F9;
}
.name {
font-size: 32px;
font-weight: 400;
color: #333333;
}
.wrap {
height: 112px;
display: flex;
align-items: center;
position: relative;
&:after {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 622px;
height: 2px;
background-color: rgba(216, 221, 230, 0.5);
}
& > label {
width: 80px;
height: 80px;
border-radius: 50%;
background-color: #4E8EEE;
font-size: 28px;
font-weight: 600;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.item-wrap {
height: 112px;
padding: 0 32px;
.u-row {
height: 100%;
& > span {
font-size: 32px;
font-weight: 400;
color: #333333;
}
}
.right {
font-size: 28px;
color: #999999;
display: flex;
align-items: center;
em {
font-style: normal;
color: #1365DD;
}
.right-arrow {
width: 16px;
height: 16px;
border-top: 5px solid #CCCCCC;
border-right: 5px solid #CCCCCC;
transform: rotate(45deg);
}
}
}
.footer {
height: 112px;
width: 100%;
position: fixed;
left: 0;
bottom: 0;
background-color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
& > div {
font-size: 28px;
color: #666666;
display: flex;
flex-direction: column;
& > img {
width: 48px;
height: 48px;
}
}
& > div:nth-child(1), & > div:nth-child(2) {
width: 135px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
& > div:last-child {
width: calc(100% - 270px);
height: 100%;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
background-color: #1365DD;
}
& > label {
font-size: 36px;
font-weight: 400;
color: #999999;
}
/*img {*/
/* width: 158px;*/
/* height: 104px;*/
/* position: absolute;*/
/* right: 0;*/
/* top: 0;*/
/*}*/
}
.cancel {
color: #ffffff;
font-size: 36px;
background-color: #005DFF
}
}
</style>

View File

@@ -0,0 +1,226 @@
<template>
<div class="meeting-list">
<div class="card" v-for="(item,index) in list" :key="index" @click="detail(item)">
<header>
<span>{{ item.title }}</span>
<span>
<span v-if="index==2">保存于</span>
{{ item.createTime }}</span>
</header>
<u-row justify="between">
<div class="time">
<span>{{ item.startTime|format }}</span>
<span>{{ item.startTime|formatDate(0) }}{{ item.startTime|formatDate(1) }}{{ item.startTime|formatDate(2) }} {{ item.startTime|formatWeek }}</span>
</div>
<div class="arrow"></div>
<div class="time">
<span>{{ item.endTime|format }}</span>
<span>{{ item.endTime|formatDate(0) }}{{ item.endTime|formatDate(1) }}{{ item.endTime|formatDate(2) }} {{ item.endTime|formatWeek }}</span>
</div>
</u-row>
<u-row class="info">
<span>发起人员</span>
<AiOpenData type="userName" :openid="item.createUserId"/>
</u-row>
<u-gap height="20"></u-gap>
<u-row class="info">
<span>会议地点</span>
<span>{{ item.address }}</span>
</u-row>
<div class="tag" v-if="item.status!=0" :style="{background:'url(' + $cdn + tag(item.status) +')'}"></div>
</div>
<u-loadmore :status="status" v-if="list.length"/>
<AiEmpty v-if="!list.length"></AiEmpty>
<AiBack/>
</div>
</template>
<script>
export default {
name: "meetingList",
props: {
params: {
type: [String, Number, Object],
}
},
data() {
return {
list: [],
current: 1,
index: null,
status: "加载更多",
}
},
onLoad(opt) {
this.index = opt.index
uni.setNavigationBarTitle({
title: opt.index == 0 ? "历史会议" : "草稿箱"
});
this.getData();
},
methods: {
detail({id}) {
let url
if (this.index == 2) {
url = "/apps/AppMeetingNotice/addMeeting?id=" + id
} else {
url = "/apps/AppMeetingNotice/detail?id=" + id
}
uni.navigateTo({url})
},
tag(status) {
return {
"1": 'common/1wks.png',
"2": 'common/1jxz.png',
"3": 'common/1yqx.png',
"4": 'common/1yjs.png'
}[status]
},
getData() {
this.$http.post("/app/appmeetinginfo/list", null, {
params: {
listType: this.index == 0 ? "2" : '0',
meetingStatus: this.index == 0 ? "4" : "0",
size: 10,
current: this.current,
}
}).then(res => {
if (res && res.data) {
if (this.current > 1 && this.current > res.data.pages) {
this.status = "已经到底啦"
}
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records
}
})
},
},
onReachBottom() {
this.current++;
this.getData();
},
filters: {
format(date) {
return date.split(" ")[1].substr(0, 5)
},
formatDate(date, index) {
return date.split(" ")[0].split("-")[index]
},
formatWeek(date) {
return "日一二三四五六".charAt((new Date(date.split(" ")[0]).getDay()))
}
},
}
</script>
<style lang="scss" scoped>
.meeting-list {
min-height: 100%;
background-color: #F5F5F5;
box-sizing: border-box;
padding: 32px;
.card {
background-color: #FFFFFF;
box-sizing: border-box;
padding: 32px;
border-radius: 8px;
margin-bottom: 32px;
position: relative;
&:last-child {
margin-bottom: 0;
}
& > header {
width: 95%;
font-size: 32px;
font-weight: 600;
color: #333333;
display: flex;
flex-direction: column;
& > span:last-child {
font-size: 28px;
font-weight: 400;
color: #999999;
margin-top: 10px;
}
}
.time {
display: flex;
flex-direction: column;
margin: 46px 0;
& > span:first-child {
font-size: 60px;
font-weight: 600;
color: #333333;
line-height: 84px;
}
& > span:last-child {
font-size: 22px;
color: #333333;
}
}
.arrow {
width: 28px;
height: 68px;
overflow: hidden;
position: relative;
transform: rotate(180deg);
&:before, &:after {
content: "";
width: 50px;
height: 50px;
position: absolute;
transform: scaleY(1.3) translate(30%, -40px) rotate(45deg);
}
&:before {
top: 59px;
background-color: #CCCCCC;
}
&:after {
left: 7px;
top: 59px;
background-color: #FFFFFF;
}
}
.info {
flex-wrap: nowrap;
& > span:first-child {
flex-shrink: 0;
font-size: 30px;
color: #999999;
}
& > span:last-child {
font-size: 30px;
color: #343D65;
}
}
.tag {
width: 112px;
height: 112px;
background-repeat: no-repeat !important;
background-size: 100% 100% !important;
position: absolute;
top: 0;
right: 0;
}
}
}
</style>