Commit 154b446b by xiaohai

build for test

parent 48af005b
......@@ -3,21 +3,24 @@
<div class="title-div">
<span>{{title}}</span>
<div class="hurdle"></div>
<a class="a-href" @click="showEdit = !showEdit">编辑</a>
<a class="a-href" @click="showEdit = true">编辑</a>
</div>
<el-form
class="info-form"
:rules="rules"
inline
label-width="150px"
v-model="info">
ref="cell_form"
:model="info">
<template v-for="(item, idx) in fieldList">
<el-form-item :label="item.title+':'" class="item-width" :key="item.fieldCode+'_'+idx">
<template v-if="!!item.systemFlag">
<template v-if="showEdit">
<el-input v-model="info[item.fieldCode]" v-if="item.fieldType == 0 || item.fieldType == 6"></el-input>
<el-input v-model="info[item.fieldCode]" v-else-if="item.fieldType == 1" type="textarea" autosize></el-input>
<el-form-item :label="item.title+':'" class="item-width" :key="item.fieldCode+'_'+idx" :prop="item.fieldCode">
<template v-if="showEdit">
<el-input v-model="info[item.fieldCode]" v-if="item.fieldType == 0 || item.fieldType == 6" :placeholder="item.fieldDescription" :disabled="item.fieldCode == 'clerkName' || item.fieldCode == 'clerkPhone'"></el-input>
<el-input v-model="info[item.fieldCode]" v-else-if="item.fieldType == 1" type="textarea" autosize></el-input>
<template
v-else-if="item.fieldType == 2 || item.fieldType == 3">
<el-select
v-else-if="item.fieldType == 2 || item.fieldType == 3"
v-if="item.systemFlag == 1"
:multiple="item.fieldType == 3"
:collapse-tags="item.fieldType == 3"
v-model="info[item.fieldCode]"
......@@ -29,97 +32,77 @@
:value="cho.key">
</el-option>
</el-select>
<el-date-picker
:format="item.fieldOperations.typeValue"
value-format="timestamp"
v-else-if="item.fieldType == 4"
v-model="info[item.fieldCode]"
type="date"
:placeholder="item.fieldDescription">
</el-date-picker>
<el-date-picker
v-else-if="item.fieldType == 5"
v-model="info[item.fieldCode]"
type="daterange"
range-separator="至"
:format="item.fieldOperations.typeValue"
value-format="timestamp"
:start-placeholder="item.fieldOperations.startDescription"
:end-placeholder="item.fieldOperations.endDescription">
</el-date-picker>
<vue-gic-upload-image
v-else-if="item.fieldType == 7"
projectName="gic-web"
wxFlag="0"
:actionUrl="uploadUrl"
:imageList="(!!info[item.fieldCode] ? info[item.fieldCode].split(',') : [])"
:limitW="500"
:limitH="500"
:maxImageLength="5"
@uploadOnSuccess="uploadOnSuccess"
@sortImg="sortImg"
@deleteImage="deleteImage">
</vue-gic-upload-image>
</template>
<template v-else>
<div>{{info[item.fieldCode]}}</div>
</template>
</template>
<template v-else>
<el-input v-model="defineObj[item.fieldCode]" v-if="item.fieldType == 0 || item.fieldType == 6"></el-input>
<el-input v-model="defineObj[item.fieldCode]" v-else-if="item.fieldType == 1" type="textarea" autosize></el-input>
<el-select
v-else-if="item.fieldType == 2 || item.fieldType == 3"
v-else
:multiple="item.fieldType == 3"
:collapse-tags="item.fieldType == 3"
v-model="defineObj[item.fieldCode]"
v-model="info[item.fieldCode]"
:placeholder="item.fieldDescription">
<el-option
v-for="cho in item.fieldOperations.fieldContent"
:key="cho.key"
v-for="(cho, index) in item.fieldOperations.fieldContent"
:key="cho.key + '_' + index"
:label="cho.name"
:value="cho.key">
:value="cho.name">
</el-option>
</el-select>
<el-date-picker
:format="item.fieldOperations.typeValue"
value-format="timestamp"
v-else-if="item.fieldType == 4"
v-model="defineObj[item.fieldCode]"
type="date"
:placeholder="item.fieldDescription">
</el-date-picker>
<el-date-picker
v-else-if="item.fieldType == 5"
v-model="defineObj[item.fieldCode]"
type="daterange"
range-separator="至"
:format="item.fieldOperations.typeValue"
value-format="timestamp"
:start-placeholder="item.fieldOperations.startDescription"
:end-placeholder="item.fieldOperations.endDescription">
</el-date-picker>
<vue-gic-upload-image
v-else-if="item.fieldType == 7"
projectName="gic-web"
wxFlag="0"
:actionUrl="uploadUrl"
:imageList="(!!defineObj[item.fieldCode] ? defineObj[item.fieldCode].split(',') : [])"
:limitW="500"
:limitH="500"
:maxImageLength="5"
@uploadOnSuccess="uploadOnSuccess"
@sortImg="sortImg"
@deleteImage="deleteImage">
</vue-gic-upload-image>
<div v-else>{{defineObj[item.fieldCode]}}</div>
</template>
<el-date-picker
:format="item.fieldOperations.typeValue"
value-format="timestamp"
v-else-if="item.fieldType == 4"
v-model="info[item.fieldCode]"
type="date"
:placeholder="item.fieldDescription">
</el-date-picker>
<el-date-picker
v-else-if="item.fieldType == 5"
v-model="info[item.fieldCode]"
type="daterange"
range-separator="至"
:format="item.fieldOperations.typeValue"
value-format="timestamp"
:start-placeholder="item.fieldOperations.startDescription"
:end-placeholder="item.fieldOperations.endDescription">
</el-date-picker>
<vue-office-upload-image
v-else-if="item.fieldType == 7"
projectName="haoban-manage-web"
wxFlag="0"
:actionUrl="uploadUrl"
:imageList="[(!!info[item.fieldCode] ? info[item.fieldCode].split(',') : [])]"
:limitW="500"
:limitH="500"
:maxImageLength="5"
@uploadOnSuccess="uploadOnSuccess"
@sortImg="sortImg"
@deleteImage="deleteImage">
</vue-office-upload-image>
</template>
<template v-else>
<div v-if="item.fieldType == 0 || item.fieldType == 1 || item.fieldType == 6">{{info[item.fieldCode]}}</div>
<template v-else-if="item.fieldType == 2">
<div v-if="item.systemFlag == 1">{{item.fieldOperations.fieldContent[(info[item.fieldCode] || 1) * 1 - 1].name}}</div>
<div v-else>{{info[item.fieldCode]}}</div>
</template>
<div v-else-if="item.fieldType == 3"></div>
<div v-else-if="item.fieldType == 4">{{info[item.fieldCode] | formatDate(item.fieldOperations.typeValue)}}</div>
<div v-else-if="item.fieldType == 5">{{info[item.fieldCode]}}</div>
<div v-else-if="item.fieldType == 7">
<img class="item-imgs" :src="img" v-for="(img, index) in (!!info[item.fieldCode] ? info[item.fieldCode].split(',') : [])" :key="index + img">
</div>
</template>
</el-form-item>
</template>
</el-form>
<div class="handle-form-btns t-ct m-b-60" v-if="showEdit">
<el-button type="primary" @click="saveEdit">保存</el-button>
<el-button @click="cancelEdit">取消</el-button>
</div>
</div>
</template>
<script>
import { formatDate } from '@/utils/index';
import { deepClone } from '@/utils/index';
import { getRequest, postRequest, postJsonRequest } from '@/api/api';
let soan= `<span></span>`;
export default {
......@@ -129,6 +112,10 @@ export default {
type: Object,
required: true
},
staticInfo: {
type: Object,
required: true
},
items: {
type: Array,
required: true
......@@ -142,25 +129,115 @@ export default {
required: true
}
},
filters: {
formatDate
},
data() {
let local = window.location.origin;
if (local.indexOf('localhost')!= -1) {
local = 'http://www.gicdev.com';
}
return {
showEdit: false,
uploadUrl: local + "/haoban-manage-web/upload-img"
uploadUrl: "/haoban-manage-web/upload-img"
};
},
methods: {
uploadOnSuccess() {},
uploadOnSuccess(res, list) {
list.push(res.file);
},
sortImg() {},
deleteImage() {}
deleteImage() {},
saveEdit() {
let ths = this;
ths.$refs.cell_form.validate(valid => {
if (valid) {
let newInfo = deepClone(ths.info);
let params = {};
let fieldList = ths.fieldList;
let defineObj = JSON.parse(ths.staticInfo.defineString);
let objToString = {};
fieldList.forEach(field => { // 将当前单元格的所有自定义字段抽离出来转化成json字符串
params[field.fieldCode] = newInfo[field.fieldCode];
for (let key in defineObj) {
if (field.fieldCode == key) {
objToString[key] = newInfo[key];
delete params[key];
}
}
});
params["jsonString"] = JSON.stringify(objToString) == "{}" ? "" : JSON.stringify(objToString);
ths.submitEdit(params);
}
});
},
submitEdit(params) {
let ths = this;
getRequest("/haoban-manage-web/record/save-record-detail", params)
.then(res => {
console.log(res, "submitEdit");
})
.catch(e => {
ths.$message({
message: e.message
});
});
},
cancelEdit() {
let nowObj = this.info;
let oldObj = this.staticInfo;
for (let key in nowObj) {
nowObj[key] = oldObj[key];
}
this.showEdit = false;
}
},
computed: {
defineObj() {
console.log(JSON.parse(this.info.defineString));
return JSON.parse(this.info.defineString);
console.log(JSON.parse(this.clerkInfo.defineString));
return JSON.parse(this.clerkInfo.defineString);
},
rules() {
let ths = this;
let obj = {};
let fields = ths.fieldList;
fields.forEach(field => {
let arr = [];
if (!!field.isMust) {
arr.push({
required: true,
message: field.fieldDescription + field.fieldName,
trigger: "change"
});
}
if (field.fieldType == 0 || field.fieldType == 1) {
if (!!field.minCount && field.maxCount) {
arr.push({
min: field.minCount,
message: "至少填写" + field.minCount + "个字符",
trigger: "change"
});
}
if (!field.minCount && !!field.maxCount) {
console.log(field.fieldCode + "====" + field.maxCount);
arr.push({
max: field.maxCount,
message: "至多填写" + field.maxCount + "个字符",
trigger: "change"
});
}
if (!!field.minCount && !!field.maxCount) {
arr.push({
min: field.minCount,
max: field.maxCount,
message: '长度在 ' + field.minCount +' 到 ' + field.maxCount + '个字符',
trigger: "change"
});
}
}
if (field.fieldType == 6) {
arr.push({type: 'number', message: field.fieldName + '必须为数字值'});
}
obj[field.fieldCode] = arr;
});
console.log(obj);
return obj;
}
}
}
......@@ -184,12 +261,15 @@ export default {
}
}
.info-form {
margin-bottom: 65px;
margin-bottom: 50px;
.item-width {
width: 49%;
.el-input, .el-textarea {
width: 350px;
}
.item-imgs {
height: 104px;
}
}
}
}
......
......@@ -17,10 +17,10 @@ import vueOfficeArea from '@gic-test/vue-office-area'
// 新增公共 footer插件
import vueGicFooter from '@gic-test/vue-gic-footer'
import vueGicImgPreview from '@gic-test/vue-gic-img-preview'
import vueGicUploadImage from '@gic-test/vue-gic-upload-image'
import vueOfficeUploadImage from '@gic-test/vue-office-upload-image'
Vue.use(vueGicImgPreview)
Vue.use(vueGicUploadImage)
Vue.use(vueOfficeUploadImage)
Vue.use(vueGicFooter)
Vue.use(vueOfficeArea)
Vue.use(vueOfficeAside)
......
......@@ -105,6 +105,11 @@ export const constantRouterMap = [
component: _import('contacts','recordInfo')
},
{
path: '/recordIo',
name: '导入导出员工档案',
component: _import('contacts','recordIo')
},
{
path: '/shareContact',
name: '共享通讯录',
component: _import('contacts','shareContact')
......
......@@ -34,12 +34,14 @@ export let date = {
switch (format) {
case "YY-MM":
case "yyyy-MM":
result = year + "-" + month;
break;
case "MM-DD":
result = month + "-" + day;
break;
case "YY-MM-DD":
case "YY-MM-DD":
case "yyyy-MM-dd":
result = year + "-" + month + "-" + day;
break;
case "YY-MM-DD HH:MM:SS":
......
......@@ -3,7 +3,7 @@
<div class="top-area">
<div class="top-title">
<span class="title-span">在职员工</span>
<a href="">
<a href="#/recordIo?importCode=record">
<el-button type="primary">导入员工档案<i class="el-icon-upload el-icon--right"></i></el-button>
</a>
</div>
......
......@@ -10,13 +10,13 @@
</div>
</div>
<template v-for="field in fieldList">
<editable-cell v-if="field.childrens" :key="field.fieldCode" :info="info" :items="items" :title="field.title" :fieldList="field.childrens"></editable-cell>
<editable-cell v-if="field.childrens" :key="field.fieldCode" :info="info" :staticInfo="staticInfo" :items="items" :title="field.title" :fieldList="field.childrens"></editable-cell>
</template>
</div>
</template>
<script>
import { getRequest, postRequest, postJsonRequest } from '@/api/api';
import { deepCopy } from '@/utils/index';
import { deepClone } from '@/utils/index';
import editableCell from "components/employeeRecord/editableCell";
export default {
name: "recordInfo",
......@@ -26,13 +26,14 @@ export default {
data() {
return {
info: {},
staticInfo: {},
statusList: ["正式", "试用", "离职"],
items: [],
fieldList: [],
}
},
methods: {
getEmployeeDetail() {
getEmployeeDetail() { // 获取员工详情
let ths = this;
let params = {
recordId: ths.$route.query.recordId
......@@ -41,7 +42,7 @@ export default {
.then(res => {
console.log(res, "info");
if (res.data.errorCode == 1) {
ths.info = res.data.result;
ths.getTemplate(res.data.result);
} else {
ths.$message.error({
message: res.data.message
......@@ -54,13 +55,13 @@ export default {
});
});
},
getTemplate() {
getTemplate(clerkInfo) { // 获取档案模板
let ths = this;
getRequest("/haoban-manage-web/record/employee-find-template", {})
.then(res => {
console.log(res, "模板");
if (res.data.errorCode == 1) {
ths.formatTemplateList(res.data.result);
ths.formatTemplateList(res.data.result, clerkInfo);
} else {
ths.$message.error({
message: res.data.message
......@@ -73,15 +74,24 @@ export default {
});
});
},
formatTemplateList(list) {
formatTemplateList(list, clerkInfo) { // 格式化档案详情和模板
let ths = this;
let fieldList = this.fieldList;
let copyData = list;
let obj = JSON.parse(clerkInfo.defineString);
let cInfo = deepClone(clerkInfo);
for (let key in obj) {
cInfo[key] = obj[key];
}
list.forEach(tem => {
if (tem.parentCode != 0) {
tem.fieldOperations = JSON.parse(tem.fieldOperations);
}
console.log(tem.fieldType, tem.fieldOperations, tem);
if (tem.fieldType == 6) {
cInfo[tem.fieldCode] *= 1; // 强制转为数字类型
clerkInfo[tem.fieldCode] *= 1;
}
// console.log(tem.fieldType, tem.fieldName, tem.fieldOperations, tem);
tem.title = tem.fieldName;
let arr = [];
copyData.forEach(li => {
......@@ -100,11 +110,17 @@ export default {
fieldList.sort(function(a,b){
return a.sort*1-b.sort*1;
});
console.log(fieldList, "new fieldList");
console.log(fieldList, clerkInfo, "new fieldList");
this.info = cInfo;
this.staticInfo = clerkInfo;
// ths.getEmployeeDetail();
},
getHistoryList() { // 获取员工历史纪录
}
},
beforeMount() {
this.getTemplate();
// this.getTemplate();
this.getEmployeeDetail();
}
}
......
<template>
<div class="io-container">
<ul class="tip-area">
<li class="tip">姓名必须和好办企业通讯录中的员工姓名保持一致,手机号必须为员工注册好办的手机号</li>
<li class="tip">员工档案导入时,直接以手机号去做匹配,通讯录中不存在的将无法导入(模板中配置的部门、职位、code,这些字段信息请保持与企业通讯录中一致,这几个字段的信息将不会修改通讯录的信息,直接取该成员对应的通讯录的字段信息)</li>
<li class="tip">如果想要新增字段,可在后台档案设置中增加,再导入模板</li>
<li class="tip">字段类型为图片上传、多选的字段无法导入、导出</li>
<li class="tip">确保导入的表头字段和后台配置表头字段的名称一致(模板下载时间不可修改)</li>
<li class="tip">由于数据量可能较大,每次最多导入2000条员工档案,若超过只取前2000条,可以分多次导入</li>
</ul>
<el-radio-group v-model="type" class="m-t-20" @change="resetList">
<el-radio-button label="import">导入员工档案</el-radio-button>
<el-radio-button label="export">导出/修改员工档案</el-radio-button>
<el-radio-button label="note">错误记录</el-radio-button>
</el-radio-group>
<div class="handle-area import" v-if="type == 'import'">
<div class="step-div" style="margin-bottom :90px;">
<span class="ft-large"></span>下载模板
<a href="http://www.gicdev.com/haoban-manage-web/record/export-record-template.json" class="d-u-btn">
<el-button type="primary">下载<i class="iconfont icon-icon_yunxiazai m-l-5"></i></el-button>
</a>
</div>
<div class="step-div">
<span class="ft-large"></span>上传员工档案
<div class="d-u-btn m-t-20">
<el-upload
class="upload-demo"
ref="upload"
:action="url"
:on-success="uploadSuccess"
:on-change="getChange"
:multiple="false"
:file-list="fileList"
:auto-upload="false">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<div slot="tip" class="el-upload__tip">文件格式必须为xls或xlsx格式</div>
</el-upload>
</div>
</div>
<div class="up-btn-div">
<el-button type="primary" @click="submitUpload('upload')" :disabled="fileList.length == 0">上传</el-button>
</div>
</div>
<div class="handle-area import" v-else-if="type == 'export'">
<div class="step-div" style="margin-bottom :90px;">
<span class="ft-large"></span>导出员工档案
<a class="d-u-btn" href="http://www.gicdev.com/haoban-manage-web/record/export-record-template.json">
<el-button type="primary">下载<i class="iconfont icon-icon_yunxiazai m-l-5"></i></el-button>
</a>
</div>
<div class="step-div">
<span class="ft-large"></span>上传更新后的员工档案
<div class="d-u-btn m-t-20">
<el-upload
class="upload-demo"
ref="uploadEdit"
:action="url"
:on-success="uploadSuccess"
:on-change="getChange"
:multiple="false"
:file-list="fileList"
:auto-upload="false">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<div slot="tip" class="el-upload__tip">文件格式必须为xls或xlsx格式</div>
</el-upload>
</div>
</div>
<div class="up-btn-div">
<el-button type="primary" @click="submitUpload('uploadEdit')" :disabled="fileList.length == 0">上传</el-button>
</div>
</div>
<div class="error-log import" v-else>
<div class="title-area">
<div class="tip">
导入总条数:0条,成功导入0条,<span class="red">错误导入0条</span>
</div>
<a :href="'http://www.gicdev.com/haoban-manage-web/record//error-log-export?importCode='+$route.query.importCode">
<el-button type="primary">导出错误记录</el-button>
</a>
</div>
<el-table
v-loading ="loading"
:data="logList"
class="m-t-20"
style="width: 100%">
<el-table-column
type="index"
width="50"
label="序号">
</el-table-column>
<el-table-column
label="错误提示"
prop="failReason"
></el-table-column>
<el-table-column
label="姓名"
prop="name"
></el-table-column>
<el-table-column
label="手机号"
prop="phoneNumber"
></el-table-column>
<el-table-column
label="部门ID"
prop="departmentId"
></el-table-column>
<el-table-column
label="职位"
prop="positionName"
></el-table-column>
<el-table-column
label="是否此部门负责人(是/否)"
prop="isManager"
>
<template slot-scope="scope">
{{scope.row.isManager == 1 ? "是" : "否"}}
</template>
</el-table-column>
<el-table-column
label="入职时间"
prop="hireDate"
></el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:page-sizes="[20, 40, 60, 80]"
:page-size="pageSize"
:current-page="currentPage"
layout="total, sizes, prev, pager, next"
:total="total">
</el-pagination>
</div>
</div>
</div>
</template>
<script>
import uploadExcelComponent from "components/uploadExcel/index";
import { getRequest, postRequest, postJsonRequest } from '@/api/api';
export default {
name: "employee-io",
components: {
uploadExcelComponent
},
data() {
let local = window.location.origin;
if (local.indexOf('localhost')!= -1) {
local = 'http://www.gicdev.com';
}
return {
type: "import",
fileList: [],
url: local + "/haoban-manage-web/record/record-template-file-upload",
logList: [],
loading: true,
pageSize: 20,
currentPage: 1,
total: 0
};
},
methods: {
handleSizeChange(val) {
this.pageSize = val;
this.getErrorNote();
},
handleCurrentChange(val) {
this.currentPage = val;
this.getErrorNote();
},
resetList(val) {
this.fileList = [];
if (val == "note") {
this.getErrorNote();
}
},
getErrorNote() {
let ths = this;
let params = {
departmentId: ths.$route.query.departmentId,
importCode: ths.$route.query.importCode
};
getRequest("/haoban-manage-web/record/find-error-log", params)
.then(res => {
console.log(res);
if (res.data.errorCode == 1) {
console.log(res.data);
ths.total = res.data.result.totalCount;
ths.logList = res.data.result.result;
ths.loading = false;
} else {
ths.$message.error({
message: res.data.message
});
}
})
.catch(e => {
ths.$message.error({
message: e.message
})
});
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
uploadSuccess() {
this.fileList = [];
this.type = "note";
this.getErrorNote();
},
submitUpload(upload) {
this.$refs[upload].submit();
},
getChange(file, fileList) {
console.log(file, fileList);
this.fileList = fileList;
}
},
beforeMount() {
if (this.type == "note") {
this.getErrorNote();
}
}
}
</script>
<style lang="scss">
.io-container {
width: 100%;
height: 538px;
background: #fff;
box-sizing: border-box;
padding: 28px 32px;
overflow: auto;
.tip-area {
width:100%;
background:rgba(236,245,255,1);
border:1px solid rgba(179,216,255,1);
border-radius:4px;
padding: 10px;
font-size:13px;
font-weight:400;
color:rgba(96,98,102,1);
.tip {
line-height: 24px;
position: relative;
padding-left: 16px;
&:last-child {
margin-bottom: 0;
}
.radio {
width:6px;
height:6px;
background:rgba(64,158,255,1);
border-radius:50%;
}
&::before {
position: absolute;
content: "";
width:6px;
height:6px;
background:rgba(64,158,255,1);
border-radius:50%;
top: 9px;
left: 0;
}
}
}
.error-log {
margin-top: 24px;
.title-area {
display: flex;
height: 32px;
line-height: 32px;
.tip {
flex: 1;
.red {
color: red;
}
}
}
.pagination {
margin-top: 30px;
text-align: right;
}
}
.handle-area {
height: 310px;
background:rgba(255,255,255,1);
border:1px solid rgba(220,223,230,1);
border-radius:4px;
padding: 25px 20px;
margin-top: 24px;
color: #606266;
.step-div {
.d-u-btn {
display:inline-block;
margin-left: 10px;
margin-right: 10px;
vertical-align: middle;
.iconfont {
margin-left: 5px;
}
.warming {
font-size:12px;
font-weight:400;
color:rgba(96,98,102,1);
line-height:30px;
margin-top: 5px;
}
}
.ft-large {
font-size: 20px;
margin-right: 10px;
color: #909399;
}
}
.up-btn-div {
text-align: center;
margin-top: 20px;
}
}
}
</style>
......@@ -332,6 +332,9 @@ input:focus {
.t-rt {
text-align: right;
}
.t-ct {
text-align: center;
}
.c-909399 {
color: #909399;
}
......@@ -363,6 +366,9 @@ input:focus {
.m-b-10 {
margin-bottom: 10px;
}
.m-b-60 {
margin-bottom: 60px;
}
.font-0 .el-form-item__content, .dialog-footer {
font-size: 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment