|
|
@@ -42,7 +42,7 @@
|
|
|
:percentage="percentage"
|
|
|
></el-progress>
|
|
|
</div>
|
|
|
- <div class="form_name">
|
|
|
+ <div class="form_name" v-if="percentage == 100">
|
|
|
<span>{{ form_name }}</span>
|
|
|
<i class="el-icon-close" @click="handleRemove"></i>
|
|
|
</div>
|
|
|
@@ -95,17 +95,96 @@
|
|
|
size="20%"
|
|
|
>
|
|
|
<div class="drawer_title">设置</div>
|
|
|
+
|
|
|
<div class="drawer_body">
|
|
|
- <div class="drawer_item">
|
|
|
- 墨轩湖每日打卡次数为<input v-model="clockIn_mo" type="text" />次
|
|
|
- </div>
|
|
|
- <div class="drawer_item">
|
|
|
- 黄家湖每日打卡次数为<input v-model="clockIn_huang" type="text" />次
|
|
|
+ <el-tabs
|
|
|
+ stretch
|
|
|
+ v-model="activeName"
|
|
|
+ type="card"
|
|
|
+ @tab-click="handleClick"
|
|
|
+ >
|
|
|
+ <el-tab-pane label="黄家湖" name="黄家湖"></el-tab-pane>
|
|
|
+ <el-tab-pane label="墨轩湖" name="墨轩湖"></el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ <div class="huang">
|
|
|
+ <div class="h_title">
|
|
|
+ <div>设置规则</div>
|
|
|
+ <el-button type="primary" @click="handleAdd">添加</el-button>
|
|
|
+ </div>
|
|
|
+ <div class="h_time">
|
|
|
+ <el-card
|
|
|
+ class="card"
|
|
|
+ shadow="hover"
|
|
|
+ v-for="item in timeList"
|
|
|
+ :key="item.id"
|
|
|
+ >
|
|
|
+ <div class="card_title">
|
|
|
+ <span v-if="item.isShow">{{ item.clockName }}</span>
|
|
|
+ <input
|
|
|
+ v-focus
|
|
|
+ v-else
|
|
|
+ v-model="item.clockName"
|
|
|
+ @blur="handleTitleSave(item)"
|
|
|
+ />
|
|
|
+ <div class="icon" @click="handleTitleEdit(item)"></div>
|
|
|
+ </div>
|
|
|
+ <div class="card_count">
|
|
|
+ <span>设置次数</span>
|
|
|
+ <el-input-number
|
|
|
+ size="mini"
|
|
|
+ v-model="item.count"
|
|
|
+ :min="1"
|
|
|
+ ></el-input-number>
|
|
|
+ </div>
|
|
|
+ <div class="card_time">
|
|
|
+ <el-time-select
|
|
|
+ placeholder="起始时间"
|
|
|
+ size="mini"
|
|
|
+ v-model="item.startTime"
|
|
|
+ :picker-options="{
|
|
|
+ start: '00:00',
|
|
|
+ step: '00:10',
|
|
|
+ end: '24:00',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ </el-time-select>
|
|
|
+ <el-time-select
|
|
|
+ placeholder="结束时间"
|
|
|
+ size="mini"
|
|
|
+ v-model="item.endTime"
|
|
|
+ :picker-options="{
|
|
|
+ start: '00:00',
|
|
|
+ step: '00:10',
|
|
|
+ end: '24:00',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ </el-time-select>
|
|
|
+ </div>
|
|
|
+ <div class="card_close" @click="handleCloseCard(item)"></div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+ <div class="h_foot">
|
|
|
+ <div>迟到规则</div>
|
|
|
+ <div>
|
|
|
+ 上班最多晚到 <input v-model="ruleObj.lateOfWork" /> 分钟,晚到{{
|
|
|
+ ruleObj.lateOfWork
|
|
|
+ }}分钟不算迟到
|
|
|
+ </div>
|
|
|
+ <div>早退规则</div>
|
|
|
+ <div>
|
|
|
+ 下班最多早走<input
|
|
|
+ v-model="ruleObj.leaveEarlyOfWork"
|
|
|
+ />分钟,早走{{ ruleObj.leaveEarlyOfWork }}分钟以上算早退
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
<div class="drawer_foot">
|
|
|
<el-button class="foot_button" @click="handleClose">取消</el-button>
|
|
|
- <el-button class="foot_button" type="primary">保存</el-button>
|
|
|
+ <el-button class="foot_button" type="primary" @click="handleSave"
|
|
|
+ >保存</el-button
|
|
|
+ >
|
|
|
</div>
|
|
|
</el-drawer>
|
|
|
|
|
|
@@ -138,24 +217,133 @@ export default {
|
|
|
parsePercentage: 0,
|
|
|
// 定时器
|
|
|
timer: null,
|
|
|
+ // 文字变化定时器
|
|
|
+ timer_info: null,
|
|
|
// 文件名称
|
|
|
form_name: "考勤表",
|
|
|
- // 文件数据
|
|
|
- fileData: null,
|
|
|
- // 墨轩湖打卡次数
|
|
|
- clockIn_mo: 4,
|
|
|
- // 黄家湖打卡次数
|
|
|
- clockIn_huang: 3,
|
|
|
+ // 解析文件所花费的时间
|
|
|
time_s: 1,
|
|
|
// 预览表格弹窗
|
|
|
dialogVisible: false,
|
|
|
+ // 弹窗当前标签栏
|
|
|
+ activeName: "黄家湖",
|
|
|
+ // 打卡时间段数据
|
|
|
+ timeList: [],
|
|
|
+ // 弹性打卡规则数据
|
|
|
+ ruleObj: {},
|
|
|
+ // 添加的打卡对象
|
|
|
+ temObj: {
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ count: 1,
|
|
|
+ clockName: "点击修改图标自定义标题",
|
|
|
+ isShow: true,
|
|
|
+ campus: "黄家湖",
|
|
|
+ },
|
|
|
};
|
|
|
},
|
|
|
+ mounted() {},
|
|
|
methods: {
|
|
|
+ // 保存按钮回调
|
|
|
+ async handleSave() {
|
|
|
+ let data = {
|
|
|
+ campusTimeList: this.timeList,
|
|
|
+ lateClock: this.ruleObj,
|
|
|
+ };
|
|
|
+ // console.log(data);
|
|
|
+ let res = await this.$axios({
|
|
|
+ url: "/attendance/campus/saveOrUpdateCampusTime",
|
|
|
+ method: "post",
|
|
|
+ data,
|
|
|
+ });
|
|
|
+ // console.log(res.data);
|
|
|
+ if (res.data.success) {
|
|
|
+ this.$message.success("修改成功");
|
|
|
+ this.getTimeData();
|
|
|
+ this.getRule();
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.message);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 删除卡片回调
|
|
|
+ handleCloseCard(item) {
|
|
|
+ this.$confirm("确定删除吗?", "提示", {
|
|
|
+ type: "warning",
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ let index = this.timeList.findIndex(
|
|
|
+ (element) => element.id == item.id
|
|
|
+ );
|
|
|
+ this.timeList.splice(index, 1);
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ this.$message.info("已取消删除");
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 修改标题回调
|
|
|
+ handleTitleEdit(item) {
|
|
|
+ item.isShow = false;
|
|
|
+ },
|
|
|
+ // 保存标题回调
|
|
|
+ handleTitleSave(item) {
|
|
|
+ item.isShow = true;
|
|
|
+ },
|
|
|
+ // 添加卡片回调
|
|
|
+ handleAdd() {
|
|
|
+ this.temObj.campus = this.activeName;
|
|
|
+ this.timeList.push(this.temObj);
|
|
|
+ },
|
|
|
+ // 切换校区回调
|
|
|
+ handleClick() {
|
|
|
+ this.getTimeData();
|
|
|
+ this.getRule();
|
|
|
+ },
|
|
|
+ // 获取打卡时间设置数据
|
|
|
+ async getTimeData() {
|
|
|
+ let params = {
|
|
|
+ campus: this.activeName,
|
|
|
+ };
|
|
|
+ let res = await this.$axios({
|
|
|
+ url: "/attendance/campus/queryCampusTime",
|
|
|
+ method: "get",
|
|
|
+ params,
|
|
|
+ });
|
|
|
+ // console.log(res.data);
|
|
|
+ if (res.data.success) {
|
|
|
+ this.timeList = res.data.data;
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.message);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取弹性考勤规则数据
|
|
|
+ async getRule() {
|
|
|
+ let params = {
|
|
|
+ campus: this.activeName,
|
|
|
+ };
|
|
|
+ let res = await this.$axios({
|
|
|
+ url: "/attendance/late/queryLateClock",
|
|
|
+ method: "get",
|
|
|
+ params,
|
|
|
+ });
|
|
|
+ // console.log(res.data);
|
|
|
+ if (res.data.success) {
|
|
|
+ this.ruleObj = res.data.data;
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.message);
|
|
|
+ }
|
|
|
+ },
|
|
|
// 文件上传回调
|
|
|
async handleUpload(file) {
|
|
|
if (file) {
|
|
|
- this.fileData = file;
|
|
|
+ this.timer_info = setInterval(() => {
|
|
|
+ if (this.info == "上传中,请稍等") {
|
|
|
+ this.info = "上传中,请稍等.";
|
|
|
+ } else if (this.info == "上传中,请稍等.") {
|
|
|
+ this.info = "上传中,请稍等..";
|
|
|
+ } else {
|
|
|
+ this.info = "上传中,请稍等";
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
this.form_name = file.name;
|
|
|
this.hasDrag = false;
|
|
|
this.showPage = 2;
|
|
|
@@ -165,62 +353,93 @@ export default {
|
|
|
let config = {
|
|
|
onUploadProgress: (progressEvent) => {
|
|
|
// 计算出当前进度
|
|
|
- this.percentage =
|
|
|
- (progressEvent.loaded / progressEvent.total).toFixed(2) * 100;
|
|
|
- },
|
|
|
- headers: {
|
|
|
- "Content-Type": "multipart/form-data",
|
|
|
- "admin_token":
|
|
|
- "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjMsImlhdCI6MTY2Mzc0MjY3OCwiZXhwIjoxNjY0OTUyMjc4fQ.tRT4VbTcITCIEp1LfZgXuQpXG9gbK0tq1ljvUI7nW-4",
|
|
|
+ this.percentage = Math.floor(
|
|
|
+ (progressEvent.loaded / progressEvent.total) * 100
|
|
|
+ );
|
|
|
+ this.percentage = this.percentage == 100 ? 90 : this.percentage;
|
|
|
},
|
|
|
};
|
|
|
-
|
|
|
let res = await this.$axios.post(
|
|
|
- "/api/tuitionpayment/payableinfo/importByExcel",
|
|
|
+ "/attendance/month/importExcel",
|
|
|
formData,
|
|
|
config
|
|
|
);
|
|
|
// console.log(res);
|
|
|
if (res.data.success) {
|
|
|
+ this.percentage = 100;
|
|
|
this.info = "上传完成,请点击开始按钮开始解析";
|
|
|
+ clearInterval(this.timer_info);
|
|
|
} else {
|
|
|
this.$message.error(res.data.message);
|
|
|
this.percentage = 0;
|
|
|
this.info = res.data.message;
|
|
|
}
|
|
|
} else {
|
|
|
- this.$message.error("请先导入文件");
|
|
|
+ this.$message.error("请先上传文件");
|
|
|
return false;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 点击开始按钮回调
|
|
|
- handleStart() {
|
|
|
- // console.log(this.fileData);
|
|
|
+ async handleStart() {
|
|
|
if (this.showPage == 2 && this.percentage == 100) {
|
|
|
- this.showPage = 3;
|
|
|
- this.timer = setInterval(() => {
|
|
|
- this.parsePercentage += 20;
|
|
|
- this.time_s += 1;
|
|
|
- if (this.parsePercentage >= 100) {
|
|
|
- this.parsePercentage = 100;
|
|
|
- clearInterval(this.timer);
|
|
|
- this.showPage = 4;
|
|
|
- }
|
|
|
- }, 1000);
|
|
|
+ // 开始解析时的处理
|
|
|
+ let res = await this.$axios({
|
|
|
+ url: "/attendance/late/queryLateClock",
|
|
|
+ method: "get",
|
|
|
+ });
|
|
|
+ console.log(res);
|
|
|
+ if (res.data.success) {
|
|
|
+ this.showPage = 3;
|
|
|
+ // 计算出解析的时间
|
|
|
+ this.timer = setInterval(() => {
|
|
|
+ this.time_s += 1;
|
|
|
+ this.parsePercentage += 1;
|
|
|
+ if (this.parsePercentage >= 90) {
|
|
|
+ this.parsePercentage = 90;
|
|
|
+ }
|
|
|
+ let result = await this.$axios({
|
|
|
+ url: "/attendance/late/queryLateClock",
|
|
|
+ method: "get",
|
|
|
+ });
|
|
|
+ console.log(result);
|
|
|
+ if (result.data.success) {
|
|
|
+ this.parsePercentage = 100;
|
|
|
+ clearInterval(this.timer);
|
|
|
+ this.showPage = 4;
|
|
|
+ }
|
|
|
+ // this.parsePercentage += 20;
|
|
|
+ // if (this.parsePercentage >= 100) {
|
|
|
+ // this.parsePercentage = 100;
|
|
|
+ // clearInterval(this.timer);
|
|
|
+ // this.showPage = 4;
|
|
|
+ // }
|
|
|
+ }, 1000);
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.message);
|
|
|
+ }
|
|
|
} else if (this.showPage == 3) {
|
|
|
this.$message.error("解析中,请勿重复点击");
|
|
|
} else {
|
|
|
- this.$message.error("请先上传文件");
|
|
|
+ this.$message.error("请上传文件后再开始解析");
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 删除列表文件时的回调
|
|
|
handleRemove() {
|
|
|
- this.hasDrag = true;
|
|
|
- this.showPage = 1;
|
|
|
- this.info = "上传中,请稍等";
|
|
|
- this.percentage = 0;
|
|
|
+ this.$confirm("确定删除已上传文件吗?", "提示", {
|
|
|
+ type: "warning",
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ this.hasDrag = true;
|
|
|
+ this.showPage = 1;
|
|
|
+ this.info = "上传中,请稍等";
|
|
|
+ this.percentage = 0;
|
|
|
+ this.$message.success("删除成功,请重新上传文件");
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ this.$message.info("已取消");
|
|
|
+ });
|
|
|
},
|
|
|
|
|
|
// 预览按钮回调
|
|
|
@@ -244,6 +463,8 @@ export default {
|
|
|
|
|
|
// 点击设置按钮回调
|
|
|
handleSet() {
|
|
|
+ this.getTimeData();
|
|
|
+ this.getRule();
|
|
|
this.drawer = true;
|
|
|
},
|
|
|
|
|
|
@@ -406,12 +627,80 @@ export default {
|
|
|
}
|
|
|
.drawer_body {
|
|
|
flex: 15;
|
|
|
- .drawer_item {
|
|
|
- margin: 10px 0 10px 10px;
|
|
|
- input {
|
|
|
- margin: 0 5px;
|
|
|
- width: 20px;
|
|
|
- text-align: center;
|
|
|
+ .huang {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 720px;
|
|
|
+
|
|
|
+ .h_title {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex: 1;
|
|
|
+ div {
|
|
|
+ font-size: 18px;
|
|
|
+ margin: 0 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .h_time {
|
|
|
+ flex: 10;
|
|
|
+ overflow: auto;
|
|
|
+
|
|
|
+ .card {
|
|
|
+ position: relative;
|
|
|
+ margin: 10px 20px;
|
|
|
+ .card_title {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ margin: 5px 0;
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 17px;
|
|
|
+ .icon {
|
|
|
+ margin-left: 10px;
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ background: url(../../assets/edit.png) no-repeat center;
|
|
|
+ background-size: 80% 80%;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .card_count {
|
|
|
+ margin: 20px 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-around;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ .card_time {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ margin: 20px 0;
|
|
|
+ }
|
|
|
+ .card_close {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ background: url(../../assets/close.png) no-repeat center;
|
|
|
+ background-size: 50% 50%;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .h_foot {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ flex: 3;
|
|
|
+ div {
|
|
|
+ flex: 1;
|
|
|
+ margin: 10px;
|
|
|
+ input {
|
|
|
+ margin: 0 5px;
|
|
|
+ width: 30px;
|
|
|
+ height: 20px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -437,4 +726,11 @@ export default {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
}
|
|
|
+::v-deep .el-card__body {
|
|
|
+ padding: 0px;
|
|
|
+}
|
|
|
+::v-deep .el-date-editor.el-input,
|
|
|
+.el-date-editor.el-input__inner {
|
|
|
+ width: 150px;
|
|
|
+}
|
|
|
</style>
|