PerTargetConfirmSelectorOnly.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. <template>
  2. <el-dialog
  3. :visible.sync="innerVisible"
  4. @close="handleClose"
  5. @open="initData"
  6. @closed="dataReset"
  7. append-to-body
  8. :close-on-click-modal="false"
  9. center
  10. title="目标确认节点配置"
  11. width="600px"
  12. >
  13. <el-form v-if="currentNode" label-width="200">
  14. <el-form-item label="启用">
  15. <el-switch
  16. v-model="currentNode.enable"
  17. />
  18. </el-form-item>
  19. <el-form-item label="">
  20. <div class="handler-list">
  21. <el-tag
  22. v-for="(item,index) in currentNode.children"
  23. :key="index"
  24. :type="childIndex === index ? '' : 'info'"
  25. closable
  26. @close="removeChild(index)"
  27. @click="childSelect(index)"
  28. >
  29. {{assigneeMap[item.assigneeType] || '未知'}}
  30. </el-tag>
  31. <el-button
  32. v-show="currentNode.enable"
  33. icon="el-icon-plus"
  34. size="mini"
  35. style="margin-bottom: 10px;"
  36. @click="addChild"
  37. />
  38. </div>
  39. </el-form-item>
  40. <el-form-item label="确认人">
  41. <el-radio-group
  42. v-model="currentNode.children[childIndex].assigneeType"
  43. :disabled="!currentNode.enable"
  44. @change="onAssigneeTypeChange"
  45. >
  46. <el-radio-button label="leader">组织管理员</el-radio-button>
  47. <el-radio-button label="user">指定人员</el-radio-button>
  48. <el-radio-button label="self">被考核人</el-radio-button>
  49. <el-radio-button label="post">岗位</el-radio-button>
  50. <el-radio-button label="deptLeader">部门负责人</el-radio-button>
  51. </el-radio-group>
  52. </el-form-item>
  53. <el-form-item label="">
  54. <template v-if="currentNode.children[childIndex].assigneeType === 'leader'">
  55. <el-select
  56. v-model="currentNode.children[childIndex].leaderLevel"
  57. placeholder="请选择管理员"
  58. :disabled="!currentNode.enable"
  59. filterable
  60. style="width: 300px;"
  61. key="leader"
  62. @change="onOrgManagerChange"
  63. >
  64. <el-option
  65. v-for="item in levelOptions"
  66. :key="item.value"
  67. :label="item.label"
  68. :value="item.value"
  69. style="width: 300px;"
  70. />
  71. </el-select>
  72. </template>
  73. <template v-if="currentNode.children[childIndex].assigneeType === 'user'">
  74. <el-select
  75. v-model="userSelected"
  76. placeholder="请选择指定人员"
  77. multiple
  78. :disabled="!currentNode.enable"
  79. filterable
  80. style="width: 300px;"
  81. key="user"
  82. @change="onUserChange"
  83. >
  84. <el-option
  85. v-for="item in employees"
  86. :key="item.id"
  87. :label="item.name"
  88. :value="item.id"
  89. style="width: 300px;"
  90. />
  91. </el-select>
  92. </template>
  93. <template v-if="currentNode.children[childIndex].assigneeType === 'post'">
  94. <el-select
  95. v-model="postSelected"
  96. placeholder="请选择岗位"
  97. multiple
  98. :disabled="!currentNode.enable"
  99. filterable
  100. style="width: 300px;"
  101. key="post"
  102. @change="onPostChange"
  103. >
  104. <el-option
  105. v-for="item in postList"
  106. :key="item.id"
  107. :label="item.name"
  108. :value="item.id"
  109. style="width: 300px;"
  110. />
  111. </el-select>
  112. </template>
  113. <template v-if="currentNode.children[childIndex].assigneeType === 'deptLeader'">
  114. <el-select
  115. v-model="deptSelected"
  116. placeholder="请选择部门"
  117. multiple
  118. :disabled="!currentNode.enable"
  119. filterable
  120. style="width: 300px;"
  121. key="deptLeader"
  122. @change="onDeptChange"
  123. >
  124. <el-option
  125. v-for="item in deptList"
  126. :key="item.id"
  127. :label="item.name"
  128. :value="item.id"
  129. style="width: 300px;"
  130. />
  131. </el-select>
  132. </template>
  133. </el-form-item>
  134. <el-form-item label="多人时">
  135. <el-radio-group
  136. v-model="currentNode.children[childIndex].multipleType"
  137. :disabled="!currentNode.enable"
  138. >
  139. <el-radio-button label="or">任一人确认(或签)</el-radio-button>
  140. <el-radio-button label="parallel">按顺序确认(会签)</el-radio-button>
  141. <el-radio-button label="sequence">同时确认(会签)</el-radio-button>
  142. </el-radio-group>
  143. </el-form-item>
  144. <el-form-item label="允许">
  145. <el-checkbox-group v-model="currentNode.children[childIndex].allows"
  146. :disabled="!currentNode.enable">
  147. <el-checkbox-button label="edit">修改指标</el-checkbox-button>
  148. <el-checkbox-button label="transfer">转交</el-checkbox-button>
  149. </el-checkbox-group>
  150. </el-form-item>
  151. </el-form>
  152. <template #footer>
  153. <el-row type="flex" justify="end">
  154. <el-col align="end">
  155. <el-button
  156. type="primary"
  157. @click="onConfirm"
  158. >
  159. 确认
  160. </el-button>
  161. </el-col>
  162. </el-row>
  163. </template>
  164. </el-dialog>
  165. </template>
  166. <script>
  167. import Template from "../../examine/components/Template.vue";
  168. export default {
  169. name: "PerTargetConfirmSelectorOnly",
  170. components: {Template},
  171. props: {
  172. showVisible: {
  173. type: Boolean,
  174. default: false
  175. },
  176. },
  177. data(){
  178. return {
  179. userInfo: this.$userInfo(),
  180. currentNode: null,
  181. childIndex: null,
  182. innerVisible: this.showVisible,
  183. loading:false,
  184. employees:[],
  185. postList:[],
  186. deptList:[],
  187. userSelected:[],
  188. postSelected:[],
  189. deptSelected:[],
  190. assigneeMap:{
  191. leader:'组织管理员',
  192. user:'指定人员',
  193. self:'被考核人',
  194. post:'岗位',
  195. deptLeader:'部门负责人',
  196. },
  197. levelOptions: [
  198. {
  199. value: 1,
  200. label: '直接管理员'
  201. },
  202. {
  203. value: 2,
  204. label: '二级管理员'
  205. },
  206. {
  207. value: 3,
  208. label: '三级管理员'
  209. },
  210. {
  211. value: 4,
  212. label: '四级管理员'
  213. },
  214. {
  215. value: 5,
  216. label: '五级管理员'
  217. },
  218. {
  219. value: 6,
  220. label: '六级管理员'
  221. }
  222. ]
  223. }
  224. },
  225. computed:{
  226. employeeMap(){
  227. const map = {};
  228. this.employees.forEach(e => {
  229. if (!map[e.id]) map[e.id] = e.name;
  230. });
  231. return map;
  232. },
  233. postMap(){
  234. const map = {};
  235. this.postList.forEach(e => {
  236. if (!map[e.id]) map[e.id] = e.name;
  237. });
  238. return map;
  239. },
  240. deptMap(){
  241. const map = {};
  242. this.deptList.forEach(e => {
  243. if (!map[e.id]) map[e.id] = e.name;
  244. });
  245. return map;
  246. },
  247. },
  248. watch:{
  249. showVisible(val){
  250. this.innerVisible = val;
  251. },
  252. },
  253. methods: {
  254. idGeneral(){
  255. return Date.now() + Math.floor(Math.random() * 10000);
  256. },
  257. defaultNode(){
  258. const node = JSON.parse("{\"id\":\"TCS_1906993155344510977\",\"type\":\"targetConfirms\",\"enable\":true,\"assigneeType\":\"self\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[],\"weight\":0,\"children\":[{\"id\":\"TC_1906993155344510978\",\"type\":\"targetConfirm\",\"enable\":true,\"assigneeType\":\"self\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[],\"weight\":0,\"children\":[]}]}");
  259. node.id = "TCS_" + this.idGeneral();
  260. node.children.forEach((_,i) => {
  261. node.children[i].id = "TC_" + this.idGeneral();
  262. });
  263. return node;
  264. },
  265. matchErrMsg(err){
  266. return err.toString().replace(/[(Error: )]/g,'');
  267. },
  268. handleClose(){
  269. this.$emit('update:showVisible',false);
  270. },
  271. dataReset(){
  272. this.currentNode = null;
  273. this.childIndex = null;
  274. this.userSelected = [];
  275. this.postSelected = [];
  276. this.deptSelected = [];
  277. },
  278. initData(){
  279. if (this.loading) return;
  280. this.dataReset();
  281. this.loading = true;
  282. let result = true;
  283. Promise.all([
  284. this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
  285. this.$axiosUser('get','/org/post'),
  286. this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
  287. ])
  288. .then(([employeeRes,postRes,deptRes]) => {
  289. if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
  290. if (postRes.data.code !== 1) throw new Error(postRes.data.message);
  291. if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
  292. this.employees = employeeRes.data.data.list
  293. .filter(e => e.account_id && e.account_id > 0)
  294. .map(e => {
  295. return {
  296. id:e.id,
  297. name:e.name,
  298. }
  299. });
  300. this.postList = postRes.data.data.map(item => {
  301. return {
  302. id: item.id,
  303. name: item.name,
  304. }
  305. });
  306. this.deptList = deptRes.data.data.list.map(item => {
  307. return {
  308. id: item.id,
  309. name: item.name,
  310. }
  311. });
  312. this.currentNode = this.defaultNode();
  313. this.childIndex = this.currentNode.children && this.currentNode.children.length > 0 ? 0 : null;
  314. if (this.childIndex !== null && !!this.currentNode.children[this.childIndex]){
  315. switch (this.currentNode.children[this.childIndex].assigneeType){
  316. case 'user':
  317. this.userSelected = this.currentNode.children[this.childIndex].assigneeIds;
  318. break;
  319. case 'post':
  320. this.postSelected = this.currentNode.children[this.childIndex].assigneeIds;
  321. break;
  322. case 'deptLeader':
  323. this.deptSelected = this.currentNode.children[this.childIndex].assigneeIds;
  324. break;
  325. }
  326. }
  327. })
  328. .catch(err => {
  329. this.$message.error(this.matchErrMsg(err));
  330. result = false;
  331. })
  332. .finally(() => {
  333. this.loading = false;
  334. if (!result) this.handleClose();
  335. })
  336. },
  337. generalId(){
  338. return Date.now() + Math.floor(Math.random() * 10000);
  339. },
  340. addChild(){
  341. let id = "TC_" + this.generalId();
  342. this.currentNode.children.push({
  343. id:id,
  344. type:'targetConfirm',
  345. enable:true,
  346. assigneeType:'self',
  347. leaderLevel:1,
  348. assigneeIds:[],
  349. multipleType:'or',
  350. allows:[],
  351. weight:0,
  352. children:[],
  353. });
  354. },
  355. removeChild(index){
  356. if (this.currentNode.children.length <= 1 || !this.currentNode.children[index]) return;
  357. let selectChildId = this.currentNode.children[index].id;
  358. this.childIndex = 0;
  359. this.currentNode.children = this.currentNode.children.filter((_,i) => i !== index);
  360. if (selectChildId){
  361. this.currentNode.children.forEach((child,i) => {
  362. if (child.id === selectChildId) this.childIndex = i;
  363. })
  364. }
  365. },
  366. onAssigneeTypeChange(v){
  367. this.currentNode.children[this.childIndex].assigneeIds = [];
  368. this.currentNode.children[this.childIndex].leaderLevel = 1;
  369. this.userSelected = [];
  370. this.postSelected = [];
  371. this.deptSelected = [];
  372. },
  373. onOrgManagerChange(v){
  374. this.currentNode.children[this.childIndex].assigneeIds = [];
  375. this.currentNode.children[this.childIndex].leaderLevel = v;
  376. this.userSelected = [];
  377. this.postSelected = [];
  378. this.deptSelected = [];
  379. },
  380. onUserChange(v){
  381. this.currentNode.children[this.childIndex].assigneeIds = [...v];
  382. this.currentNode.children[this.childIndex].leaderLevel = 1;
  383. this.userSelected = v;
  384. this.postSelected = [];
  385. this.deptSelected = [];
  386. },
  387. onPostChange(v){
  388. this.currentNode.children[this.childIndex].assigneeIds = [...v];
  389. this.currentNode.children[this.childIndex].leaderLevel = 1;
  390. this.userSelected = [];
  391. this.postSelected = v;
  392. this.deptSelected = [];
  393. },
  394. onDeptChange(v){
  395. this.currentNode.children[this.childIndex].assigneeIds = [...v];
  396. this.currentNode.children[this.childIndex].leaderLevel = 1;
  397. this.userSelected = [];
  398. this.postSelected = [];
  399. this.deptSelected = v;
  400. },
  401. childSelect(index){
  402. if (!this.currentNode.children[index]) return;
  403. this.childIndex = index;
  404. this.userSelected = this.currentNode.children[this.childIndex].assigneeType === 'user' ? this.currentNode.children[this.childIndex].assigneeIds : [];
  405. this.postSelected = this.currentNode.children[this.childIndex].assigneeType === 'post' ? this.currentNode.children[this.childIndex].assigneeIds : [];
  406. this.deptSelected = this.currentNode.children[this.childIndex].assigneeType === 'deptLeader' ? this.currentNode.children[this.childIndex].assigneeIds : [];
  407. },
  408. onConfirm(){
  409. this.$emit('confirm',this.currentNode);
  410. this.handleClose();
  411. },
  412. }
  413. }
  414. </script>
  415. <style scoped lang="scss">
  416. .handler-list {
  417. width: 500px;
  418. margin: 0 auto 16px auto;
  419. border-radius: 6px;
  420. border: 1px solid #d7dae2;
  421. padding: 10px 0 0 10px;
  422. box-sizing: border-box;
  423. display: flex;
  424. flex-wrap: wrap;
  425. .el-tag {
  426. margin: 0 10px 10px 0;
  427. cursor: pointer;
  428. }
  429. }
  430. </style>