Browse Source

修改列表样式

master
song 4 years ago
parent
commit
a26a322ca3
  1. 2
      public/index.html
  2. 10
      rest/project.http
  3. 11
      src/App.vue
  4. 14
      src/common/portrait.styl
  5. 3
      src/components/HeadNav/HeadNav.vue
  6. 303
      src/components/List/List.vue
  7. 2
      src/components/TimePicker/TimePicker.vue
  8. 3
      src/config/api.js
  9. 3
      src/main.js
  10. 2
      src/plugins/ant-design-vue.js

2
public/index.html

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

10
rest/project.http

@ -1,14 +1,14 @@
### login
# @name login
POST https://www.tall.wiki/gateway/tall/v1.0/users/signin
POST https://test.tall.wiki/gateway/tall/v1.0/users/signin
content-type: application/json;charset=utf-8
{
"client": 1,
"data": {
"credential": "song",
"identifier": "999999"
"credential": "123456",
"identifier": "zb"
},
"scene": 0,
"type": 3
@ -18,7 +18,7 @@ content-type: application/json;charset=utf-8
### 导入插件
# POST http://127.0.0.1:7220/plugin/import
POST http://www.tall.wiki/gateway/pluginshop/plugin/import
POST http://test.tall.wiki/gateway/pluginshop/plugin/import
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Authorization: Bearer {{login.response.body.$.data.token}}
@ -34,6 +34,6 @@ Content-Type: xlsx
### 更新redis内的插件信息
POST http://www.tall.wiki/gateway/pluginshop/plugin/updatePluginOfRedis
POST http://test.tall.wiki/gateway/pluginshop/plugin/updatePluginOfRedis
content-type: application/json;charset=utf-8
Authorization: Bearer {{login.response.body.$.data.token}}

11
src/App.vue

@ -1,5 +1,5 @@
<template>
<div id="app" class="px-2">
<div id="app">
<head-nav class="head-nav" />
<router-view></router-view>
</div>
@ -18,11 +18,11 @@ export default {
},
async created() {
this.setProjectId(this.$route.query.pid);
const userId = this.$route.query.uid;
const params = { userId };
await this.getUserId(params);
await this.getAllMembers({ projectId: this.$route.query.pid });
this.setProjectId(this.$route.query.pid);
},
methods: {
@ -40,11 +40,4 @@ body,
min-height: 100%;
width: 100%;
}
#app {
/* background: transparent; */
}
body {
/* background: #f5f5f5 !important; */
}
</style>

14
src/common/portrait.styl

@ -483,7 +483,7 @@ h2{
}
.second-base-bg{
background: #AACD06
background: #52c41a
}
//
@ -491,6 +491,14 @@ h2{
color: #fff
}
.red--text{
color: #f00
}
.green--text{
color: #52c41a
}
.title-color{
color: rgba(0,0,0,.85)
}
@ -511,3 +519,7 @@ h2{
.line-height-36{
line-height: 36px
}
.line-through{
text-decoration: line-through
}

3
src/components/HeadNav/HeadNav.vue

@ -1,5 +1,5 @@
<template>
<div class="d-flex justify-space-between align-center justify-center nav">
<div class="d-flex justify-space-between align-center justify-center nav mb-4">
<!-- <a-icon type="left" class="back" /> -->
<div>考勤管理</div>
<a-button type="primary" size="small" class="export"> 导出 </a-button>
@ -23,7 +23,6 @@ export default {
<style lang="less" scoped>
.nav {
position: relative;
height: 50px;
}
.back {
position: absolute;

303
src/components/List/List.vue

@ -1,87 +1,164 @@
<template>
<div class="mt-5">
<div class="d-flex flex-nowrap table-head">
<div style="width: 10%"></div>
<div class="table-head-item">姓名</div>
<div class="table-head-item" style="width: 16%">姓名</div>
<div class="table-head-item"></div>
<div class="table-head-item"></div>
<div class="table-head-item">审核人</div>
<div class="table-head-item" style="width: 30%">审核人</div>
</div>
<div v-if="clockInfos && clockInfos.length">
<div v-for="(list, listIndex) in clockInfos" :key="listIndex" class="teble-box">
<div class="table-time px-2">{{ list.dateTime }}</div>
<a-table :pagination="false" :show-header="false" :columns="columns" :data-source="list.recordList">
<template slot="actions" slot-scope="text, record, index">
<img @click="showMenu(index)" src="https://www.tall.wiki/staticrec/drag.svg" />
</template>
<!-- -->
<template slot="morning" slot-scope="text, record, index">
<div v-if="record.morningStatus">
{{ $moment(record.morning - 0).format('HH:mm') }}
<div v-if="!record.isMine && !record.isChecker">
<span v-if="record.morningStatus">{{ $moment(record.morning - 0).format('HH:mm') }}</span>
<span v-else>未打卡</span>
</div>
<div v-else>
<div v-if="record.isMine">
<span v-if="record.morningStatus" class="baseColor font-bold">
{{ $moment(record.morning - 0).format('HH:mm') }}
</span>
<a-button
v-else
type="primary"
size="small"
@click="checkTime(listIndex, index, 0, record.id, record.memberId, record.checkerId)"
>
打卡
</a-button>
</div>
<div v-if="record.isChecker">
<div v-if="record.morningStatus && !showMorningTime">
<a-popconfirm
ok-text="取消"
cancel-text="修改"
ok-type=""
@confirm="cancel"
:visible="morningVisible"
@cancel="changeStatus(record.id, 0, 'morning')"
>
<a-icon slot="icon" type="" />
<a-button slot="title" size="small" @click="rejectStatus(record.id, 1, 'morning', record.morning)">驳回</a-button>
<span
class="font-bold"
:class="record.morningStatus === 2 ? 'line-through red--text' : 'green--text'"
@click="changeVisible(record.morningStatus, 'morningVisible')"
>
{{ $moment(record.morning - 0).format('HH:mm') }}
</span>
</a-popconfirm>
</div>
<div v-if="!record.morningStatus && !showMorningTime">未打卡</div>
<!-- 修改时间 -->
<a-time-picker
placeholder="请选择"
style="width: 100%"
v-if="showMorningTime"
format="HH:mm"
class="px-2"
@change="timeChange"
@openChange="openChange($event, 'morning')"
/>
</div>
</div>
<a-button
v-else
type="primary"
size="small"
@click="checkTime(listIndex, index, 0, record.id, record.memberId, record.checkerId)"
>
打卡
</a-button>
</template>
<!-- -->
<template slot="night" slot-scope="text, record, index">
<div v-if="record.nightStatus">
{{ $moment(record.night - 0).format('HH:mm') }}
<div v-if="!record.isMine && !record.isChecker">
<span v-if="record.nightStatus">{{ $moment(record.night - 0).format('HH:mm') }}</span>
<span v-else>未打卡</span>
</div>
<div v-else>
<div v-if="record.isMine">
<span v-if="record.nightStatus" class="baseColor font-bold">
{{ $moment(record.night - 0).format('HH:mm') }}
</span>
<a-button
v-else
type="primary"
size="small"
@click="checkTime(listIndex, index, 1, record.id, record.memberId, record.checkerId)"
>
打卡
</a-button>
</div>
<div v-if="record.isChecker">
<div v-if="record.nightStatus && !showNightTime">
<a-popconfirm
ok-text="取消"
cancel-text="修改"
ok-type=""
@confirm="cancel"
:visible="visible"
@cancel="changeStatus(record.id, 0, 'night')"
>
<a-icon slot="icon" type="" />
<a-button slot="title" size="small" @click="rejectStatus(record.id, 1, 'night', record.night)">驳回</a-button>
<span
class="font-bold"
:class="record.nightStatus === 2 ? 'line-through red--text' : 'green--text'"
@click="changeVisible(record.nightStatus, 'visible')"
>
{{ $moment(record.night - 0).format('HH:mm') }}
</span>
</a-popconfirm>
</div>
<div v-if="!record.nightStatus && !showNightTime">未打卡</div>
<!-- 修改时间 -->
<a-time-picker
placeholder="请选择"
style="width: 100%"
v-if="showNightTime"
format="HH:mm"
class="px-2"
@change="timeChange"
@openChange="openChange($event, 'night')"
/>
</div>
</div>
<a-button
v-else
type="primary"
size="small"
@click="checkTime(listIndex, index, 1, record.id, record.memberId, record.checkerId)"
>
打卡
</a-button>
</template>
<!-- 审核人 -->
<template slot="checkerName" slot-scope="text, record">
<a-select :default-value="record.checkerId || checkerId" style="width: 80px" placeholder="选择" @change="chooseChecker">
<a-select-option :value="member.memberId" v-for="member in members" :key="member.memberId">
{{ member.name }}
</a-select-option>
</a-select>
<div class="px-2">
<div v-if="!record.isMine || (record.isMine && record.morningStatus && record.nightStatus)">
{{ record.checkerName || members[0].name }}
</div>
<a-select v-else :default-value="record.checkerId || members[0].memberId" style="width: 100%" @change="chooseChecker">
<a-select-option :value="member.memberId" v-for="member in members" :key="member.memberId">
{{ member.name }}
</a-select-option>
</a-select>
</div>
</template>
</a-table>
</div>
</div>
<a-empty class="mt-8 mb-8" description="暂无打卡信息" v-else />
<a-drawer
placement="bottom"
:closable="false"
:mask-closable="false"
:visible="visible"
:after-visible-change="afterVisibleChange"
class="actions-box"
>
<p class="mb-1">修改</p>
<p class="mb-4">驳回</p>
<p class="mb-0" @click="onClose">取消</p>
</a-drawer>
</div>
</template>
<script>
import { mapState } from 'vuex';
import { clockQuery, clockPunch } from '@/config/api';
import { clockQuery, clockPunch, clockAudit } from '@/config/api';
const columns = [
{ title: ' ', dataIndex: 'actions', key: 'actions', scopedSlots: { customRender: 'actions' }, align: 'center', width: '10%' },
{ title: '姓名', dataIndex: 'memberName', key: 'memberName', align: 'center', width: '22.5%' },
{ title: '早', dataIndex: 'morning', key: 'morning', scopedSlots: { customRender: 'morning' }, align: 'center', width: '22.5%' },
{ title: '晚', dataIndex: 'night', key: 'night', scopedSlots: { customRender: 'night' }, align: 'center', width: '22.5%' },
{ title: '姓名', dataIndex: 'memberName', key: 'memberName', align: 'center', width: '16%' },
{ title: '早', dataIndex: 'morning', key: 'morning', scopedSlots: { customRender: 'morning' }, align: 'center', width: '27%' },
{ title: '晚', dataIndex: 'night', key: 'night', scopedSlots: { customRender: 'night' }, align: 'center', width: '27%' },
{
title: '审核人',
dataIndex: 'checkerName',
key: 'checkerName',
scopedSlots: { customRender: 'checkerName' },
align: 'center',
width: '22.5%',
width: '30%',
},
];
@ -93,15 +170,26 @@ export default {
memberIdList: [],
options: null,
checkerId: undefined,
morningVisible: false,
visible: false,
placement: 'left',
timer: null,
showNightTime: false,
showMorningTime: false,
chooseTime: '',
auditOptions: null,
};
},
computed: mapState('home', ['projectId', 'members']),
mounted() {
this.setParams();
this.timer = setInterval(() => {
if (this.projectId) {
clearInterval(this.timer);
this.setParams();
}
}, 300);
},
methods: {
@ -152,7 +240,7 @@ export default {
this.clockInfos[listIndex].recordList[index].night = selectTime;
}
const dateTime = this.$moment(time).format('x') - 0;
const params = { param: { checkerId: this.checkerId || checkerId, clockType, dateTime, id, memberId } };
const params = { param: { checkerId: this.checkerId || checkerId || this.members[0].memberId, clockType, dateTime, id, memberId } };
this.handleClockPunch(params);
},
@ -172,25 +260,90 @@ export default {
this.$message.success('打卡成功');
this.setParams();
} else {
this.$message.error(msg || '获取失败');
this.$message.error(msg || '打卡失败');
throw msg;
}
} catch (error) {
throw error || '获取失败';
throw error || '打卡失败';
}
},
showMenu(index) {
console.log('展开菜单', index);
this.visible = true;
changeVisible(status, type) {
if (status !== 2) {
this[type] = true;
}
},
//
changeStatus(id, type, timeType) {
if (timeType === 'morning') {
this.morningVisible = false;
this.showMorningTime = true;
} else {
this.visible = false;
this.showNightTime = true;
}
this.auditOptions = { id, type };
},
//
timeChange(time) {
this.chooseTime = this.$moment(time).format('x');
},
async openChange(open, timeType) {
if (!open && this.chooseTime) {
this.auditOptions[timeType] = this.chooseTime;
this.auditOptions.projectId = this.projectId;
const params = { param: this.auditOptions };
await this.handleClockAudit(params);
}
if (!open && !this.chooseTime) {
this.showNightTime = false;
this.showMorningTime = false;
}
},
afterVisibleChange(val) {
console.log('visible', val);
//
async rejectStatus(id, type, timeType, time) {
if (timeType === 'morning') {
this.morningVisible = false;
} else {
this.visible = false;
}
const params = { param: { id, type, [timeType]: time, projectId: this.projectId } };
await this.handleClockAudit(params);
},
onClose() {
//
cancel() {
this.visible = false;
this.morningVisible = false;
},
/**
* 审核打卡
* @param {string} id 打卡记录id
* @param {string} morning 早打卡时间
* @param {string} night 晚打卡时间
* @param {string} projectId 项目id
* @param {string} type 审批类型(0-修改,1-驳回)
*/
async handleClockAudit(params) {
try {
const res = await clockAudit(params);
const { code, msg } = res.data;
if (code === 200) {
this.$message.success(params.param.type === 0 ? '修改成功' : '驳回成功');
this.showNightTime = false;
this.showMorningTime = false;
this.auditOptions = null;
this.setParams();
} else {
this.$message.error(msg || '审核失败');
throw msg;
}
} catch (error) {
throw error || '审核失败';
}
},
},
};
@ -200,19 +353,19 @@ export default {
.table-head {
border-bottom: 1px solid #e8e8e8;
background: #fafafa;
height: 40px;
line-height: 40px;
height: 36px;
line-height: 36px;
font-weight: bold;
}
.table-time {
height: 40px;
line-height: 40px;
height: 36px;
line-height: 36px;
border-bottom: 1px solid #e8e8e8;
}
.table-head-item {
width: 22.5%;
width: 27%;
text-align: center;
}
@ -222,7 +375,11 @@ img {
}
.teble-box >>> .ant-table-row-cell-break-word {
padding: 8px 0 !important;
padding: 4px 0 !important;
}
.teble-box >>> .ant-table-row {
height: 41px !important;
}
.actions-box >>> .ant-drawer-content-wrapper {
@ -238,9 +395,21 @@ img {
}
.actions-box >>> .ant-drawer-body p {
height: 40px;
line-height: 40px;
height: 36px;
line-height: 36px;
background: #fcfcfc;
text-align: center;
}
</style>
<style>
.ant-popover-inner {
width: 200px;
}
.ant-popover-message {
position: absolute !important;
left: 2px;
top: 8px;
}
</style>

2
src/components/TimePicker/TimePicker.vue

@ -5,6 +5,7 @@
:disabled-date="disabledStartDate"
show-time
allow-clear
locale="zh-cn"
:format="monthFormat"
placeholder="起始时间"
class="box box1"
@ -13,7 +14,6 @@
<a-date-picker
v-model="endValue"
:disabled-date="disabledEndDate"
show-time
allow-clear
:format="monthFormat"
class="box box2"

3
src/config/api.js

@ -10,3 +10,6 @@ export const clockPunch = params => axios.post(`${defaultwbs}/clock/punch`, para
// 查询所有成员
export const queryChecker = params => axios.post(`${defaultwbs}/deliver/queryChecker`, params);
// 查询所有成员
export const clockAudit = params => axios.post(`${defaultwbs}/clock/audit`, params);

3
src/main.js

@ -9,6 +9,9 @@ import './plugins/ant-design-vue.js';
import 'common/portrait.styl';
import './assets/icon/iconfont.css';
import moment from 'moment'; //导入文件
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
Vue.prototype.$moment = moment; //赋值使用

2
src/plugins/ant-design-vue.js

@ -43,6 +43,7 @@ import {
Card,
Skeleton,
Drawer,
TimePicker,
} from 'ant-design-vue';
import { ConfigProvider } from 'ant-design-vue';
Vue.component(ConfigProvider.name, ConfigProvider);
@ -80,6 +81,7 @@ Vue.use(Divider);
Vue.use(Card);
Vue.use(Skeleton);
Vue.use(Drawer);
Vue.use(TimePicker);
Vue.prototype.$message = message;
Vue.prototype.$notification = notification;

Loading…
Cancel
Save