Commit ce6bdfbc authored by 罗超's avatar 罗超

修改OKR部分功能

parent 314ff401
......@@ -48,7 +48,7 @@ module.exports = function (ctx) {
build: {
vueRouterMode: 'hash', // available values: 'hash', 'history'
env: ctx.dev ? {
API: 'http://192.168.1.27:8300/api'
API: 'http://192.168.1.13:8085/api'
} : {
API: 'http://eduapi.oytour.com/api'
},
......
......@@ -226,3 +226,45 @@ export function setObjectiveStatus(data){
data
})
}
export function queryKRRuleList(data){
return request({
url: '/OKRPeriod/GetOKRRuleDownLoadList',
method: 'post',
data
})
}
export function queryMyManageDepartment(data){
return request({
url: '/OKRPeriod/GetOKRMyManageDepartment',
method: 'post',
data
})
}
export function queryMyChildEmployeeList(data){
return request({
url: '/OKRPeriod/GetOKRMyChildEmployeeList',
method: 'post',
data
})
}
export function setKRRule(data){
return request({
url: '/OKRPeriod/SetOKRKeyResultUseRule',
method: 'post',
data
})
}
export function queryKRRuleRangeList(data){
return request({
url: '/OKRPeriod/GetOKRKeyResultRuleReList',
method: 'post',
data
})
}
export function deleteKRRule(data){
return request({
url: '/OKRPeriod/CancelOKRKeyResultUseRule',
method: 'post',
data
})
}
\ No newline at end of file
<template>
<q-dialog v-model="dialog" maximized full-height seamless position="right">
<q-card style="margin-top:61px;width:420px" class="no-border-radius classinfo_Dialog">
<div style="height:100%">
<q-card style="width:420px;height:100%" class="no-border-radius classinfo_Dialog">
<q-tabs
v-model="tab"
class="text-primary"
......@@ -9,7 +9,7 @@
<q-tab name="two" label="最佳范例" />
</q-tabs>
<div class="WritingAssistant-tabContent-1nYI5" v-if="tab=='one'">
<div class="WritingAssistant-tabContent-1nYI5 scroll myscroll" style="height:calc(100% - 48px)" v-if="tab=='one'">
<div class="WritingGuide-section-1XCZt">
<h3 class="WritingGuide-title-3wBKZ">
如何写出好的 Objective?
......@@ -108,14 +108,14 @@
</div>
<div class="WritingGuide-otherPrinciple-2AhOv" >
<div class="WritingGuide-otherPrinciple-2AhOv" style="margin-bottom:20px;">
<h3 class="WritingGuide-title-3wBKZ">
其他制定原则
</h3>
<ul><li>Objective 和每个 Objective 对应的 Key Result 数量应控制在 3-5 个</li><li>及时与上级、合作方沟通目标,达成一致</li><li>想要了解更多? <a href="https://bytedance.feishu.cn/docs/doccnNcwoql8HhrXSYZ7phudjMg" target="_blank" rel="noopener noreferrer">OKR 制定常见误区</a></li></ul>
</div>
</div>
<div v-else class="WritingAssistant-tabContent-1nYI5">
<div v-else class="WritingAssistant-tabContent-1nYI5 scroll myscroll" style="height:calc(100% - 48px)">
<div class="BestCase-tagContainer-1k1dW">
<div v-for="(x,y) in list" :key="y" class="BestCase-tag-206SU" :class="{'BestCase-focused-2aQSy':index == y}" @click="index=y,Selectlist = list[y].list">
{{x.title}}
......@@ -171,13 +171,14 @@
</div>
</div>
</div>
<div style="margin-bottom:10px">&nbsp;</div>
</div>
</q-card>
<div class="dialog-out-close" @click="closeSaveForm"
style="height:40px !important;border-top-left-radius: 4px !important;border-bottom-left-radius: 4px !important;">
<q-icon name="iconfont icon-jujue1" size="26px" />
</div>
</q-dialog>
</div>
</template>
<script>
......
<template>
<q-card class="q-px-md" style="width:600px;">
<q-card-section class="row items-center q-pb-none">
<div class="text-h6">
<span>关联系统数据模板</span>
</div>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
<q-card-section>
<q-banner
rounded
class="bg-orange-2 text-black q-py-none q-px-md q-mb-md"
style="min-height:30px;"
>
<div class="row items-center">
<span class="q-mr-md">
<inline-svg
class="svg-icon svg-icon-orange"
src="icons/svg/Code/Warning-2.svg"
></inline-svg>
</span>
<span style="font-size:12px;"
>关联系统数据后,无法进行手动进度设置,如需手动设置进度需要取消关联</span
>
</div>
</q-banner>
<div class="text-subtitle2 text-weight-bold q-mt-md">
<span>模板选择</span>
</div>
<div class="q-mt-xs">
<q-select
filled
v-model="chosenRule"
:options="tempsList"
option-value="Id"
option-label="RuleName"
dense
options-selected-class="text-deep-orange"
:rules="[val => !!val || '请选择规则模板']"
ref="tempchosen"
>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps" v-on="scope.itemEvents">
<q-item-section avatar>
<q-avatar size="40px;" rounded color="green-1">
<span class="text-light-green">{{
scope.opt.RuleName.substring(0, 1)
}}</span>
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label>{{ scope.opt.RuleName }}</q-item-label>
<q-item-label caption>{{ scope.opt.Remark }}</q-item-label>
</q-item-section>
</q-item>
</template>
</q-select>
</div>
<div class="text-subtitle2 text-weight-bold q-mt-md">
<span>关键值设定</span>
</div>
<div class="flex row items-start q-mt-xs">
<q-input
dense
standout
behavior="menu"
v-model="initTarget"
label="起始值"
mask="#.##"
fill-mask="0"
reverse-fill-mask
class="q-mr-xs col"
/>
<q-input
dense
standout
behavior="menu"
v-model="maxTarget"
ref="maxTarget"
label="目标值"
mask="#.##"
fill-mask="0"
reverse-fill-mask
class="q-ml-xs col"
:rules="[
val =>
!(Number.parseFloat(initTarget) >= Number.parseFloat(val)) ||
'目标值不能小于或等于初始值'
]"
/>
</div>
<div class="text-subtitle2 text-weight-bold q-mt-md">
<span>关联部门/人员</span>
</div>
<div class="flex row q-mt-xs">
<div class="q-mr-md">
<q-select
dense
standout
behavior="menu"
:options="groupData"
option-label="name"
option-value="id"
v-model="defaultGroupType"
></q-select>
</div>
<div class="col relative-position">
<q-input
standout
bottom-slots
v-model="searchText"
placeholder="输入你需要搜索的内容"
dense
@input="querySearch"
>
<template v-slot:append>
<inline-svg
class="svg-icon svg-icon-primary"
src="icons/svg/General/Search.svg"
></inline-svg>
</template>
</q-input>
<div
style="width:100%;margin-top:45px;max-height:300px;"
class="bg-grey-1 q-py-xs absolute-top-left shadow-3 rounded-borders scroll myscroll"
v-if="showResult"
>
<q-list>
<q-item
class="rounded-borders"
clickable
v-ripple
v-for="(x, i) in resultsList"
:key="i"
@click="createRange(x)"
>
<q-item-section avatar>
<q-avatar
style="background-color: #F3F6F9;"
rounded
size="40px"
text-color="secondary"
>
<img :src="x.icon" v-if="x.icon" />
<span v-else>{{ x.name.substring(0, 1) }}</span>
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label class="font-pfb">{{ x.name }}</q-item-label>
<q-item-label caption class="remark-font">
<span>{{
x.type == 2 ? `${x.deptName}·${x.postName}` : "部门"
}}</span>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
<div
class="q-py-lg remark-font text-center"
v-if="!resultsList || resultsList.length == 0"
>
未找到数据,对方或不是你的{{ defaultGroupType.name }}
</div>
</div>
</div>
</div>
<div class=" scroll" style="height:200px">
<div class="row items-center">
<q-avatar rounded color="primary" size="36px">
<inline-svg
class="svg-icon svg-icon-white"
src="icons/svg/Code/Git4.svg"
></inline-svg>
</q-avatar>
<div class="text-subtitle2 col q-mx-md">
<div>我自己</div>
<div class="remark-font">
使用模板系统会强制将用户设定为第一统计对象,此处无法修改
</div>
</div>
</div>
<div
class="row items-center q-mt-md"
v-for="(x, i) in rangeList"
:key="i"
>
<q-avatar
style="background-color: #F3F6F9;"
rounded
size="40px"
text-color="secondary"
v-if="x.type == 2"
>
<img :src="x.icon" v-if="x.icon" />
<span v-else>{{ x.name.substring(0, 1) }}</span>
</q-avatar>
<q-avatar
rounded
size="40px"
text-color="warning"
color="orange-1"
v-if="x.type == 1"
>
<span>{{ x.name.substring(0, 1) }}</span>
</q-avatar>
<div class="text-subtitle2 col q-mx-md">
<div>{{ x.name }}</div>
<div class="remark-font">
{{ x.type == 2 ? `${x.deptName}·${x.postName}` : "部门" }}
</div>
</div>
<div class="row" style="height:20px;">
<span title="删除" @click="deleteRange(i)">
<inline-svg
class="svg-icon svg-icon-g-p"
src="icons/svg/General/Trash.svg"
width="20px"
height="20px"
></inline-svg>
</span>
</div>
</div>
</div>
</q-card-section>
<q-card-actions align="right">
<div>
<q-btn flat label="取消" color="primary q-mr-md" v-close-popup />
<q-btn label="保存" color="primary" @click="saveRange" />
</div>
</q-card-actions>
</q-card>
</template>
<script>
import {
queryKRRuleList,
queryMyManageDepartment,
queryMyChildEmployeeList,
setKRRule,
queryKRRuleRangeList
} from "../../api/okr/work";
import { mapGetters } from "vuex";
export default {
props: ["kr", "period"],
computed: {
...mapGetters(["userInfo"])
},
data() {
return {
tempsList: [],
chosenRule: null,
defaultGroupType: {},
groupData: [
{
id: 1,
name: "直系下属"
},
{
id: 2,
name: "下级部门"
}
],
deptsList: [],
usersList: [],
resultsList: [],
showResult: false,
searchText: "",
rangeList: [],
initTarget: "0.00",
maxTarget: "0.00"
};
},
created() {
this.defaultGroupType = this.groupData[0];
if (this.kr.RuleId != 0) {
this.initTarget = this.kr.StartValue.toFixed(2);
this.maxTarget = this.kr.EndValue.toFixed(2);
}
this.queryRules();
},
mounted() {
if (this.kr.RuleId != 0) {
setTimeout(() => {
this.queryRangeList();
}, 1000);
}
},
methods: {
saveRange() {
this.$refs.tempchosen.validate();
this.$refs.maxTarget.validate();
if (!this.$refs.tempchosen.hasError && !this.$refs.maxTarget.hasError) {
let obj = {
Id: this.kr.Id,
RuleId: this.chosenRule.Id,
RuleSTime: this.period.StartDate,
RuleETime: this.period.EndDate,
StartValue: this.initTarget,
EndValue: this.maxTarget,
RelationList: [
{
Type: 2,
RelationId: this.userInfo.Id
}
]
};
this.rangeList.forEach(x => {
obj.RelationList.push({
Type: x.type,
RelationId: x.id
});
});
setKRRule(obj).then(r => {
this.$emit("save");
});
}
},
deleteRange(i) {
this.rangeList.splice(i, 1);
},
createRange(obj) {
let range = this.rangeList.find(x => {
if (x.id == obj.id && x.type == obj.type) {
return x;
}
});
if (!range || !range.id) {
this.rangeList.unshift(obj);
}
this.searchText = "";
this.showResult = false;
},
queryRules() {
queryKRRuleList({}).then(r => {
this.tempsList = r.Data;
if (this.kr.RuleId > 0) {
this.tempsList.forEach(x => {
if (x.Id == this.kr.RuleId) {
this.chosenRule = x;
}
});
}
this.queryMyDepat();
});
},
queryMyDepat() {
queryMyManageDepartment({}).then(r => {
this.queryUsers();
this.deptsList = r.Data;
});
},
queryUsers() {
queryMyChildEmployeeList({}).then(r => {
this.usersList = r.Data;
});
},
querySearch() {
this.searchText = this.searchText.trim();
let reg = /[0-9]+/g;
this.searchText = this.searchText.replace(reg, "");
if (this.searchText != "") {
this.resultsList = [];
if (this.defaultGroupType.id == 1) {
this.usersList.forEach(x => {
if (x.EmployeeName.indexOf(this.searchText) != -1) {
this.resultsList.push({
id: x.Id,
name: x.EmployeeName,
type: 1,
icon: x.UserIcon,
deptName: x.DeptName,
postName: x.PostName
});
}
});
} else if (this.defaultGroupType.id == 2) {
this.deptsList.forEach(x => {
this.searchDepartment(x);
});
}
this.showResult = true;
} else {
this.showResult = false;
}
},
searchDepartment(obj) {
if (obj.DeptName.indexOf(this.searchText) != -1) {
this.resultsList.push({
id: obj.DeptId,
name: obj.DeptName,
type: 1
});
}
if (obj.ChildList && obj.ChildList.length > 0) {
obj.ChildList.forEach(x => {
this.searchDepartment(x);
});
}
},
queryRangeList() {
queryKRRuleRangeList({
KeyResultId: this.kr.Id
}).then(r => {
console.log(r.Data)
r.Data.forEach(x => {
if (x.Type == 2 && x.RelationId != this.userInfo.Id) {
this.rangeList.push({
id: x.RelationId,
name: x.RelationName,
type: 2,
icon: x.UserIcon,
deptName: x.DeptName,
postName: x.PostName
});
} else if (x.Type == 1) {
this.rangeList.push({
id: x.RelationId,
name: x.RelationName,
type: 1
});
console.log('this.rangeList',this.rangeList);
}
});
console.log(this.rangeList);
});
}
}
};
</script>
<style></style>
......@@ -7,7 +7,7 @@
:outlined="newBoxState"
:placeholder="newObjective.placeHolder"
:autofocus="newObjective.Id == 0"
:style="{ 'margin-left': newBoxState ? '-12px' : '15px'}"
:style="{ 'margin-left': newBoxState ? '-12px' : '15px' }"
@focus="changeState(1)"
@blur="changeState(2)"
>
......@@ -15,17 +15,32 @@
<div class="relative-position" v-if="!newBoxState">
<inline-svg
class="svg-icon"
:class="{'svg-icon-primary':newObjective.Status==2,'svg-icon-grey':newObjective.Status==4,'svg-icon-accent':newObjective.Status==1,'svg-icon-negative':newObjective.Status==3}"
:class="{
'svg-icon-primary': newObjective.Status == 2,
'svg-icon-grey': newObjective.Status == 4,
'svg-icon-accent': newObjective.Status == 1,
'svg-icon-negative': newObjective.Status == 3
}"
src="icons/svg/Communication/Flag.svg"
></inline-svg>
<q-tooltip content-class="bg-dark">
{{newObjective.Status==1?'审核中':''}}
{{newObjective.Status==2?'审核通过':''}}
{{newObjective.Status==3?'审核不通过':''}}
{{newObjective.Status==4?'未提交审核':''}}
{{ newObjective.Status == 1 ? "审核中" : "" }}
{{ newObjective.Status == 2 ? "审核通过" : "" }}
{{ newObjective.Status == 3 ? "审核不通过" : "" }}
{{ newObjective.Status == 4 ? "未提交审核" : "" }}
</q-tooltip>
<okr-align :obj='newObjective' :periodId='periodId' direction="up" v-if="newObjective.Id>0"></okr-align>
<okr-align :obj='newObjective' :periodId='periodId' direction="down" v-if="newObjective.ChildList&&newObjective.ChildList.length>0"></okr-align>
<okr-align
:obj="newObjective"
:periodId="periodId"
direction="up"
v-if="newObjective.Id > 0"
></okr-align>
<okr-align
:obj="newObjective"
:periodId="periodId"
direction="down"
v-if="newObjective.ChildList && newObjective.ChildList.length > 0"
></okr-align>
</div>
</template>
<template v-slot:prepend>
......@@ -33,16 +48,25 @@
<inline-svg
v-if="newBoxState"
class="svg-icon"
:class="{'svg-icon-primary':newObjective.Status==2,'svg-icon-grey':newObjective.Status==4,'svg-icon-accent':newObjective.Status==1,'svg-icon-negative':newObjective.Status==3}"
:class="{
'svg-icon-primary': newObjective.Status == 2,
'svg-icon-grey': newObjective.Status == 4,
'svg-icon-accent': newObjective.Status == 1,
'svg-icon-negative': newObjective.Status == 3
}"
src="icons/svg/Communication/Flag.svg"
></inline-svg>
<q-tooltip content-class="bg-dark">
{{newObjective.Status==1?'审核中':''}}
{{newObjective.Status==2?'审核通过':''}}
{{newObjective.Status==3?'审核不通过':''}}
{{newObjective.Status==4?'未提交审核':''}}
{{ newObjective.Status == 1 ? "审核中" : "" }}
{{ newObjective.Status == 2 ? "审核通过" : "" }}
{{ newObjective.Status == 3 ? "审核不通过" : "" }}
{{ newObjective.Status == 4 ? "未提交审核" : "" }}
</q-tooltip>
<div class="absolute" style="bottom:0px;right:5px;height:14px;" v-if="newObjective.IsLock==1">
<div
class="absolute"
style="bottom:0px;right:5px;height:14px;"
v-if="newObjective.IsLock == 1"
>
<inline-svg
v-if="!newBoxState"
class="svg-icon svg-icon-grey"
......@@ -51,7 +75,6 @@
height="14px"
></inline-svg>
</div>
</div>
</template>
<template v-slot:append>
......@@ -161,6 +184,24 @@
class="items-center"
clickable
v-ripple
v-if="newObjective.Status == 3 || newObjective.Status == 4"
@click="setObjectiveStatus"
>
<q-item-section avatar>
<inline-svg
class="svg-icon svg-icon-g-p"
src="icons/svg/General/Shield-check.svg"
width="20px"
height="20px"
></inline-svg>
</q-item-section>
<q-item-section>提交审核</q-item-section>
</q-item>
<q-item
class="items-center"
clickable
v-ripple
v-if="newObjective.Status == 3 || newObjective.Status == 4"
@click="setObjectiveStatus"
>
<q-item-section avatar>
......@@ -217,14 +258,14 @@
src="icons/svg/Design/Circle.svg"
width="14px"
height="14px"
v-if="x.IsLock==2"
v-if="x.IsLock == 2"
></inline-svg>
<inline-svg
class="svg-icon svg-icon-grey"
src="icons/svg/General/Lock.svg"
width="14px"
height="14px"
v-if="x.IsLock==1"
v-if="x.IsLock == 1"
></inline-svg>
</template>
<template v-slot:append>
......@@ -232,6 +273,19 @@
class="flex row"
v-if="newObjective.Title && newObjective.Title.length > 0"
>
<div class="q-mr-lg" v-if="x.RuleId > 0" style="margin-top:22px">
<inline-svg
class="svg-icon svg-icon-secondary"
src="icons/svg/General/Save.svg"
width="20px"
height="20px"
></inline-svg>
<q-tooltip content-class="bg-dark"
>使用模板「{{
x.RuleName
}}」自动更新进度,<br />更新时间间隔一小时</q-tooltip
>
</div>
<div>
<span class="block remark-font text-right">进度</span>
<q-btn dense flat color="white" text-color="dark">
......@@ -262,7 +316,7 @@
</q-popup-proxy>
</q-btn>
</div>
<div class="q-mx-lg" style="width:47px;text-align:right">
<div class="q-mx-lg" style="width:51px;text-align:right">
<span class="block remark-font text-right">权重</span>
<q-btn
dense
......@@ -351,6 +405,41 @@
</q-item-section>
<q-item-section>Key Result权限设置</q-item-section>
</q-item>
<q-item
class="items-center"
clickable
v-ripple
@click="openUnion(x)"
>
<q-item-section avatar>
<inline-svg
class="svg-icon svg-icon-g-p"
src="icons/svg/General/Save.svg"
width="20px"
height="20px"
></inline-svg>
</q-item-section>
<q-item-section>{{
x.RuleId == 0 ? "关联系统数据" : "修改关联模板"
}}</q-item-section>
</q-item>
<q-item
class="items-center"
clickable
v-ripple
v-if="x.RuleId>0"
@click="cancelRule(x.Id)"
>
<q-item-section avatar>
<inline-svg
class="svg-icon svg-icon-g-p"
src="icons/svg/Navigation/Minus.svg"
width="20px"
height="20px"
></inline-svg>
</q-item-section>
<q-item-section>删除关联模板</q-item-section>
</q-item>
<q-item
class="items-center"
clickable
......@@ -425,8 +514,21 @@
</div>
</div>
</div>
<q-separator v-if="(newObjective.Status==2 ||newObjective.Status==3 )&& newObjective.AuditUserId && newObjective.AuditUserId>0"></q-separator>
<div v-if="(newObjective.Status==2 ||newObjective.Status==3 )&& newObjective.AuditUserId && newObjective.AuditUserId>0" class="q-pa-md">
<q-separator
v-if="
(newObjective.Status == 2 || newObjective.Status == 3) &&
newObjective.AuditUserId &&
newObjective.AuditUserId > 0
"
></q-separator>
<div
v-if="
(newObjective.Status == 2 || newObjective.Status == 3) &&
newObjective.AuditUserId &&
newObjective.AuditUserId > 0
"
class="q-pa-md"
>
<div class="flex row items-start">
<div
class="bg-grey-3 flex items-center justify-center q-mr-md"
......@@ -434,46 +536,54 @@
>
<inline-svg
class="svg-icon"
:class="{'svg-icon-primary':newObjective.Status==2,'svg-icon-negative':newObjective.Status==3}"
:class="{
'svg-icon-primary': newObjective.Status == 2,
'svg-icon-negative': newObjective.Status == 3
}"
src="icons/svg/General/Shield-check.svg"
width="20px"
height="20px"
></inline-svg>
</div>
<div class="col okr-audit">
<div class="text-subtitle2 text-weight-bold q-my-xs">
<span class="q-mr-md">OKR审核</span>
<span :class="{'text-primary':newObjective.Status==2,'text-negative':newObjective.Status==3}">【{{newObjective.Status==2?'通过':'不通过'}}】</span>
<span
:class="{
'text-primary': newObjective.Status == 2,
'text-negative': newObjective.Status == 3
}"
>【{{ newObjective.Status == 2 ? "通过" : "不通过" }}】</span
>
</div>
</div>
</div>
<q-card flat class="q-mt-md">
<q-card-section>
<div class="flex row items-center">
<q-avatar
size="40px"
font-size="18px"
rounded
color="orange-2"
text-color="orange"
class="text-weight-bold"
>
<img :src="newObjective.UserIcon" v-if="newObjective.UserIcon" />
<span v-else-if="newObjective.AuditUserName">{{
newObjective.AuditUserName .substring(0, 1)
}}</span>
</q-avatar>
<div class="col q-ml-md">
<div class="text-subtitle1">{{ newObjective.AuditUserName }}</div>
<div class="remark-font">{{ newObjective.AuditTime }}</div>
<q-card-section>
<div class="flex row items-center">
<q-avatar
size="40px"
font-size="18px"
rounded
color="orange-2"
text-color="orange"
class="text-weight-bold"
>
<img :src="newObjective.UserIcon" v-if="newObjective.UserIcon" />
<span v-else-if="newObjective.AuditUserName">{{
newObjective.AuditUserName.substring(0, 1)
}}</span>
</q-avatar>
<div class="col q-ml-md">
<div class="text-subtitle1">{{ newObjective.AuditUserName }}</div>
<div class="remark-font">{{ newObjective.AuditTime }}</div>
</div>
</div>
</div>
<div class="q-mt-md">
{{ decodeURIComponent(newObjective.AuditRemark) }}
</div>
</q-card-section>
</q-card>
<div class="q-mt-md">
{{ decodeURIComponent(newObjective.AuditRemark) }}
</div>
</q-card-section>
</q-card>
</div>
<q-dialog v-model="showPower">
<kr-power
......@@ -482,6 +592,13 @@
@save="saveFinish"
></kr-power>
</q-dialog>
<q-dialog v-model="showUnion">
<kr-union
:kr="krPwoerInfo"
:period="period"
@save="saveUnionFinish"
></kr-union>
</q-dialog>
</q-card>
</template>
......@@ -496,21 +613,24 @@ import {
setKRProgress,
setKRScore,
setObjectiveProgress,
setObjectiveState
setObjectiveState,
deleteKRRule
} from "../../api/okr/work";
import process from "./okr-process";
import objectiveProcess from "./objective-process";
import krPower from "./kr-power";
import progressRemark from "./progressRemark";
import okrAlign from './okr-align'
import okrAlign from "./okr-align";
import krUnion from "./kr-union";
export default {
props: ["objective"],
props: ["objective", "period"],
components: {
process,
objectiveProcess,
krPower,
progressRemark,
okrAlign
okrAlign,
krUnion
},
data() {
return {
......@@ -545,7 +665,8 @@ export default {
krPwoerInfo: {},
powerType: 3,
showProgressRemark: false,
periodId: 0
periodId: 0,
showUnion: false
};
},
created() {
......@@ -585,13 +706,20 @@ export default {
}
},
methods: {
setObjectiveStatus(){
setObjectiveState({
ObjectiveId:this.newObjective.Id
cancelRule(id){
deleteKRRule({
KeyResultId:id
}).then(r=>{
this.newObjective.Status=1
this.updatedObjective()
})
},
setObjectiveStatus() {
setObjectiveState({
ObjectiveId: this.newObjective.Id
}).then(r => {
this.newObjective.Status = 1;
});
},
addProgressRemark() {
this.showProgressRemark = true;
setTimeout(() => {
......@@ -600,7 +728,6 @@ export default {
},
closeProgressRemark(html) {
this.newObjective.ProgressRemark = encodeURIComponent(html);
console.log(this.newObjective.ProgressRemark);
this.changeState(2);
this.showProgressRemark = false;
},
......@@ -646,9 +773,17 @@ export default {
this.powerType = type;
this.showPower = true;
},
openUnion(kr) {
this.krPwoerInfo = kr;
this.showUnion = true;
},
saveFinish(isLock) {
this.showPower = false;
this.krPwoerInfo.IsLock=isLock?1:2
this.krPwoerInfo.IsLock = isLock ? 1 : 2;
},
saveUnionFinish() {
this.showUnion = false;
this.updatedObjective();
},
validateWeight(val, i) {
val = val < 0 ? 0 : val;
......@@ -656,7 +791,6 @@ export default {
this.keysReuslt[i].Weight = val;
},
changeWeight(i) {
console.log(i);
let msg = {
KeyResultId: this.keysReuslt[i].Id,
Weight: this.keysReuslt[i].Weight
......@@ -696,7 +830,6 @@ export default {
}
},
changeScore(i) {
console.log("保存分数");
let obj = this.keysReuslt[i].Score.toString();
if (obj.indexOf(".") == obj.length - 1) {
obj += "0";
......@@ -712,7 +845,6 @@ export default {
},
validateScore(i) {
let obj = this.keysReuslt[i].Score.toString();
console.log(this.keysReuslt[i].Score);
obj = obj.replace(/[^\d.]/g, "");
obj = obj.replace(/\.{2,}/g, ".");
obj = obj
......@@ -734,7 +866,6 @@ export default {
this.isUpdateProgress = true;
},
updateKrProcess(kr, i) {
console.log(kr);
this.keysReuslt[i] = kr;
this.$forceUpdate();
},
......@@ -758,8 +889,7 @@ export default {
changeKeysState(state, i) {
if (!this.isUpdateProgress) {
this.keysReuslt[i].newBoxState = state == 1;
this.$forceUpdate();
console.log(this.keysReuslt[i].KeyResultId);
this.$forceUpdate();
if (
state == 2 &&
((this.keysReuslt[i].Name != "" && !this.keysReuslt[i].Id) ||
......@@ -784,22 +914,34 @@ export default {
Type: kr.IsEasyMode == 1 ? 3 : 4,
ProgressState: kr.ProgressState
}).then(r => {
setKRProgress({
KeyResultId: kr.Id,
Type: kr.IsEasyMode,
Progress: kr.Progress,
StartValue: kr.StartValue,
EndValue: kr.EndValue,
CurrentValue: kr.CurrentValue
}).then(r => {
//this.updatedObjective()
this.newObjective.Progress = r.Data.TProgress;
setKRProgressState({
if (kr.RuleId == 0) {
setKRProgress({
KeyResultId: kr.Id,
Type: 1,
ProgressState: kr.ProgressState
}).then(r => {});
});
Type: kr.IsEasyMode,
Progress: kr.Progress,
StartValue: kr.StartValue,
EndValue: kr.EndValue,
CurrentValue: kr.CurrentValue
}).then(r => {
//
this.newObjective.Progress = r.Data.TProgress;
setKRProgressState({
KeyResultId: kr.Id,
Type: 1,
ProgressState: kr.ProgressState
}).then(r => {
this.updatedObjective()
});
});
}else{
setKRProgressState({
KeyResultId: kr.Id,
Type: 1,
ProgressState: kr.ProgressState
}).then(r => {
this.updatedObjective()
});
}
});
},
getRandomPlace() {
......@@ -818,6 +960,7 @@ export default {
});
if (i == -1) {
this.keysReuslt.push({
Id: 0,
KeyResultId: 0,
ObjectiveId: this.newObjective.Id,
Name: "",
......@@ -878,4 +1021,7 @@ export default {
.all-borders-2 {
border: 2px solid var(--q-color-primary) !important;
}
.okr-add .edui-editor {
z-index: 9 !important;
}
</style>
......@@ -74,9 +74,10 @@
评论
</q-tooltip>
</q-btn>
<q-btn unelevated color="white icon-btn q-mr-md">
<q-btn unelevated color="white icon-btn q-mr-md" @click="showOkrStatus">
<inline-svg
class="svg-icon svg-icon-secondary"
class="svg-icon"
:class="{'svg-icon-secondary':!isShowRemark,'svg-icon-white':isShowRemark}"
src="icons/svg/Code/Spy.svg"
></inline-svg>
<q-tooltip content-class="bg-dark">
......@@ -178,7 +179,8 @@ export default {
reloading: true,
isShowBox: false,
likeStatus: false,
auditPeroids: []
auditPeroids: [],
isShowRemark:false
};
},
watch: {
......@@ -216,6 +218,10 @@ export default {
this.queryLikeState();
},
methods: {
showOkrStatus(){
this.isShowRemark=!this.isShowRemark
this.$emit('remark-status',this.isShowRemark)
},
queryLikeState() {
queryUserIsLike({ UserId: this.user.Id }).then(r => {
this.likeStatus = r.Data;
......
......@@ -45,9 +45,10 @@
评论
</q-tooltip>
</q-btn>
<q-btn unelevated color="white icon-btn q-mr-md">
<q-btn unelevated :color="isShowRemark?'secondary':'white'" @click="showOkrStatus" class="icon-btn q-mr-md" >
<inline-svg
class="svg-icon svg-icon-secondary"
class="svg-icon"
:class="{'svg-icon-secondary':!isShowRemark,'svg-icon-white':isShowRemark}"
src="icons/svg/Code/Spy.svg"
></inline-svg>
<q-tooltip content-class="bg-dark">
......@@ -98,6 +99,7 @@
@cancel="changeUpdate"
class="q-mb-lg"
:ref="`object_${i}`"
:period='periodList[periodId]'
></okr-add>
</div>
<!-- <okr-add
......@@ -185,7 +187,8 @@ export default {
showPower: false,
krPwoerInfo: {},
powerType: 3,
isShowBox: false
isShowBox: false,
isShowRemark:false
};
},
watch: {
......@@ -201,6 +204,10 @@ export default {
this.user =this.userObj
},
methods: {
showOkrStatus(){
this.isShowRemark=!this.isShowRemark
this.$emit('remark-status',this.isShowRemark)
},
hideHistory() {
this.isShowBox = false;
},
......@@ -237,6 +244,11 @@ export default {
init() {
queryOKRPeriodList().then(r => {
this.periodList = r.Data;
this.periodList.forEach((x,i)=>{
if(x.IsCurrent==1){
this.periodId=i
}
})
this.$emit("change",this.periodList[this.periodId].Id)
this.queryMyObjective();
});
......
......@@ -22,12 +22,14 @@
style="width:240px;"
>
<div class="col">
<q-tooltip content-class="bg-dark" v-if="kr.RuleId>0">已使用系统模板,无法手动更新进度,如需更新请删除关联模板</q-tooltip>
<div class="text-subtitle2 text-weight-bold">起始值</div>
<q-input
dense
style="height:30px"
v-model="kr.StartValue"
@keyup="validateInput('StartValue')"
:disable="kr.RuleId>0"
>
</q-input>
</div>
......@@ -38,6 +40,7 @@
style="height:30px"
v-model="kr.CurrentValue"
@keyup="validateInput('CurrentValue')"
:disable="kr.RuleId>0"
>
</q-input>
</div>
......@@ -48,6 +51,7 @@
style="height:30px"
v-model="kr.EndValue"
@keyup="validateInput('EndValue')"
:disable="kr.RuleId>0"
>
</q-input>
</div>
......@@ -142,7 +146,7 @@ export default {
calcProcess() {
let crt = this.kr.CurrentValue - this.kr.StartValue;
if (crt > 0) {
this.kr.Progress = (crt * 100) / this.kr.EndValue;
this.kr.Progress = ((crt * 100) / (this.kr.EndValue-this.kr.StartValue)).toFixed(2);
} else {
this.kr.Progress = 0;
}
......
......@@ -40,27 +40,19 @@
direction="down"
v-if="newObjective.ChildList && newObjective.ChildList.length > 0"
></okr-align>
</div>
</template>
<template v-slot:prepend>
<div class="relative-position">
<inline-svg
v-if="newBoxState"
class="svg-icon svg-icon-primary"
src="icons/svg/Communication/Flag.svg"
></inline-svg>
<div
class="absolute"
style="bottom:0px;right:5px;height:14px;"
style="top:0px;right:0px;height:14px;"
v-if="newObjective.IsLock == 1"
>
<inline-svg
v-if="!newBoxState"
class="svg-icon svg-icon-grey"
src="icons/svg/General/Lock.svg"
width="14px"
height="14px"
></inline-svg>
<q-tooltip content-class="bg-dark">已设为保密内容,请勿外传</q-tooltip>
</div>
</div>
</template>
......@@ -148,6 +140,19 @@
class="flex row"
v-if="newObjective.Title && newObjective.Title.length > 0"
>
<div class="q-mr-lg" v-if="x.RuleId > 0" style="margin-top:22px">
<inline-svg
class="svg-icon svg-icon-secondary"
src="icons/svg/General/Save.svg"
width="20px"
height="20px"
></inline-svg>
<q-tooltip content-class="bg-dark"
>使用模板「{{
x.RuleName
}}」自动更新进度,<br />更新时间间隔一小时</q-tooltip
>
</div>
<div>
<span class="block remark-font text-right">进度</span>
<q-btn dense flat color="white" text-color="dark">
......@@ -168,7 +173,7 @@
<span>{{ x.Progress }}%</span>
</q-btn>
</div>
<div class="q-mx-lg" style="width:47px;text-align:right">
<div class="q-mx-lg" style="width:51px;text-align:right">
<span class="block remark-font text-right">权重</span>
<q-btn
dense
......@@ -221,7 +226,7 @@
<div class="text-subtitle2 text-weight-bold q-my-xs">
进度记录
</div>
<div class="text-body2" v-html="newObjective.ProgressRemark"></div>
<div class="text-body2" v-html="decodeURIComponent(newObjective.ProgressRemark)"></div>
</div>
</div>
</div>
......@@ -383,6 +388,7 @@ export default {
created() {
this.newObjective = this.objective;
this.audit.ObjectiveId = this.objective.Id;
},
watch: {
objective: {
......
<template>
<div class="flex column full-height" style="padding-top:54px !important;">
<!-- <img alt="Quasar logo" src="~assets/quasar-logo-full.svg"> -->
<div class="sub-header" v-if="AccountType==2 || ispower==true">
<div class="sub-header">
<!-- <div style="margin: 0 auto;width: 130px;">
<el-tabs v-model="model" >
<el-tab-pane :label="item.label" :name="item.value" :key="item.value" v-for="(item, index) in options"></el-tab-pane>
......@@ -32,11 +32,11 @@
</q-list>
</q-menu>
</q-btn>
<q-btn @click="changeMenu(2)" flat :color="chosenMenu==2?'primary':'blue-grey-14'" :class="[chosenMenu==2?'text-weight-bold':'']" label="备课管理">
<q-btn @click="changeMenu(2)" v-if="AccountType==2 || ispower==true" flat :color="chosenMenu==2?'primary':'blue-grey-14'" :class="[chosenMenu==2?'text-weight-bold':'']" label="备课管理">
</q-btn>
</div>
<div v-if="chosenMenu==1" class="flex col" style="flex: 1">
<okr></okr>
<okr v-if="okrMenu==1"></okr>
</div>
<div v-if="chosenMenu==2" class="col" style="height: 750px;overflow: auto">
<teachplan></teachplan>
......@@ -47,6 +47,7 @@
<script>
import teachplan from './course/teacherLesson'
import okr from './okr/index'
import alignView from './okr/okr-align-view'
export default {
components:{
teachplan,
......@@ -62,7 +63,8 @@
model: 'one',
AccountType:1,
ispower:false,//是否显示备课管理
chosenMenu:1
chosenMenu:1,
okrMenu:0
}
},
created() {
......@@ -90,6 +92,9 @@
},
methods:{
changeMenu(i){
if(i==1){
this.okrMenu=1
}
this.chosenMenu=i
},
getMapList(list){
......
......@@ -334,9 +334,22 @@
<okr-info
:user-obj="userParam"
@change="queryMyList"
@remark-status="updateOkrRemarkStatus"
v-if="!isOtherUser"
></okr-info>
<okr-emp-info :user-id="userInfo.Id" :user-obj="chosenUser" v-if="isOtherUser" :audit-mode="auditMode" :peroids="auditPeroids" @finish="deleteAuditUser" @addAudit="insertAuditUser"></okr-emp-info>
<okr-emp-info
:user-id="userInfo.Id"
:user-obj="chosenUser"
@remark-status="updateOkrRemarkStatus"
v-if="isOtherUser"
:audit-mode="auditMode"
:peroids="auditPeroids"
@finish="deleteAuditUser"
@addAudit="insertAuditUser"
></okr-emp-info>
</div>
<div class="col-auto" v-if="showOkrRemark" style="height:100%">
<gruid></gruid>
</div>
</div>
</template>
......@@ -351,6 +364,7 @@ import {
import { queryEmployee } from "../../api/users/user";
import okrInfo from "../../components/okr/okr-info";
import okrEmpInfo from "../../components/okr/okr-emp-info";
import gruid from "../../components/okr/guide";
export default {
data() {
return {
......@@ -364,13 +378,15 @@ export default {
usersList: [],
showResult: false,
aduitsList: [],
auditMode:false,
auditPeroids:""
auditMode: false,
auditPeroids: "",
showOkrRemark: false
};
},
components: {
okrInfo,
okrEmpInfo
okrEmpInfo,
gruid
},
computed: {
...mapGetters(["userInfo"])
......@@ -391,20 +407,23 @@ export default {
this.$root.$off("openUserObj", this.openUserObjective);
},
methods: {
insertAuditUser(obj){
updateOkrRemarkStatus(val) {
this.showOkrRemark = val;
},
insertAuditUser(obj) {
let index = -1;
this.aduitsList.forEach((x, i) => {
if (x.Id == obj.Id) {
if(x.PeriodIds.split(',').indexOf(obj.PeriodIds)==-1){
x.PeriodIds+=','+obj.PeriodIds
if (x.PeriodIds.split(",").indexOf(obj.PeriodIds) == -1) {
x.PeriodIds += "," + obj.PeriodIds;
}
}
});
if(index==-1){
this.aduitsList.push(obj)
if (index == -1) {
this.aduitsList.push(obj);
}
},
deleteAuditUser(id){
deleteAuditUser(id) {
let index = 0;
this.aduitsList.forEach((x, i) => {
if (x.Id == id) {
......@@ -463,15 +482,16 @@ export default {
this.getMe();
this.isOtherUser = false;
} else {
this.auditMode=m.indexOf('aduits_')!=-1&&obj.PeriodIds!=''
this.auditMode = m.indexOf("aduits_") != -1 && obj.PeriodIds != "";
this.chosenUser = obj;
this.isOtherUser = true;
this.auditPeroids=obj.PeriodIds
this.auditPeroids = obj.PeriodIds;
}
this.showOkrRemark=false
},
openUserObjective(obj) {
this.isOtherUser = obj.Id != this.userInfo.Id;
console.log(this.isOtherUser,obj.Id,this.userInfo)
console.log(this.isOtherUser, obj.Id, this.userInfo);
if (this.isOtherUser) {
this.chosenUser = obj;
} else {
......@@ -479,10 +499,11 @@ export default {
}
this.activeMenu = "";
this.searchText = "";
this.auditMode=false;
this.auditPeroids="";
this.auditMode = false;
this.auditPeroids = "";
this.usersList = [];
this.showResult = false;
this.showOkrRemark=false;
},
getMe() {
this.userParam = {
......
<template>
<div>
<div style="height:100%;">
<RelationGraph
ref="seeksRelationGraph"
:options="graphOptions"
:on-node-click="onNodeClick"
:on-line-click="onLineClick"
/>
</div>
</div>
</template>
<script>
import RelationGraph from "relation-graph";
export default {
name: "Demo",
components: { RelationGraph },
data() {
return {
graphOptions: {
allowSwitchLineShape: true,
allowSwitchJunctionPoint: true,
defaultJunctionPoint: "border"
// 这里可以参考"Graph 图谱"中的参数进行设置
}
};
},
mounted() {
this.showSeeksGraph();
},
methods: {
showSeeksGraph(query) {
var __graph_json_data = {
rootId: "a",
nodes: [
{ id: "a", text: "A", borderColor: "yellow" },
{ id: "b", text: "B", color: "#43a2f1", fontColor: "yellow" },
{ id: "c", text: "C", nodeShape: 1, width: 80, height: 60 },
{ id: "e", text: "E", nodeShape: 0, width: 150, height: 150 }
],
links: [
{ from: "a", to: "b", text: "关系1", color: "#43a2f1" },
{ from: "a", to: "c", text: "关系2" },
{ from: "a", to: "e", text: "关系3" },
{ from: "b", to: "e", color: "#67C23A" }
]
};
// 以上数据中的node和link可以参考"Node节点"和"Link关系"中的参数进行配置
this.$refs.seeksRelationGraph.setJsonData(
__graph_json_data,
seeksRGGraph => {
// Called when the relation-graph is completed
}
);
},
onNodeClick(nodeObject, $event) {
console.log("onNodeClick:", nodeObject);
},
onLineClick(lineObject, $event) {
console.log("onLineClick:", lineObject);
}
}
};
</script>
<style></style>
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