Commit 9804c50d authored by 高宇's avatar 高宇

完成工作日志项目;

parent debf18c1
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
console.log(window.VupPortalSdk.vueAppDevSdk) console.log(window.VupPortalSdk.vueAppDevSdk)
var portal = VupPortalSdk.vueAppDevSdk var portal = VupPortalSdk.vueAppDevSdk
var $ = portal.jQuery var $ = portal.jQuery
var portalName = 'work-log' var portalName = 'worklog'
var menuConfig = { var menuConfig = {
menus: [ menus: [
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
"isRouteShow": 1, "isRouteShow": 1,
"title": "工作日志", "title": "工作日志",
"appName": portalName, "appName": portalName,
"url": "/list" "url": "/worklog"
}, },
{ {
"icon": "fa-book", "icon": "fa-book",
......
...@@ -12,6 +12,22 @@ export default { ...@@ -12,6 +12,22 @@ export default {
delWorkLog: { delWorkLog: {
url: '/vue/work-log/delete' url: '/vue/work-log/delete'
}, },
// 获取工作日志新建 option
getWorkLogNewOptions: {
url: '/vue/work-log/get-new'
},
// 获取工作日志编辑
getWorkLogEdit: {
url: '/vue/work-log/get-edit'
},
// 工作日志编辑
saveWorkLogEdit: {
url: '/vue/work-log/save-edit'
},
// 工作日志新建
saveWorkLogAdd: {
url: '/vue/work-log/save-new'
},
// 留言 // 留言
getCommentList: { getCommentList: {
...@@ -26,5 +42,27 @@ export default { ...@@ -26,5 +42,27 @@ export default {
// 留言删除 // 留言删除
deleteComment: { deleteComment: {
url: '/vue/comment/delete' url: '/vue/comment/delete'
},
// 获取编辑信息
getClient: {
url: '/vue/client/get-edit'
},
// 获取客户工作日志列表
getWorkLogClient: {
url: '/vue/work-log/of-client'
},
// 搜索客户名称列表
searchClientByName: {
url: '/vue/search/client-by-name'
},
// 搜索客户联系人
searchContactByClientId: {
url: '/vue/search/contact-by-client-id'
},
// 搜索客户项目
searchProjectByClientId: {
url: '/vue/search/project-by-client-id'
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<section class="client-nav"> <section class="client-nav">
<router-link v-for="(nav, key) in navs" <router-link v-for="(nav, key) in navs"
:key="key" :key="key"
:to="{name: nav.routerName, params: {id: $route.params.id}}" :to="{app: nav.appName, name: nav.routerName, params: {id: $route.params.id}}"
:class="['btn', 'btn-default', 'btn-sm', {'btn-info': routeName === nav.routerName}, {'disabled': routeName === nav.routerName}]"> :class="['btn', 'btn-default', 'btn-sm', {'btn-info': routeName === nav.routerName}, {'disabled': routeName === nav.routerName}]">
<i :class="['fa', 'fa-fw',nav.icon]"></i> <i :class="['fa', 'fa-fw',nav.icon]"></i>
{{nav.title}} {{nav.title}}
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :span="24" class="entity-name"> <el-col :span="24" class="entity-name">
<i class="fa fa-star" aria-hidden="true"></i> <i class="fa fa-star" aria-hidden="true"></i>
<router-link :to="toView(item)">{{ item.client.name }}</router-link> <router-link :to="toView(item)" v-if="Object.keys(item.client).length > 0">{{ item.client.name }}</router-link>
<span v-else>客户名称{{noneText}}</span>
</el-col> </el-col>
<el-col :span="24" class="entity-name"> <el-col :span="24" class="entity-name">
<i class="fa fa-th-list" aria-hidden="true"></i> <i class="fa fa-th-list" aria-hidden="true"></i>
<span>{{ Object.keys(item.project).length > 0 ? item.project.name : '(未设置)' }}</span> <span>{{ Object.keys(item.project).length > 0 ? item.project.name : noneText }}</span>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<img class="user-avatar rounded-circle" :src="item.createdBy.avatar.name"> <img class="user-avatar rounded-circle" :src="item.createdBy.avatar.name">
...@@ -109,9 +110,9 @@ ...@@ -109,9 +110,9 @@
}, },
toView (item) { toView (item) {
let obj = { let obj = {
name: 'viewClient', name: 'ofClient',
params: { params: {
id: item.id id: item.client_id
} }
} }
return obj return obj
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
<span>{{label}}</span> <span>{{label}}</span>
</el-col> </el-col>
<el-col :span="14"> <el-col :span="14">
<el-checkbox-group v-model="items" size="mini"> <el-checkbox-group v-model="items" size="mini" v-if="optionsList.length > 0">
<el-checkbox-button v-for="(check, key) in optionsList" :value="check.value" :label="check.name" :key="key">{{check.name}}</el-checkbox-button> <el-checkbox-button v-for="(check, key) in optionsList" :label="check.key" :key="key">{{check.name}}</el-checkbox-button>
</el-checkbox-group> </el-checkbox-group>
<span style="font-size:12px; color: #ccc;" v-else>没有数据</span>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<slot name="formError"></slot> <slot name="formError"></slot>
......
<template>
<section class="single-date-time-picker">
<el-row :gutter="10">
<el-col :span="4" :class="['client-label', 'text-right', {'required': required}]">
<span>{{startLabel}}</span>
</el-col>
<el-col :span="14">
<el-row :gutter="10">
<el-col :span="24" class="calc-timer">
<el-row :gutter="2">
<el-col :span="12">
<el-date-picker
size="mini"
:clearable="false"
v-model="startDateTime.date"
type="date"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
placeholder="选择日期">
</el-date-picker>
</el-col>
<el-col :span="12">
<el-time-select
size="mini"
:clearable="false"
v-model="startDateTime.time"
:picker-options="{start: '00:00', step: '00:15', end: '24:00'}"
placeholder="选择时间">
</el-time-select>
</el-col>
</el-row>
</el-col>
</el-row>
<span class="tips"><em>{{tips}}</em></span>
</el-col>
<el-col :span="6">
<slot name="formError"></slot>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="4" class="client-label text-right">
<span>{{calcLabel}}</span>
</el-col>
<el-col :span="14">
<div class="calc-input">
<div>
<el-button type="primary" size="mini" icon="el-icon-minus" @click="reduceMin"></el-button>
<el-input v-model="calcTime" size="mini" placeholder="间隔时间" @keyup.native="handleInput">
<template slot="append">分钟</template>
</el-input>
<el-button type="primary" size="mini" icon="el-icon-plus" @click="plusMin"></el-button>
</div>
</div>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="4" :class="['client-label', 'text-right', {'required': required}]">
<span>{{endLabel}}</span>
</el-col>
<el-col :span="14">
<el-row :gutter="10">
<el-col :span="24" class="calc-timer">
<el-row :gutter="2">
<el-col :span="12">
<el-date-picker
:clearable="false"
size="mini"
v-model="endDateTime.date"
type="date"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
placeholder="选择日期">
</el-date-picker>
</el-col>
<el-col :span="12">
<el-time-select
size="mini"
:clearable="false"
v-model="endDateTime.time"
:picker-options="{start: '00:00', step: '00:15', end: '24:00'}"
placeholder="选择时间">
</el-time-select>
</el-col>
</el-row>
</el-col>
</el-row>
</el-col>
<el-col :span="6">
<slot name="formError"></slot>
<span class="el-form-item__error">{{calcError}}</span>
</el-col>
</el-row>
</section>
</template>
<script>
import itemMixin from '../../lib/singleItemMixin'
export default {
name: 'single-date-time-picker',
mixins: [itemMixin],
data () {
return {
calcTime: 0,
calcError: ''
}
},
props: ['pickerType'],
methods: {
handleInput (e) {
this.calcTime = e.target.value.replace(/[^\d]/g, 0)
},
reduceMin () {
this.calcTime -= 15
if (this.calcTime < 0) {
this.calcTime = 0
return
}
},
plusMin () {
this.calcTime += 15
if (this.calcTime >= 1440) {
this.calcTime = 1440
}
},
compareTime () {
let start = new Date(this.start_at)
let end = new Date(this.end_at)
let diffTime = end.getTime() - start.getTime()
let days = Math.floor(diffTime / (24 * 3600 * 1000))
let level = diffTime % (24 * 3600 * 1000)
let hours = Math.floor(level / (3600 * 1000))
var leave2 = level % (3600 * 1000) // 计算小时数后剩余的毫秒数
var minutes = Math.floor(leave2 / (60 * 1000))
// console.log(minutes)
this.calcTime = minutes + hours * 60 + days * 24 * 60
if (this.calcTime < 0) {
this.calcTime = 0
}
if (start >= end) {
this.calcError = '结束时间的值必须大于"开始时间"。'
} else {
this.calcError = ''
}
},
updateTime (val) {
if (this.startDateTime.date === '' && this.startDateTime.time === '') {
return
}
if (val > 1440) {
this.calcError = '请检查结束时间,看起来您工作了超过24个小时!'
}
if (val === '') {
this.calcTime = 0
return
}
let start = new Date(this.start_at)
let min = start.getMinutes()
let minutes = (min + parseInt(val)) % 60
let hours = start.getHours() + Math.floor((min + parseInt(val)) / 60)
// let days = start.getDate() + Math.floor(start.getHours() / 24)
// console.log(start.getDate())
start.setMinutes(minutes)
if (hours === 24) {
start.setHours(0)
start.setMinutes(0)
start.setDate(start.getDate() + 1)
} else {
start.setHours(hours)
}
this.endDateTime.date = start.getFullYear() + '-' + ((start.getMonth() + 1) + 100).toString().slice(1, 3) + '-' + (start.getDate() + 100).toString().slice(1, 3)
this.endDateTime.time = (start.getHours() + 100).toString().slice(1, 3) + ':' + (start.getMinutes() + 100).toString().slice(1, 3)
// console.log(this.endDateTime.data)
}
},
watch: {
'startDateTimeItem' (val) {
if (val !== '') {
let t = val.split(' ')
this.startDateTime.date = t[0]
this.startDateTime.time = t[1]
}
},
'endDateTimeItem' (val) {
if (val !== '') {
let t = val.split(' ')
this.endDateTime.date = t[0]
this.endDateTime.time = t[1]
}
},
'startDateTime.date' (val) {
if (this.startDateTime.time !== '') {
this.start_at = val + ' ' + this.startDateTime.time
if (this.endDateTime.date === '' || this.endDateTime.date === '') {
this.endDateTime.date = val
this.endDateTime.time = this.startDateTime.time
}
}
},
'startDateTime.time' (val) {
if (this.startDateTime.date !== '') {
this.start_at = this.startDateTime.date + ' ' + val
if (this.endDateTime.date === '' || this.endDateTime.date === '') {
this.endDateTime.date = this.startDateTime.date
this.endDateTime.time = val
}
}
},
'endDateTime.date' (val) {
if (val) {
if (this.endDateTime.time !== '') {
this.end_at = val + ' ' + this.endDateTime.time
}
}
},
'endDateTime.time' (val) {
// console.log(val)
if (val) {
if (this.endDateTime.date !== '') {
this.end_at = this.endDateTime.date + ' ' + val
}
}
},
'start_at' (val) {
this.compareTime()
this.$emit('update:startItem', val)
},
'end_at' (val) {
if (this.start_at !== '') {
this.compareTime()
}
this.$emit('update:endItem', val)
},
'calcTime' (val) {
this.updateTime(val)
}
}
}
</script>
<style scoped>
.single-date-time-picker > .el-row:not(:last-child) {
margin-bottom: 15px;
}
</style>
<style>
.calc-input {
display: inline-block;
width: 100%;
}
.calc-input > div {
display: flex;
}
.calc-input > div > .el-button {
margin-right: 0;
color: #333;
background-color: #fff;
border-color: #ccc;
padding: 7px 9px;
}
.calc-input > div > .el-button:hover {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.calc-input > div > .el-input {
border: 1px solid #DCDFE6;
}
.calc-input > div > .el-input input {
text-align: center;
border: none;
}
.calc-input > div > .el-input .el-input-group__append {
border: none;
}
.calc-timer .el-input {
width: 100%;
}
</style>
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<span>{{label}}</span> <span>{{label}}</span>
</el-col> </el-col>
<el-col :span="14"> <el-col :span="14">
<el-radio-group size="mini" v-model="item"> <el-radio-group size="mini" v-model="item" @change="setRadioOption">
<el-radio-button v-for="(radio, key) in optionsList" :key="key" :label="radio.key"> <el-radio-button v-for="(radio, key) in optionsList" :key="key" :label="radio.key">
{{radio.name}} {{radio.name}}
</el-radio-button> </el-radio-button>
...@@ -23,7 +23,15 @@ ...@@ -23,7 +23,15 @@
import itemMixin from '../../lib/singleItemMixin' import itemMixin from '../../lib/singleItemMixin'
export default { export default {
name: 'single-radio', name: 'single-radio',
mixins: [itemMixin] mixins: [itemMixin],
methods: {
setRadioOption (val) {
if (this.setOption) {
this.setOption(val)
}
}
},
props: ['setOption']
} }
</script> </script>
......
<template>
<section class="single-search-input">
<el-row :gutter="10">
<el-col :span="4" :class="['client-label', 'text-right', {'required': required}]">
<span>{{label}}</span>
</el-col>
<el-col :span="14">
<el-autocomplete
size="mini"
v-model="searchItem"
:hide-loading="true"
:trigger-on-focus="false"
:fetch-suggestions="querySearchAsync"
placeholder="输入查找客户"
@select="handleSelect"
></el-autocomplete>
</el-col>
<el-col :span="6">
<slot name="formError"></slot>
</el-col>
</el-row>
</section>
</template>
<script>
import itemMixin from '../../lib/singleItemMixin'
import {
requestAPI,
api
} from '@/lib/commonMixin'
export default {
name: 'single-search-input',
mixins: [itemMixin],
data () {
return {
searchItem: ''
}
},
props: ['formShowText', 'formSearchItem', 'setOption'],
methods: {
querySearchAsync (queryString, cb) {
if (queryString === '') {
return
}
requestAPI(api.searchClientByName, {
data: {
name: queryString
}
}).then(res => {
cb(res.map(i => {
return {value: i.name, key: i.key}
}))
})
},
handleSelect (item) {
this.$emit('update:searchItem', item.key)
if (this.setOption) {
this.setOption(item.key)
}
}
},
watch: {
'formShowText': {
handler (val) {
if (val !== '') {
this.searchItem = val
}
},
immediate: true
}
}
}
</script>
<style scoped>
.el-autocomplete {
width: 100%;
}
</style>
<template>
<div>
</div>
</template>
<script>
export default {
name: '',
data () {
return {}
},
methods: {},
created () {
}
}
</script>
<style scoped>
</style>
<template>
<div>
</div>
</template>
<script>
export default {
name: '',
data () {
return {}
},
methods: {},
created () {
}
}
</script>
<style scoped>
</style>
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
:key-code="'keyword'" :key-code="'keyword'"
type="keyword" type="keyword"
button-title="新建工作日志" button-title="新建工作日志"
:add-new-user="addNewUser" :add-new-user="addNewLog"
:search-keyword="searchKeyword"></client-header> :search-keyword="searchKeyword"></client-header>
<client-form ref="clientForm" :filter="filter" @update:clientList="form =>{ updateForm(form) }"></client-form> <client-form ref="clientForm" :filter="filter" @update:clientList="form =>{ updateForm(form) }"></client-form>
<div class="page-body-content"> <div class="page-body-content">
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
type="primary" type="primary"
size="mini" size="mini"
:disabled="!item.can_update" :disabled="!item.can_update"
@click="edit(item.id)"> @click="editLog(item)">
<i class="fa fa-edit"></i> 编辑 <i class="fa fa-edit"></i> 编辑
</el-button> </el-button>
<el-button class="pull-right" <el-button class="pull-right"
...@@ -39,9 +39,7 @@ ...@@ -39,9 +39,7 @@
size="mini" size="mini"
@click.prevent.stop="leaveMessageSch(item)"> @click.prevent.stop="leaveMessageSch(item)">
<span :class="['badge', {'badge-unread': item.unread > 0}]" <span :class="['badge', {'badge-unread': item.unread > 0}]"
v-if="item.commentCount"> v-if="item.commentCount">{{item.commentCount.comment}}</span>
{{item.commentCount.comment}}
</span>
<i class="fa fa-commenting"></i> 留言 <i class="fa fa-commenting"></i> 留言
</el-button> </el-button>
</span> </span>
...@@ -177,7 +175,9 @@ ...@@ -177,7 +175,9 @@
viewer.update() viewer.update()
}) })
}, },
edit () {}, editLog (row) {
this.$router.push({name: 'workLogEdit', params: {id: row.id}})
},
delLog (id) { delLog (id) {
this.$confirm('确认删除吗?', '提示').then(() => { this.$confirm('确认删除吗?', '提示').then(() => {
requestAPI(api.delWorkLog, { requestAPI(api.delWorkLog, {
...@@ -200,8 +200,9 @@ ...@@ -200,8 +200,9 @@
}).catch(_ => { }).catch(_ => {
}) })
}, },
addNewUser () { addNewLog () {
this.$refs.leaveModule.isShow('新建客户', 'clientAdd') this.$router.push({name: 'workLogAdd'})
// this.$refs.leaveModule.isShow('新建客户', 'clientAdd')
}, },
searchKeyword (search) { searchKeyword (search) {
this.updateForm(search) this.updateForm(search)
...@@ -211,7 +212,6 @@ ...@@ -211,7 +212,6 @@
this.getList() this.getList()
}, },
updateForm (form) { updateForm (form) {
console.log(form)
Object.assign(this.form, form) Object.assign(this.form, form)
this.getList() this.getList()
}, },
...@@ -239,16 +239,6 @@ ...@@ -239,16 +239,6 @@
res.forEach(item => { res.forEach(item => {
if (item.itemKey) { if (item.itemKey) {
item.cascader = [] item.cascader = []
item.value.forEach(i => {
i.label = i.name
i.value = i.id
i.children = i.items
delete i.items
i.children.forEach(s => {
s.label = s.name
s.value = s.id
})
})
} }
}) })
return res return res
......
<template>
<section>
<div class="content">
<client-header ref="clientHeader"
:title="'客户名称:' + model.name"
:title-span="12"
type=""></client-header>
<div class="page-body-content">
<client-nav :trigger="addWorkLog" trigger-text="新建工作日志"></client-nav>
<div v-loading="loading">
<ScheduleItem
v-for="(item, key) in result.list"
:item="item"
:key="key"
@update:image="imgs => {setImage(imgs)}">
<span slot="opearate">
<el-button class="pull-right"
type="primary"
size="mini"
:disabled="!item.can_delete"
@click="delLog(item.id)">
<i class="fa fa-trash-o faa-shake"></i> 删除
</el-button>
<el-button class="pull-right"
type="primary"
size="mini"
:disabled="!item.can_update"
@click="editWorkLog(item)">
<i class="fa fa-edit"></i> 编辑
</el-button>
<el-button class="pull-right"
type="primary"
size="mini"
@click.prevent.stop="leaveMessageSch(item)">
<span :class="['badge', {'badge-unread': item.unread > 0}]"
v-if="item.commentCount">{{item.commentCount.comment}}</span>
<i class="fa fa-commenting"></i> 留言
</el-button>
</span>
</ScheduleItem>
<div v-if="result.list.length === 0">
<el-card class="box-card">
未查询到数据!
</el-card>
</div>
</div>
<Pagenation
@update:pager="pager => {updatePage(pager)}"
:pager.sync="pagenation"
:total="totalcount"
v-if="totalcount > pagenation.pagesize">
</Pagenation>
</div>
</div>
</section>
</template>
<script>
import {
requestAPI,
api
} from '@/lib/commonMixin'
import ScheduleItem from '../../common/scheduleItem'
import clientHeader from '../../common/clientHeader'
import Pagenation from '../schedulePagenation'
export default {
name: '',
data () {
return {
client_id: '',
loading: false,
clientName: '',
model: {
name: ''
},
result: {
list: []
},
detailModel: [],
pagenation: {
page: 1
},
totalcount: 0,
tableList: [],
options: []
}
},
components: {
ScheduleItem,
clientHeader,
Pagenation
},
methods: {
editWorkLog (row) {
this.$router.push({name: 'workLogEdit', params: {id: row.id}})
},
addWorkLog () {
this.$router.push({name: 'workLogClientAdd', params: {id: this.$route.params.id}})
},
updatePage (pager) {
Object.assign(this.pagenation, pager)
this.getList()
},
getList () {
if (this.loading) {
return
}
this.loading = true
requestAPI(api.getWorkLogClient, {
data: {
id: this.$route.params.id
}
}).then(res => {
this.result.list = res.list
// this.pagenation.page = res.pagenation.thispage
this.totalcount = res.pagenation.totalcount
}).finally(_ => {
this.loading = false
})
}
},
created () {
requestAPI(api.getClient, {
data: {
id: this.$route.params.id
}
}).then(res => {
this.options = res.options
Object.keys(res.model).forEach(item => {
this.$set(this.model, item, res.model[item])
})
this.getList()
}, error => {
if (Array.isArray(error.msg)) {
error.msg.forEach(item => {
this.$notify.error({
title: '错误',
message: item.error
})
})
}
})
}
}
</script>
<style scoped>
</style>
<template>
<section>
<operation-work-log
ref="operationWorkLog"
type="add"
:error-data="errorData">
<span slot="operationBtn">
<el-button type="primary" @click="saveWorkLog" size="mini">保存</el-button>
<el-button @click="close" size="mini">关闭</el-button>
</span>
</operation-work-log>
</section>
</template>
<script>
import operationWorkLog from './operationWorkLog'
import {
requestAPI,
api
} from '@/lib/commonMixin'
import {setModule} from '../../../lib/viewHelper'
export default {
name: '',
components: {
operationWorkLog
},
data () {
return {
errorData: {}
}
},
methods: {
setDraft (subData) {
// start_at end_at scenario_option_id scenario_id
let comparison = ['start_at', 'end_at', 'scenario_option_id', 'scenario_id']
let error = []
comparison.forEach(item => {
if (subData[item] === '') {
error.push(item)
}
})
return error.length > 0
},
saveWorkLog () {
let from = this.$refs.operationWorkLog.getForm()
let subData = setModule(from, 'WorkLogs')
if (this.setDraft(from)) {
this.$confirm('信息不完整,是否保存为草稿?', '提示', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'warning'
}).then(() => {
this.saveFun(Object.assign({}, subData, {is_draft: 1}))
}).catch(_ => {
this.saveFun(subData)
})
} else {
this.saveFun(subData)
}
},
saveFun (subData) {
requestAPI(api.saveWorkLogAdd, {
data: {...subData}
}).then(res => {
this.$message({
message: '保存成功!',
type: 'success'
})
}, error => {
error.msg.forEach(item => {
this.$set(this.errorData, item.name, item.error)
})
})
},
close () {}
},
mounted () {
this.$refs.operationWorkLog.initAdd()
}
}
</script>
<style scoped>
</style>
<template>
<section>
<operation-work-log
ref="operationWorkLog"
type="add"
:error-data="errorData">
<span slot="operationBtn">
<el-button type="primary" @click="saveWorkLog" size="mini">保存</el-button>
<el-button @click="close" size="mini">关闭</el-button>
</span>
</operation-work-log>
</section>
</template>
<script>
import {
requestAPI,
api
} from '@/lib/commonMixin'
import operationWorkLog from './operationWorkLog'
import {setModule} from '../../../lib/viewHelper'
export default {
name: '',
components: {
operationWorkLog
},
data () {
return {
errorData: {}
}
},
methods: {
setDraft (subData) {
// start_at end_at scenario_option_id scenario_id
let comparison = ['start_at', 'end_at', 'scenario_option_id', 'scenario_id']
let error = []
comparison.forEach(item => {
if (subData[item] === '') {
error.push(item)
}
})
return error.length > 0
},
saveWorkLog () {
let from = this.$refs.operationWorkLog.getForm()
let subData = setModule(from, 'WorkLogs')
if (this.setDraft(from)) {
this.$confirm('信息不完整,是否保存为草稿?', '提示', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'warning'
}).then(() => {
this.saveFun(Object.assign({}, subData, {is_draft: 1}))
}).catch(_ => {
this.saveFun(subData)
})
} else {
this.saveFun(subData)
}
},
saveFun (subData) {
requestAPI(api.saveWorkLogEdit, {
data: {...subData}
}).then(res => {
this.$message({
message: '保存成功!',
type: 'success'
})
}, error => {
error.msg.forEach(item => {
this.$set(this.errorData, item.name, item.error)
})
})
},
close () {
}
},
mounted () {
this.$refs.operationWorkLog.initEdit()
}
}
</script>
<style scoped>
</style>
<template>
<div class="work-log-add-edit-form auto-template-form">
<el-form :model="WorkLogs">
<el-form-item :show-message="false" :error="errorData['client_id'] ? errorData['client_id'] : ''">
<single-search-input
:form-serch-item="WorkLogs.client_id"
:form-show-text="searchText"
:set-option="setClientOption"
label="客户名称"
@update:searchItem="val => {WorkLogs.client_id = val}">
<span slot="formError" class="el-form-item__error">
{{errorData['client_id']}}
</span>
</single-search-input>
</el-form-item>
<el-form-item :show-message="false" :error="errorData['workLogContacts'] ? errorData['workLogContacts'] : ''">
<single-checkbox
:form-item="WorkLogs.workLogContacts"
label="联系人"
:options-list="getOptions('WorkLogs[workLogContacts]')"
@update:item="val => {WorkLogs.workLogContacts = val}">
<span slot="formError" class="el-form-item__error">
{{errorData['workLogContacts']}}
</span>
</single-checkbox>
</el-form-item>
<el-form-item :show-message="false" :error="errorData['project_id'] ? errorData['project_id'] : ''">
<single-select
:form-item="WorkLogs.project_id"
label="项目名称"
:options-list="getOptions('WorkLogs[project_id]')"
@update:item="val => {WorkLogs.project_id = val}">
<span slot="formError" class="el-form-item__error">
{{errorData['project_id']}}
</span>
</single-select>
</el-form-item>
<el-form-item :show-message="false" :error="errorData['escort'] ? errorData['escort'] : ''">
<single-input
label="陪同人员"
type="textarea"
:rows="4"
:form-item="WorkLogs.escort"
@update:item="val => {WorkLogs.escort = val}">
<span slot="formError" class="el-form-item__error">
{{errorData['escort']}}
</span>
</single-input>
</el-form-item>
<el-form-item :show-message="false" :error="errorData['start_at'] ? errorData['start_at'] : ''">
<single-date-time-picker
:start-date-time-item="WorkLogs.start_at"
:end-date-time-item="WorkLogs.end_at"
start-label="开始时间"
end-label="结束时间"
calc-label="用时"
:required="true"
pickerType="edit"
@update:startItem="val => {WorkLogs.start_at = val}"
@update:endItem="val => {WorkLogs.end_at = val}">
<span slot="formError" class="el-form-item__error">
{{errorData['start_at']}}
</span>
</single-date-time-picker>
</el-form-item>
<el-form-item :show-message="false" :error="errorData['scenario_id'] ? errorData['scenario_id'] : ''">
<single-radio
label="工作日志类型"
:required="true"
:form-item="WorkLogs.scenario_id"
:options-list="getOptions('WorkLogSearch[scenario_id]')"
:set-option="setScenarioOption"
@update:item="val => {WorkLogs.scenario_id = val}">
<span slot="formError" class="el-form-item__error">
{{errorData['scenario_id']}}
</span>
</single-radio>
</el-form-item>
<el-form-item :show-message="false" :error="errorData['scenario_option_id'] ? errorData['scenario_option_id'] : ''">
<single-radio
label="工作内容"
:required="true"
:form-item="WorkLogs.scenario_option_id"
:options-list="getOptions('WorkLogSearch[scenario_option_id]')"
@update:item="val => {WorkLogs.scenario_option_id = val}">
<span slot="formError" class="el-form-item__error">
{{errorData['scenario_option_id']}}
</span>
</single-radio>
</el-form-item>
<el-form-item :show-message="false" :error="errorData['description'] ? errorData['description'] : ''">
<single-input
label="说明"
type="textarea"
:rows="4"
:form-item="WorkLogs.description"
@update:item="val => {WorkLogs.description = val}">
<span slot="formError" class="el-form-item__error">
{{errorData['description']}}
</span>
</single-input>
</el-form-item>
<el-form-item>
<el-row :gutter="10">
<el-col :offset="4" :span="14">
<slot name="operationBtn">
</slot>
</el-col>
</el-row>
</el-form-item>
</el-form>
</div>
</template>
<script>
import {
requestAPI,
api
} from '@/lib/commonMixin'
import singleDateTimePicker from '../../common/singleDateTimePicker'
import singleSearchInput from '../../common/singleSearchInput'
import singleInput from '../../common/singleInput'
import singleCheckbox from '../../common/singleCheckbox'
import singleSelect from '../../common/singleSelect'
import SingleRadio from '../../common/singleRadio'
export default {
name: '',
data () {
return {
WorkLogs: {
id: '',
client_id: '',
end_at: '',
created_by: '',
start_at: '',
description: '',
workLogContacts: [],
scenario_id: '',
scenario_option_id: '',
escort: '',
project_id: '',
is_draft: 0
},
options: {
'WorkLogs[workLogContacts]': {
value: []
},
'WorkLogs[project_id]': {
value: []
},
'WorkLogSearch[scenario_option_id]': {
value: []
}
},
client: {},
searchText: '',
scenarioOptionIds: [],
pageType: '',
optionsKey: 'WorkLogSearch'
}
},
components: {
SingleRadio,
singleDateTimePicker,
singleSearchInput,
singleInput,
singleCheckbox,
singleSelect
},
methods: {
getOptions (key) {
let option = {}
if (key.indexOf('[') !== -1 && key.indexOf(']') !== -1) {
option = this.options[key]
} else {
option = this.options[this.optionsKey + '[' + key + ']']
}
if (option) {
return option.value
}
return []
},
setScenarioOption (val) {
let scenario = this.scenarioOptionIds.find(i => i.key === val)
if (scenario) {
this.options['WorkLogSearch[scenario_option_id]'].value = scenario.value
}
},
setClientOption (id) {
requestAPI(api.searchContactByClientId, {
data: {
client_id: id
}
}).then(res => {
this.options['WorkLogs[workLogContacts]'].value = res
})
requestAPI(api.searchProjectByClientId, {
data: {
client_id: id
}
}).then(res => {
this.options['WorkLogs[project_id]'].value = res
})
},
getForm () {
return {...this.WorkLogs}
},
setForm (model) {
Object.keys(this.WorkLogs).forEach(item => {
if (item === 'workLogContacts') {
this.WorkLogs[item] = model[item].map(i => i.key)
} else {
this.WorkLogs[item] = model[item]
}
})
this.searchText = this.client.name
// this.WorkLogs.scenario_id = 1
this.setScenarioOption(this.WorkLogs.scenario_id)
},
initAdd () {
if (this.$route.params.id) {
this.WorkLogs.client_id = this.$route.params.id
requestAPI(api.getClient, {
data: {
id: this.$route.params.id
}
}).then(res => {
this.searchText = res.model.name
})
requestAPI(api.searchContactByClientId, {
data: {
client_id: this.$route.params.id
}
}).then(res => {
this.options['WorkLogs[workLogContacts]'].value = res
})
requestAPI(api.searchProjectByClientId, {
data: {
client_id: this.$route.params.id
}
}).then(res => {
this.options['WorkLogs[project_id]'].value = res
})
}
requestAPI(api.getWorkLogNewOptions).then(res => {
// res.options['WorkLogSearch[scenario_id]']
Object.keys(res.options).forEach(key => {
if (res.options[key].value) {
this.scenarioOptionIds = res.options[key].value
// console.log(this.scenarioOptionIds)
}
this.$set(this.options, key, res.options[key])
})
this.$nextTick(() => {
this.WorkLogs.scenario_id = 1
this.setScenarioOption(1)
})
})
},
initEdit () {
requestAPI(api.getWorkLogEdit, {
data: {
id: this.$route.params.id
}
}).then(res => {
Object.keys(res.options).forEach(item => {
if (res.options[item].value) {
res.options[item].value.forEach(i => {
if (i.value) {
this.scenarioOptionIds.push(i)
}
})
}
if (!this.options[item]) {
this.$set(this.options, item, res.options[item])
} else {
Object.assign(this.options[item], res.options[item])
}
})
Object.keys(res.model.client).forEach(item => {
this.$set(this.client, item, res.model.client[item])
})
this.setForm(res.model)
this.$nextTick(() => {
this.WorkLogs.scenario_id = res.model.scenario_id
this.setScenarioOption(res.model.scenario_id)
})
})
}
},
props: ['errorData'],
watch: {
'WorkLogs': {
handler (val) {
// console.log(val)
},
deep: true
}
}
}
</script>
<style lang="scss">
.auto-template-form {
.el-form-item {
margin-bottom: 15px;
}
.client-label {
position: relative;
font-size: 12px;
}
.client-label span {
padding-right: 10px;
}
.client-label.required:after {
content: "*";
color: #eb7567;
position: absolute;
top: 3px;
right: 6px;
}
.el-form-item__error {
position: static;
}
}
</style>
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
clearable clearable
v-if="item.itemKey" v-if="item.itemKey"
:options="item.value" :options="item.value"
:props="cascaderOption"
@change="setCascader(item)" @change="setCascader(item)"
></el-cascader> ></el-cascader>
</el-form-item> </el-form-item>
...@@ -46,7 +47,12 @@ ...@@ -46,7 +47,12 @@
name: 'client-form', name: 'client-form',
data () { data () {
return { return {
clientForm: {} clientForm: {},
cascaderOption: {
value: 'key',
label: 'name',
children: 'value'
}
} }
}, },
props: ['filter'], props: ['filter'],
...@@ -66,18 +72,19 @@ ...@@ -66,18 +72,19 @@
setDefault (filter) { setDefault (filter) {
filter.forEach(item => { filter.forEach(item => {
if (item.default) { if (item.default) {
let ids = findWhere(item.value, item.default, 'id') let keys = findWhere(item.value, item.default, 'key')
if (ids.node) { if (keys.node) {
if (ids.parentNode) { if (keys.parentNode) {
this.clientForm[item.itemKey] = ids.parentNode.id this.clientForm[item.itemKey] = keys.parentNode.key
this.clientForm[item.key] = ids.node.id this.clientForm[item.key] = keys.node.key
item.cascader = [ids.parentNode.id, ids.node.id] item.cascader = [keys.parentNode.id, keys.node.key]
} else { } else {
this.clientForm[item.itemKey] = '' this.clientForm[item.itemKey] = ''
this.clientForm[item.key] = ids.node.id this.clientForm[item.key] = keys.node.key
item.cascader = [ids.node.id] item.cascader = [keys.node.key]
} }
} }
console.log(item.cascader)
} }
}) })
}, },
......
...@@ -126,12 +126,14 @@ export let navs = () => { ...@@ -126,12 +126,14 @@ export let navs = () => {
{ {
title: '客户信息', title: '客户信息',
icon: 'fa-user', icon: 'fa-user',
routerName: 'viewClient' routerName: 'viewClient',
appName: 'client'
}, },
{ {
title: '工作日志', title: '工作日志',
icon: 'fa-book', icon: 'fa-book',
routerName: '' routerName: 'ofClient',
appName: 'worklog'
}, },
{ {
title: '商机信息', title: '商机信息',
......
...@@ -4,7 +4,17 @@ export default { ...@@ -4,7 +4,17 @@ export default {
item: '', item: '',
items: [], items: [],
timeItem: '', timeItem: '',
inputSelectItem: 'rmb' inputSelectItem: 'rmb',
start_at: '',
end_at: '',
startDateTime: {
date: '',
time: ''
},
endDateTime: {
date: '',
time: ''
}
} }
}, },
props: { props: {
...@@ -18,9 +28,18 @@ export default { ...@@ -18,9 +28,18 @@ export default {
formTimeItem: { formTimeItem: {
type: String type: String
}, },
startDateTimeItem: {
type: String
},
endDateTimeItem: {
type: String
},
label: { label: {
type: String type: String
}, },
startLabel: {type: String},
endLabel: {type: String},
calcLabel: {type: String},
required: { required: {
type: Boolean type: Boolean
}, },
...@@ -76,7 +95,12 @@ export default { ...@@ -76,7 +95,12 @@ export default {
watch: { watch: {
'formItem': { 'formItem': {
handler (val) { handler (val) {
if (Array.isArray(val)) {
console.log(val)
this.items = val
} else {
this.item = val this.item = val
}
}, },
deep: true, deep: true,
immediate: true immediate: true
......
...@@ -64,11 +64,11 @@ let getNode = function (json, nodeId, type, nodeObj) { ...@@ -64,11 +64,11 @@ let getNode = function (json, nodeId, type, nodeObj) {
break break
} else { } else {
// 3.如果有子节点就开始找 // 3.如果有子节点就开始找
if (obj.children) { if (obj.value) {
// 4.递归前,记录当前节点,作为parent 父亲 // 4.递归前,记录当前节点,作为parent 父亲
nodeObj.parentNode = obj nodeObj.parentNode = obj
// 递归往下找 // 递归往下找
getNode(obj.children, nodeId, type, nodeObj) getNode(obj.value, nodeId, type, nodeObj)
} else { } else {
// 跳出当前递归,返回上层递归 // 跳出当前递归,返回上层递归
continue continue
......
...@@ -3,10 +3,9 @@ import portal from 'vis-portal' ...@@ -3,10 +3,9 @@ import portal from 'vis-portal'
import ElementRoute from './routes/workLog' import ElementRoute from './routes/workLog'
let routes = [] let routes = []
const appName = 'work-log' const appName = 'worklog'
routes = [].concat(ElementRoute) routes = [].concat(ElementRoute)
console.log(routes)
let RouterInit = () => { let RouterInit = () => {
portal.createApp(appName, {}, app => { portal.createApp(appName, {}, app => {
app.mapRoute(routes) app.mapRoute(routes)
......
import clientList from '../components/workLog/list' import clientList from '../components/workLog/list'
import test from '../components/test' import workLogOfClient from '../components/workLog/logOfClient/workLogOfClient'
import workLogAdd from '../components/workLog/work/addLog'
import workLogEdit from '../components/workLog/work/editLog'
const projectTitle = '金畅逍BMS - ' const projectTitle = '金畅逍BMS - '
const routes = [ const routes = [
{ {
path: '/list', path: '/worklog',
name: 'workLogList', name: 'workLogList',
component: clientList, component: clientList,
meta: { meta: {
...@@ -11,9 +13,27 @@ const routes = [ ...@@ -11,9 +13,27 @@ const routes = [
} }
}, },
{ {
path: '/test', path: '/ofClient/:id',
name: 'test', name: 'ofClient',
component: test component: workLogOfClient,
meta: {
title: projectTitle + '客户信息'
}
},
{
path: '/workLogAdd',
name: 'workLogAdd',
component: workLogAdd
},
{
path: '/workLogClientAdd/:id',
name: 'workLogClientAdd',
component: workLogAdd
},
{
path: '/workLogEdit/:id',
name: 'workLogEdit',
component: workLogEdit
} }
] ]
export default routes export default routes
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
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