936 lines
27 KiB
Vue
936 lines
27 KiB
Vue
<template>
|
||
<div class="scheduling">
|
||
<!-- 左侧日程列表 -->
|
||
<a-card class="scheduling-list">
|
||
<!-- 标题 -->
|
||
<template slot="title">
|
||
Scheduling
|
||
<div class="line"></div>
|
||
</template>
|
||
<!-- 标题结束 -->
|
||
<!-- 内容 -->
|
||
<div class="scheduling-list-content">
|
||
<div class="scheduling-list-item" v-for="item of schedulingInfo" :key="item.id">
|
||
<h4 class="title">
|
||
<span>
|
||
{{ item.username }}
|
||
</span>
|
||
<a-popconfirm title="Do You Want To Delete This Item?" placement="bottom" @confirm="onDel(item)">
|
||
<a class="del"></a>
|
||
</a-popconfirm>
|
||
</h4>
|
||
<div class="scheduling-list-item-container" @dragover.prevent @drop="onDrop(item)">
|
||
<!-- 左侧边框 -->
|
||
<div class="left-border">
|
||
<div class="left-top-border">
|
||
<div class="left-top-corner"></div>
|
||
</div>
|
||
<div class="left-bottom-border"></div>
|
||
</div>
|
||
<!-- 左侧边框结束 -->
|
||
<div class="scheduling-list-item-content">
|
||
<template v-for="(station, index) in item.stationList">
|
||
<span
|
||
:key="station.stationId"
|
||
class="draggable"
|
||
draggable
|
||
@dragstart="onDragStart(station, item.userId)"
|
||
>
|
||
{{ station.stationName }}
|
||
</span>
|
||
{{ index == item.stationList.length - 1 ? '' : '、' }}
|
||
</template>
|
||
</div>
|
||
<!-- 右侧边框 -->
|
||
<div class="right-border">
|
||
<div class="right-top-border"></div>
|
||
<div class="right-bottom-border"></div>
|
||
</div>
|
||
<!-- 右侧边框结束 -->
|
||
</div>
|
||
</div>
|
||
<a-empty v-if="!schedulingInfo || !schedulingInfo.length" style="margin-top: 40px;"></a-empty>
|
||
</div>
|
||
<!-- 内容结束 -->
|
||
</a-card>
|
||
<div class="scheduling-calendar">
|
||
<!-- 日历 -->
|
||
<a-calendar v-model="currentDate" @select="onSelectDate">
|
||
<template slot="headerRender">
|
||
<!-- 搜索栏 -->
|
||
<div class="search-form">
|
||
<a-row>
|
||
<a-col :span="6">
|
||
<a-form-model class="search-form-form">
|
||
<a-form-model-item label="Month" style="marign-bottom: 0">
|
||
<a-month-picker v-model="currentMonth" :allow-clear="false"></a-month-picker>
|
||
</a-form-model-item>
|
||
</a-form-model>
|
||
</a-col>
|
||
<a-space class="btn-group">
|
||
<a-button @click="onAdd" type="primary">
|
||
<img src="@/assets/images/global/add.png" alt="" />
|
||
Add
|
||
</a-button>
|
||
<a-button @click="onEdit" type="primary">
|
||
<img src="@/assets/images/global/edit.png" alt="" />
|
||
Edit
|
||
</a-button>
|
||
<a-button type="primary">
|
||
<img src="@/assets/images/global/import.png" alt="" />
|
||
Import
|
||
</a-button>
|
||
<a-button type="primary">
|
||
<img src="@/assets/images/global/export.png" alt="" />
|
||
Export
|
||
</a-button>
|
||
</a-space>
|
||
</a-row>
|
||
</div>
|
||
<!-- 搜索栏结束 -->
|
||
</template>
|
||
<!-- 日历内部内容 -->
|
||
<template slot="dateCellRender" slot-scope="value">
|
||
<div
|
||
class="scheduling-calendar-content"
|
||
v-if="scheduleList[value.format(dateFormat)] && scheduleList[value.format(dateFormat)].length"
|
||
>
|
||
<div class="item" v-for="item in scheduleList[value.format(dateFormat)]" :key="item.id">
|
||
{{ `${item.username}(${item.stationList.length})` }}
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<!-- 日历内部内容 -->
|
||
</a-calendar>
|
||
<!-- 日历结束 -->
|
||
</div>
|
||
|
||
<!-- 增加/编辑排班弹窗 -->
|
||
<custom-modal :title="isAdd ? 'Add' : 'Edit'" :width="845" v-model="visible" :okHandler="submit">
|
||
<a-spin :spinning="isGettingDetail">
|
||
<div class="account-assign">
|
||
<a-transfer
|
||
:selectedKeys="selectedStationKeys"
|
||
:target-keys="targetKeys"
|
||
:render="item => item.title"
|
||
:operations="['Assign', 'Remove']"
|
||
:titles="['Particulate Station', 'Roster personnel']"
|
||
:show-select-all="false"
|
||
@change="onChange"
|
||
@selectChange="handleSelectChange"
|
||
>
|
||
<template slot="children" slot-scope="{ props: { direction, selectedKeys }, on: { itemSelect } }">
|
||
<!-- 左侧穿梭框中的树 -->
|
||
<a-tree
|
||
v-if="direction === 'left'"
|
||
blockNode
|
||
checkable
|
||
checkStrictly
|
||
defaultExpandAll
|
||
:checkedKeys="[...selectedKeys, ...targetKeys]"
|
||
:treeData="treeData"
|
||
@check="
|
||
(_, props) => {
|
||
onChecked(_, props, [...selectedKeys, ...targetKeys], itemSelect)
|
||
}
|
||
"
|
||
@select="
|
||
(_, props) => {
|
||
onChecked(_, props, [...selectedKeys, ...targetKeys], itemSelect)
|
||
}
|
||
"
|
||
/>
|
||
<!-- 右侧穿梭框中的树 -->
|
||
<a-tree
|
||
v-if="direction === 'right'"
|
||
blockNode
|
||
checkStrictly
|
||
defaultExpandAll
|
||
:treeData="accountTreeData"
|
||
:selectedKeys.sync="rightAccountChildSelectedKeys"
|
||
@select="
|
||
(_, props) => {
|
||
onSelectAccount(_, props, itemSelect)
|
||
}
|
||
"
|
||
/>
|
||
</template>
|
||
</a-transfer>
|
||
|
||
<!-- 穿梭框右上方搜索 -->
|
||
<div class="account-search">
|
||
<label>User Name</label>
|
||
<custom-popover-search
|
||
placeholder="Enter User Name"
|
||
:options="accountList"
|
||
:keyword.sync="keyword"
|
||
:remote-method="getAccountList"
|
||
@add="onAddToList"
|
||
></custom-popover-search>
|
||
</div>
|
||
<!-- 穿梭框右上方搜索结束 -->
|
||
</div>
|
||
</a-spin>
|
||
</custom-modal>
|
||
<!-- 增加/编辑排班弹窗结束 -->
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import FormMixin from '@/mixins/FormMixin'
|
||
import moment from 'moment'
|
||
import { cloneDeep } from 'lodash'
|
||
import { getAction } from '@/api/manage'
|
||
import CustomPopoverSearch from '@/components/CustomPopoverSearch'
|
||
import { deleteAction, postAction, putAction } from '../../api/manage'
|
||
|
||
const dateFormat = 'YYYY-MM-DD'
|
||
const monthFormat = 'YYYY-MM'
|
||
export default {
|
||
mixins: [FormMixin],
|
||
components: {
|
||
VNodes: {
|
||
functional: true,
|
||
render: (_, ctx) => ctx.props.vnodes
|
||
},
|
||
CustomPopoverSearch
|
||
},
|
||
data() {
|
||
this.dateFormat = dateFormat
|
||
return {
|
||
currentMonth: moment(), // 当前月份
|
||
|
||
currentDate: moment(), // 当前日期
|
||
schedulingInfo: [], // 当前选中的日程详情,用于 scheduling 左侧展示
|
||
|
||
isGettingList: false,
|
||
scheduleList: [], // 该月的日程列表
|
||
|
||
visible: false, // 新增/编辑弹窗是否显示
|
||
|
||
isGettingDetail: false, // 编辑时正在获取详情
|
||
|
||
originalTreeData: [], // 站点的树状结构
|
||
selectedStationKeys: [], // 穿梭框左侧选中的站点列表
|
||
targetKeys: [],
|
||
|
||
isGettingStationList: false,
|
||
keyword: '', // 穿梭框右上角搜索用户的关键词
|
||
|
||
stationList: [], // 站点列表(原始数据)
|
||
accountList: [], // 搜索出来的用户列表
|
||
|
||
accountTreeData: [], // 用户列表树状结构
|
||
checkedAccount: '', // 右侧穿梭框选中的账号
|
||
rightAccountChildSelectedKeys: [], // 右侧穿梭框选中的值
|
||
|
||
isChanging: false,
|
||
dragItem: null,
|
||
fromUserId: ''
|
||
}
|
||
},
|
||
created() {
|
||
this.getList()
|
||
this.getStationList()
|
||
},
|
||
methods: {
|
||
// 获取该月日程列表
|
||
async getList() {
|
||
try {
|
||
this.isGettingList = true
|
||
const { result } = await getAction(`/sysTask/findList?yearMonth=${this.currentMonth.format('YYYY-MM')}`)
|
||
this.scheduleList = result
|
||
this.schedulingInfo = this.scheduleList[this.currentDate.format(dateFormat)]
|
||
} catch (error) {
|
||
console.error(error)
|
||
} finally {
|
||
this.isGettingList = false
|
||
}
|
||
},
|
||
|
||
async getStationList() {
|
||
try {
|
||
this.isGettingStationList = true
|
||
const { success, result, message } = await getAction('/gardsStations/findPage?pageIndex=1&pageSize=1000')
|
||
if (success) {
|
||
const records = result.records
|
||
const set = new Set(records.map(item => item.countryCode))
|
||
this.originalTreeData = Array.from(set).map((countryCode, index) => {
|
||
return {
|
||
title: countryCode,
|
||
key: index.toString(),
|
||
disabled: true,
|
||
children: records
|
||
.filter(item => item.countryCode == countryCode)
|
||
.map(item => ({ title: item.stationCode, key: item.stationId.toString(), children: [] }))
|
||
}
|
||
})
|
||
|
||
this.stationList = records
|
||
} else {
|
||
this.$message.error(message)
|
||
}
|
||
} catch (error) {
|
||
console.error(error)
|
||
} finally {
|
||
this.isGettingStationList = false
|
||
}
|
||
},
|
||
|
||
async getAccountList() {
|
||
try {
|
||
const { success, result, message } = await getAction(
|
||
`/sys/user/list?pageIndex=1&pageSize=1000&username=${this.keyword}`
|
||
)
|
||
if (success) {
|
||
const records = result.records
|
||
this.accountList = records.map(item => ({
|
||
label: item.username,
|
||
value: item.id
|
||
}))
|
||
} else {
|
||
this.$message.error(message)
|
||
}
|
||
} catch (error) {
|
||
console.error(error)
|
||
}
|
||
},
|
||
|
||
// 选中某一个日期
|
||
onSelectDate(date) {
|
||
this.currentDate = date
|
||
if (this.currentDate.format(monthFormat) !== this.currentMonth.format(monthFormat)) {
|
||
this.currentMonth = this.currentDate.clone()
|
||
}
|
||
if (this.isGettingList) {
|
||
this.$message.info('Is Getting Schedule,Waitting...')
|
||
return
|
||
}
|
||
this.schedulingInfo = this.scheduleList[date.format(dateFormat)]
|
||
},
|
||
|
||
// 获取详情
|
||
async getScheduleDetail() {
|
||
try {
|
||
this.isGettingDetail = true
|
||
const { success, result, message } = await getAction(
|
||
`/sysTask/findInfo?day=${this.currentDate.format(dateFormat)}`
|
||
)
|
||
if (success) {
|
||
const selectedStations = [] // 找出已经被选中的站点
|
||
const accountTree = [] // 构建右侧的树
|
||
result.forEach(item => {
|
||
const accountItem = {
|
||
title: item.userName,
|
||
key: item.userId,
|
||
children: []
|
||
}
|
||
accountTree.push(accountItem)
|
||
|
||
item.stationList.forEach(station => {
|
||
selectedStations.push(station.stationId)
|
||
accountItem.children.push({
|
||
title: station.stationName,
|
||
key: station.stationId,
|
||
isLeaf: true
|
||
})
|
||
})
|
||
})
|
||
this.targetKeys = selectedStations
|
||
this.accountTreeData = accountTree
|
||
} else {
|
||
this.$message.error(message)
|
||
}
|
||
} catch (error) {
|
||
console.error(error)
|
||
} finally {
|
||
this.isGettingDetail = false
|
||
}
|
||
},
|
||
|
||
// 左侧删除某一天的日程
|
||
async onDel({ id: taskId, userId }) {
|
||
try {
|
||
const { success } = await deleteAction('/sysTask/deleteById', {
|
||
taskId,
|
||
userId
|
||
})
|
||
if (success) {
|
||
this.$message.success('Delete Success')
|
||
this.getList()
|
||
} else {
|
||
this.$message.success('Delete Fail')
|
||
}
|
||
} catch (error) {
|
||
console.error(error)
|
||
}
|
||
},
|
||
|
||
onAdd() {
|
||
if (this.schedulingInfo.length) {
|
||
this.$message.warn('Has Schedule, Only Can Edit')
|
||
return
|
||
}
|
||
|
||
this.isAdd = true
|
||
this.visible = true
|
||
|
||
this.selectedStationKeys = []
|
||
this.targetKeys = []
|
||
this.accountTreeData = []
|
||
this.rightAccountChildSelectedKeys = []
|
||
this.checkedAccount = ''
|
||
},
|
||
|
||
onEdit() {
|
||
if (!this.schedulingInfo.length) {
|
||
this.$message.warn('Has No Schedule, Add It First')
|
||
return
|
||
}
|
||
this.isAdd = false
|
||
this.visible = true
|
||
|
||
this.rightAccountChildSelectedKeys = []
|
||
this.checkedAccount = ''
|
||
this.getScheduleDetail()
|
||
},
|
||
|
||
onImport() {
|
||
console.log('%c [ 新增 ]-88', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||
},
|
||
|
||
onExport() {
|
||
console.log('%c [ 新增 ]-88', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||
},
|
||
|
||
// 开始拖拽
|
||
onDragStart(item, fromUserId) {
|
||
this.dragItem = item
|
||
this.fromUserId = fromUserId
|
||
},
|
||
// 拖拽结束
|
||
async onDrop(item) {
|
||
const toUserId = item.userId
|
||
if (this.fromUserId != toUserId) {
|
||
try {
|
||
this.isChanging = true
|
||
const { success } = await putAction('/sysTask/changeScheduling', {
|
||
day: this.currentDate.format('YYYY-MM-DD'),
|
||
fromUserId: this.fromUserId,
|
||
toUserId,
|
||
stationIds: [this.dragItem.stationId]
|
||
})
|
||
if (success) {
|
||
this.$message.success('Change Success')
|
||
this.getList()
|
||
} else {
|
||
this.$message.error('Change Fail')
|
||
}
|
||
} catch (error) {
|
||
console.error()
|
||
} finally {
|
||
this.isChanging = false
|
||
}
|
||
}
|
||
},
|
||
|
||
// 提交日程
|
||
async submit() {
|
||
if (!this.accountTreeData.length) {
|
||
this.$message.warn('Person List Is Empty')
|
||
return Promise.reject()
|
||
}
|
||
if (!this.accountTreeData.some(accountTreeItem => accountTreeItem.children.length)) {
|
||
this.$message.warn('Every Person Has No Station Assigned')
|
||
return Promise.reject()
|
||
}
|
||
try {
|
||
let method = putAction
|
||
let url = '/sysTask/update'
|
||
let successMsg = 'Edit Success'
|
||
let failMsg = 'Edit Fail'
|
||
if (this.isAdd) {
|
||
method = postAction
|
||
url = '/sysTask/create'
|
||
successMsg = 'Add Success'
|
||
failMsg = 'Add Fail'
|
||
}
|
||
const params = []
|
||
this.accountTreeData.forEach(accountTreeItem => {
|
||
if (accountTreeItem.children.length) {
|
||
params.push({
|
||
schedulingDate: this.currentDate.format('YYYY-MM-DD HH:mm:ss'),
|
||
stationList: accountTreeItem.children.map(child => {
|
||
return {
|
||
stationId: child.key
|
||
}
|
||
}),
|
||
userId: accountTreeItem.key
|
||
})
|
||
}
|
||
})
|
||
const { success } = await method(url, params)
|
||
if (success) {
|
||
this.$message.success(successMsg)
|
||
this.getList()
|
||
} else {
|
||
this.$message.error(failMsg)
|
||
return Promise.reject()
|
||
}
|
||
} catch (error) {
|
||
return Promise.reject()
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 以下是对穿梭框的处理
|
||
*/
|
||
|
||
isChecked(selectedKeys, eventKey) {
|
||
return selectedKeys.indexOf(eventKey) !== -1
|
||
},
|
||
|
||
onChecked(_, e, checkedKeys, itemSelect) {
|
||
const { eventKey } = e.node
|
||
itemSelect(eventKey, !this.isChecked(checkedKeys, eventKey))
|
||
},
|
||
|
||
handleSelectChange(sourceSelectedKeys, targetSelectedKeys) {
|
||
this.selectedStationKeys = [...sourceSelectedKeys, ...targetSelectedKeys]
|
||
},
|
||
|
||
// 处理station列表
|
||
handleTreeData(data, targetKeys = [], level) {
|
||
data.forEach(item => {
|
||
if (level !== 0) {
|
||
item.disabled = targetKeys.includes(item.key)
|
||
}
|
||
if (item.children) {
|
||
this.handleTreeData(item.children, targetKeys)
|
||
}
|
||
})
|
||
return data
|
||
},
|
||
|
||
// 将选中的账号加入到右侧穿梭框
|
||
onAddToList(selectedAccount) {
|
||
const addedAccounts = selectedAccount
|
||
.filter(id => !this.accountTreeData.find(account => account.key == id)) // 如果之前没有加过,才加进去
|
||
.map(id => {
|
||
const find = this.accountList.find(account => account.value == id)
|
||
return {
|
||
title: find.label,
|
||
key: id,
|
||
children: []
|
||
}
|
||
})
|
||
this.accountTreeData.push(...addedAccounts)
|
||
this.rightAccountChildSelectedKeys = []
|
||
this.checkedAccount = ''
|
||
},
|
||
|
||
// 选中了穿梭框右侧的树节点
|
||
onSelectAccount(_, e, itemSelect) {
|
||
const { eventKey, isLeaf, selected } = e.node
|
||
// selected 是前一个状态,也就是selected 为false时,其实是选中了
|
||
if (isLeaf) {
|
||
// 选中了子节点,也就是站点
|
||
this.checkedAccount = ''
|
||
|
||
if (selected) {
|
||
// 取消选中
|
||
itemSelect(eventKey, false)
|
||
} else {
|
||
this.accountTreeData.forEach(account => {
|
||
// 将所有右侧的穿梭状态重置
|
||
account.children.forEach(child => {
|
||
itemSelect(child.key, false)
|
||
})
|
||
})
|
||
itemSelect(eventKey, true) // 选中该栏
|
||
}
|
||
} else {
|
||
this.checkedAccount = selected ? '' : eventKey
|
||
// 将所有右侧的穿梭状态重置
|
||
this.accountTreeData.forEach(account => {
|
||
// 将所有右侧的穿梭状态重置
|
||
account.children.forEach(child => {
|
||
itemSelect(child.key, false)
|
||
})
|
||
})
|
||
}
|
||
},
|
||
|
||
// 穿梭框变化
|
||
onChange(targetKeys, direction, moveKeys) {
|
||
if (direction == 'right') {
|
||
if (!this.checkedAccount) {
|
||
this.$message.warning('Please Select A Person To Assign')
|
||
return
|
||
}
|
||
const findAccount = this.accountTreeData.find(account => account.key == this.checkedAccount)
|
||
if (findAccount) {
|
||
const children = moveKeys.map(key => {
|
||
const findStation = this.stationList.find(station => station.stationId == key)
|
||
return {
|
||
isLeaf: true,
|
||
title: findStation.stationCode,
|
||
key
|
||
}
|
||
})
|
||
findAccount.children.push(...children)
|
||
}
|
||
} else {
|
||
const moveKey = moveKeys[0]
|
||
console.log('%c [ moveKey ]-577', 'font-size:13px; background:pink; color:#bf2c9f;', moveKey)
|
||
let parentIndex = -1,
|
||
childIndex = -1
|
||
for (const pIndex in this.accountTreeData) {
|
||
// 找到要移除的Station在右侧列表中的位置
|
||
const account = this.accountTreeData[pIndex]
|
||
const cIndex = account.children.findIndex(child => child.key == moveKey)
|
||
if (-1 !== cIndex) {
|
||
parentIndex = pIndex
|
||
childIndex = cIndex
|
||
break
|
||
}
|
||
}
|
||
this.accountTreeData[parentIndex].children.splice(childIndex, 1)
|
||
console.log('%c [ childIndex ]-591', 'font-size:13px; background:pink; color:#bf2c9f;', childIndex)
|
||
}
|
||
this.targetKeys = targetKeys
|
||
}
|
||
},
|
||
computed: {
|
||
treeData() {
|
||
return this.handleTreeData(cloneDeep(this.originalTreeData), this.targetKeys, 0)
|
||
}
|
||
},
|
||
watch: {
|
||
currentMonth() {
|
||
this.currentDate = this.currentMonth.clone()
|
||
this.getList()
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style lang="less" scoped>
|
||
.scheduling {
|
||
height: 100%;
|
||
overflow: hidden;
|
||
display: flex;
|
||
&-list {
|
||
flex-shrink: 0;
|
||
width: 350px;
|
||
height: 100%;
|
||
background-color: #022024;
|
||
border-color: rgb(12, 106, 102, 0.9);
|
||
border-radius: 0;
|
||
::v-deep {
|
||
.ant-card {
|
||
&-head {
|
||
font-family: MicrogrammaD-MediExte;
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
padding-left: 15px;
|
||
background-color: #022024;
|
||
border-bottom-color: rgba(12, 235, 201, 0.3);
|
||
&-title {
|
||
padding-top: 22px;
|
||
padding-bottom: 0;
|
||
}
|
||
.line {
|
||
width: 70px;
|
||
height: 3px;
|
||
background-color: #0cebc9;
|
||
margin-top: 10px;
|
||
}
|
||
}
|
||
&-body {
|
||
height: calc(100% - 66px);
|
||
overflow: auto;
|
||
}
|
||
}
|
||
}
|
||
&-content {
|
||
padding: 0 12px;
|
||
}
|
||
&-item {
|
||
margin-top: 15px;
|
||
.title {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
font-family: Aria;
|
||
font-size: 14px;
|
||
color: #fff;
|
||
font-weight: bold;
|
||
margin-bottom: 4px;
|
||
position: relative;
|
||
padding-left: 8px;
|
||
span {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
}
|
||
.del {
|
||
margin-left: 15px;
|
||
margin-right: 10px;
|
||
width: 14px;
|
||
height: 14px;
|
||
background: url(~@/assets/images/system/del-normal.png);
|
||
background-size: cover;
|
||
&:hover {
|
||
background-image: url(~@/assets/images/system/del-active.png);
|
||
}
|
||
}
|
||
}
|
||
@borderColor: #0a544e;
|
||
@borderRadius: 4px;
|
||
@bgColor: #03353f;
|
||
&-container {
|
||
border-bottom: 1px solid @borderColor;
|
||
border-bottom-left-radius: @borderRadius;
|
||
border-bottom-right-radius: @borderRadius;
|
||
margin-top: 4px;
|
||
display: flex;
|
||
.left-border {
|
||
width: 6px;
|
||
position: relative;
|
||
.left-top-border {
|
||
position: relative;
|
||
.left-top-corner {
|
||
border: 1px solid @borderColor;
|
||
background-color: @bgColor;
|
||
position: absolute;
|
||
top: 25px;
|
||
left: 2px;
|
||
width: 9px;
|
||
height: 9px;
|
||
transform: rotate(45deg);
|
||
border-top: none;
|
||
border-right: 0;
|
||
}
|
||
}
|
||
.left-bottom-border {
|
||
height: calc(100% - 30px);
|
||
position: absolute;
|
||
left: 0;
|
||
bottom: 0;
|
||
width: 7px;
|
||
background-color: @bgColor;
|
||
border-left: 1px solid @borderColor;
|
||
border-bottom-left-radius: @borderRadius;
|
||
}
|
||
}
|
||
.right-border {
|
||
width: 14px;
|
||
position: relative;
|
||
.right-top-border {
|
||
position: absolute;
|
||
right: 4px;
|
||
top: 4px;
|
||
width: 20px;
|
||
height: 20px;
|
||
border: 1px solid transparent;
|
||
border-top-color: @borderColor;
|
||
transform: rotate(45deg);
|
||
background-color: @bgColor;
|
||
}
|
||
|
||
.right-bottom-border {
|
||
position: absolute;
|
||
right: 0;
|
||
bottom: 0;
|
||
width: 100%;
|
||
height: calc(100% - 14px);
|
||
border-right: 1px solid @borderColor;
|
||
border-bottom-right-radius: @borderRadius;
|
||
background-color: @bgColor;
|
||
}
|
||
}
|
||
}
|
||
&-content {
|
||
min-height: 62px;
|
||
border-top: 1px solid @borderColor;
|
||
border-left: 1px solid @borderColor;
|
||
padding: 6px;
|
||
background-color: @bgColor;
|
||
line-height: 26px;
|
||
flex: 1;
|
||
color: #6ebad0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 右侧日历
|
||
&-calendar {
|
||
height: 100%;
|
||
margin-left: 20px;
|
||
padding-right: 10px;
|
||
.ant-fullcalendar-fullscreen {
|
||
height: 100%;
|
||
overflow: auto;
|
||
padding-right: 5px;
|
||
::v-deep {
|
||
.ant-fullcalendar-full {
|
||
height: calc(100% - 61px);
|
||
overflow: auto;
|
||
padding-right: 5px;
|
||
}
|
||
}
|
||
}
|
||
.search-form {
|
||
padding: 10px;
|
||
border: 1px solid #416f7f;
|
||
border-bottom: 0;
|
||
&-form {
|
||
.ant-form-item {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
.btn-group {
|
||
float: right;
|
||
height: 40px;
|
||
img {
|
||
margin-right: 12px;
|
||
height: 18px;
|
||
}
|
||
}
|
||
}
|
||
|
||
&-content {
|
||
padding: 10px;
|
||
height: 100%;
|
||
overflow: hidden auto;
|
||
background-color: rgba(140, 255, 229, 0.1);
|
||
&::-webkit-scrollbar {
|
||
width: 4px !important;
|
||
}
|
||
.item {
|
||
font-family: Arial;
|
||
font-size: 14px;
|
||
color: #00fdd3;
|
||
height: 20px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.account-assign {
|
||
position: relative;
|
||
width: 672px;
|
||
margin: 0 auto;
|
||
.ant-transfer {
|
||
margin-bottom: 10px;
|
||
::v-deep {
|
||
.ant-transfer-list {
|
||
width: 282px;
|
||
height: 411px;
|
||
&-header {
|
||
height: 37px;
|
||
&-selected {
|
||
span:first-child {
|
||
display: none;
|
||
}
|
||
}
|
||
&-title {
|
||
left: 16px;
|
||
}
|
||
}
|
||
&-content {
|
||
&-item {
|
||
&:hover {
|
||
background-color: transparent;
|
||
}
|
||
}
|
||
}
|
||
|
||
&:last-child {
|
||
height: 364px;
|
||
position: relative;
|
||
top: 47px;
|
||
}
|
||
}
|
||
|
||
.ant-transfer-operation {
|
||
.ant-btn {
|
||
width: 92px;
|
||
height: 26px;
|
||
padding: 0;
|
||
.anticon {
|
||
display: none;
|
||
}
|
||
span {
|
||
margin-left: 0;
|
||
}
|
||
&:first-child {
|
||
margin-bottom: 52px;
|
||
&::after {
|
||
display: inline-block;
|
||
margin-left: 13px;
|
||
content: '';
|
||
width: 18px;
|
||
height: 10px;
|
||
background: url(~@/assets/images/system/transfer-right.png) no-repeat;
|
||
background-size: contain;
|
||
}
|
||
}
|
||
&:nth-child(2) {
|
||
&::before {
|
||
display: inline-block;
|
||
margin-right: 6px;
|
||
content: '';
|
||
width: 18px;
|
||
height: 10px;
|
||
background: url(~@/assets/images/system/transfer-left.png) no-repeat;
|
||
background-size: contain;
|
||
position: static;
|
||
opacity: initial;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.account-search {
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
width: 282px;
|
||
display: flex;
|
||
align-items: center;
|
||
label {
|
||
color: #5b9cba;
|
||
font-size: 16px;
|
||
flex-shrink: 0;
|
||
margin-right: 10px;
|
||
user-select: none;
|
||
}
|
||
}
|
||
}
|
||
.ant-select-dropdown-content::before {
|
||
top: 2px;
|
||
}
|
||
.account-add {
|
||
padding: 0;
|
||
padding-top: 10px;
|
||
text-align: center;
|
||
cursor: pointer;
|
||
background: #03353f;
|
||
a {
|
||
display: inline-block;
|
||
width: 100%;
|
||
padding: 5px;
|
||
border-top: 1px solid #0da397;
|
||
color: #0cebc9;
|
||
}
|
||
}
|
||
|
||
.draggable {
|
||
cursor: pointer;
|
||
}
|
||
</style>
|