detail.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. <template>
  2. <basic-container>
  3. <div>
  4. <el-tabs v-model="activeType" :before-leave="beforeLeave">
  5. <el-tab-pane label="项目基本信息" name="1">
  6. <div>
  7. <el-form :model="projectForm" :rules="projectRules" ref="projectForm" label-width="120px">
  8. <el-row>
  9. <el-col :span="12">
  10. <el-form-item label="项目名称" prop="projectName">
  11. <el-input v-model="projectForm.projectName"></el-input>
  12. </el-form-item>
  13. <el-form-item label="项目别名" prop="projectAlias">
  14. <el-input v-model="projectForm.projectAlias"></el-input>
  15. </el-form-item>
  16. <el-form-item label="项目编号" prop="projectNumber">
  17. <el-input v-model="projectForm.projectNumber"></el-input>
  18. </el-form-item>
  19. <el-form-item label="公路等级" prop="projectGrade">
  20. <el-select v-model="projectForm.projectGrade" placeholder="请选择" class="w-100p">
  21. <el-option v-for="item in highwayGradeList" :key="item.id" :label="item.dictValue" :value="item.dictKey"></el-option>
  22. </el-select>
  23. </el-form-item>
  24. <el-form-item label="计划开工日期" prop="planStartTime">
  25. <el-date-picker v-model="projectForm.planStartTime" type="date" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期"></el-date-picker>
  26. </el-form-item>
  27. <el-form-item label="实际开工日期" prop="actualStartTime">
  28. <el-date-picker v-model="projectForm.actualStartTime" type="date" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期"></el-date-picker>
  29. </el-form-item>
  30. <el-form-item label="项目预算投资" prop="estimatedAmount">
  31. <el-input v-model="projectForm.estimatedAmount">
  32. <template slot="append">万元</template>
  33. </el-input>
  34. </el-form-item>
  35. </el-col>
  36. <el-col :span="12">
  37. <el-form-item label="项目概况" prop="projectGist">
  38. <el-input v-model="projectForm.projectGist" type="textarea" :rows="7"></el-input>
  39. </el-form-item>
  40. <el-form-item label="内置里程">
  41. <el-radio-group v-model="radioType">
  42. <el-radio-button label="总里程"></el-radio-button>
  43. <el-radio-button label="路面"></el-radio-button>
  44. <el-radio-button label="路基"></el-radio-button>
  45. </el-radio-group>
  46. <el-input-number v-model="projectForm.projectAllMileage" v-show="radioType == '总里程'" :min="0" label="总里程"></el-input-number>
  47. <el-input-number v-model="projectForm.projectPavement" v-show="radioType == '路面'" :min="0" label="路面"></el-input-number>
  48. <el-input-number v-model="projectForm.projectSubgrade" v-show="radioType == '路基'" :min="0" label="路基"></el-input-number>
  49. </el-form-item>
  50. <el-form-item label="计划完工日期" prop="planEndTime">
  51. <el-date-picker v-model="projectForm.planEndTime" type="date" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期"></el-date-picker>
  52. </el-form-item>
  53. <el-form-item label="实际完工日期" prop="actualEndTime">
  54. <el-date-picker v-model="projectForm.actualEndTime" type="date" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期"></el-date-picker>
  55. </el-form-item>
  56. </el-col>
  57. </el-row>
  58. </el-form>
  59. </div>
  60. </el-tab-pane>
  61. <el-tab-pane label="分配WBS模版" name="2">
  62. <div>
  63. <div class="text-align-c">
  64. <el-radio-group v-model="templateType">
  65. <el-radio :label="2">试验</el-radio>
  66. <el-radio :label="1">质检</el-radio>
  67. </el-radio-group>
  68. </div>
  69. <div class="text-align-c mg-t-20">
  70. <span class="mg-r-20">选择WBS</span>
  71. <el-select v-model="wbsId" @change="wbsChange" placeholder="请选择WBS" style="width:500px;">
  72. <el-option-group
  73. v-for="group in treeList"
  74. :key="group.label"
  75. :label="group.label">
  76. <el-option
  77. v-for="(item,index) in group.options"
  78. :key="index"
  79. :label="item.label"
  80. :value="item.value">
  81. </el-option>
  82. </el-option-group>
  83. </el-select>
  84. </div>
  85. <tree-tree :left-tree-data="leftTreeData" scrollbarStyle="height:calc(100vh - 500px)" ref="treetotree" :show-all-check="true" @onAddTree="treeChang" @onDelTree="treeChang" @onCheckAll="treeChang"></tree-tree>
  86. </div>
  87. </el-tab-pane>
  88. <el-tab-pane label="分配系统维护人员" name="3">
  89. <div>
  90. <div class="flex jc-al-c">
  91. <span class="mg-r-10">项目名称</span>
  92. <el-input v-model="projectForm.projectName" disabled style="width:300px;margin-right:30px;"></el-input>
  93. <span class="mg-r-10">合同段名称</span>
  94. <el-select v-model="cId" placeholder="请选择" @change="getUserByCondition">
  95. <el-option label="全部" value=""></el-option>
  96. <el-option v-for="item in contractList" :key="item.id" :label="item.contractName" :value="item.id"></el-option>
  97. </el-select>
  98. </div>
  99. <el-divider></el-divider>
  100. <div class="flex jc-al-c mg-b-10">
  101. <span>维护人员角色</span>
  102. <avue-input-tree :check-strictly="true" v-model="rId" placeholder="请选择" type="tree" :dic="roleList" :props="treeProps"></avue-input-tree>
  103. <!-- <el-select v-model="rId" clearable placeholder="请选择" @change="getUserByCondition">
  104. <el-option v-for="item in roleList" :key="item.id" :label="item.title" :value="item.id"></el-option>
  105. </el-select> -->
  106. </div>
  107. <div>
  108. <el-table :data="contractUserList" border height="500" style="width: 100%">
  109. <el-table-column prop="name" label="姓名" align="center"></el-table-column>
  110. <el-table-column prop="postName" label="岗位" align="center"></el-table-column>
  111. <el-table-column prop="phone" label="电话" align="center"></el-table-column>
  112. <el-table-column label="操作" align="center">
  113. <template slot-scope="scope">
  114. <el-button
  115. size="mini"
  116. type="danger"
  117. @click="handleDelete(scope.$index, scope.row)">删除</el-button>
  118. </template>
  119. </el-table-column>
  120. </el-table>
  121. </div>
  122. <div class="flex jc-al-c mg-t-20">
  123. <span>添加系内部人员</span>
  124. <el-select v-model="userId" filterable placeholder="请输入搜索">
  125. <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id"></el-option>
  126. </el-select>
  127. <el-button type="success" @click="addUserToProject">添加</el-button>
  128. <el-button type="primary">创建新用户</el-button>
  129. <el-button type="danger" @click="handleDeletes">全部删除</el-button>
  130. </div>
  131. <el-divider></el-divider>
  132. </div>
  133. </el-tab-pane>
  134. </el-tabs>
  135. <div class="flex jc-sb">
  136. <div></div>
  137. <div>
  138. <el-button type="success" size="medium" @click="saveQuit">保存并退出</el-button>
  139. <el-button type="info" size="medium" v-if="activeType != 1" @click="saveNext('p')">保存并返回上一步</el-button>
  140. <el-button type="info" size="medium" v-if="activeType != 3" @click="saveNext('n')">保存并进入下一步</el-button>
  141. </div>
  142. </div>
  143. </div>
  144. </basic-container>
  145. </template>
  146. <script>
  147. import {submitProject,getProjectDeatil,findWbsTreeList,findProjectTree,submitWbsTreeInProject} from "@/api/manager/projectinfo";
  148. import {findContractByProjectId,saveUserInfoByProject,findUserListByCondition,
  149. findUserByName,removeUsersByIds} from "@/api/manager/contractinfo";
  150. import {getRoleTree} from "@/api/system/role";
  151. import {getAlltree} from "@/api/manager/wbstree";
  152. import {getDictionary} from "@/api/system/dict";
  153. import {mapGetters} from "vuex";
  154. import treeTree from "@/components/tree-tree/main"
  155. export default {
  156. components: {
  157. treeTree
  158. },
  159. data() {
  160. return {
  161. activeType:'1',
  162. typeChang:{
  163. 1:false,
  164. 2:false,
  165. 3:false,
  166. },
  167. id:'',
  168. highwayGradeList:[],
  169. radioType:'总里程',
  170. projectForm:{},
  171. projectRules:{
  172. projectName: [
  173. { required: true, message: '请输入项目名称', trigger: 'blur' },
  174. ],
  175. projectAlias: [
  176. { required: true, message: '请输入项目别名', trigger: 'blur' },
  177. ],
  178. },
  179. contractList:[],
  180. cId:'',
  181. rId:'',
  182. roleList:[],
  183. userId:'',
  184. userList:[],
  185. contractUserList:[],
  186. treeProps:{
  187. label:"title",
  188. value:"id"
  189. },
  190. templateType:1,
  191. treeList:[],
  192. wbsId:'',
  193. leftTreeData:[],
  194. }
  195. },
  196. computed: {
  197. ...mapGetters(["userInfo"]),
  198. },
  199. watch:{
  200. projectForm:{
  201. handler: function() { // 此处注意,handler函数不能为箭头函数,this会取上下文,而不是组件里的this,此外,深度监听,必须为handler函数名,否则会无效果
  202. this.typeChang['1'] = true;
  203. },
  204. deep: true
  205. },
  206. activeType: async function (newValue) {
  207. if(newValue == '3'){
  208. this.getContractList();
  209. this.getRoleList();
  210. this.getUserByCondition();
  211. this.getUserByName();
  212. }else if(newValue == '2'){
  213. let refId = this.projectForm.referenceWbsTemplateId;
  214. if(refId && refId>0){
  215. //有引用id,回显
  216. this.wbsId = refId;
  217. let projectTree = await findProjectTree(this.projectForm.id,refId)
  218. if(Array.isArray(projectTree.data.data)){
  219. this.templateType = projectTree.data.data[0].wbsType;
  220. let leftData = await getAlltree(this.userInfo.tenant_id,'1',refId)
  221. if(Array.isArray(leftData.data.data)){
  222. this.leftTreeData = leftData.data.data;
  223. }else{
  224. this.leftTreeData = [];
  225. }
  226. this.$refs.treetotree.setRightTree(projectTree.data.data);
  227. }
  228. }
  229. this.getTreeList();
  230. }
  231. }
  232. },
  233. created() {
  234. this.init();
  235. //console.log(this.userInfo)
  236. },
  237. mounted(){
  238. this.$nextTick(()=>{
  239. this.typeChang = {
  240. 1:false,
  241. 2:false,
  242. 3:false,
  243. }
  244. })
  245. },
  246. methods: {
  247. init(){
  248. this.getHighwayGradeList();
  249. this.id = this.$route.query.id;
  250. if(this.id){
  251. this.getProjectDeatil();
  252. }
  253. },
  254. beforeLeave(activeName, oldActiveName){
  255. if(oldActiveName == '1' && !this.projectForm.id){
  256. this.$message({
  257. type: "warning",
  258. message: "请先保存项目后,再进行项目的分配"
  259. });
  260. return false;
  261. }
  262. if(this.typeChang[oldActiveName]){
  263. this.$confirm('检测到新编辑内容, 是否保存?', '提示', {
  264. confirmButtonText: '确定',
  265. cancelButtonText: '不用',
  266. type: 'warning'
  267. }).then(() => {
  268. switch (oldActiveName) {
  269. case '1':
  270. this.saveProject().then((res)=>{
  271. this.projectForm.id = res.data.data.id;
  272. this.$message({
  273. type: "success",
  274. message: "保存成功!"
  275. });
  276. });
  277. break;
  278. }
  279. })
  280. }
  281. },
  282. getProjectDeatil(){
  283. getProjectDeatil(this.id).then((res)=>{
  284. this.projectForm = res.data.data;
  285. this.$nextTick(()=>{
  286. this.typeChang['1'] = false;
  287. })
  288. })
  289. },
  290. async saveQuit(){
  291. if(this.activeType == '1'){
  292. await this.saveProject();
  293. }else if(this.activeType == '2'){
  294. await this.saveWbsTree();
  295. }
  296. this.$message({
  297. type: "success",
  298. message: "保存成功!"
  299. });
  300. this.$router.go(-1);
  301. },
  302. async saveNext(type){
  303. if(this.activeType == '1'){
  304. let res = await this.saveProject();
  305. this.projectForm.id = res.data.data.id;
  306. }else if(this.activeType == '2'){
  307. await this.saveWbsTree();
  308. }
  309. this.$message({
  310. type: "success",
  311. message: "保存成功!"
  312. });
  313. this.typeChang[this.activeType] = false;
  314. let num = Number(this.activeType);
  315. if(type == 'n'){
  316. num++;
  317. }else if(type == 'p'){
  318. num--;
  319. }
  320. this.activeType = num.toString();
  321. },
  322. saveProject(){
  323. return new Promise((resolve, reject) => {
  324. this.$refs['projectForm'].validate((valid) => {
  325. if (valid) {
  326. resolve(submitProject(this.projectForm))
  327. }else{
  328. reject('验证失败')
  329. }
  330. })
  331. })
  332. },
  333. saveWbsTree(){
  334. let obj = {};
  335. let ids = this.$refs.treetotree.getTreeAllId('rightTree');
  336. obj = {
  337. wbsId:this.wbsId,
  338. projectId:this.projectForm.id,
  339. wbsTreeIds:ids
  340. }
  341. return submitWbsTreeInProject(obj);
  342. },
  343. addUserToProject(){
  344. if(!this.userId){
  345. this.$message({
  346. type: "warning",
  347. message: "请先选择用户再进行添加"
  348. });
  349. return;
  350. }
  351. if(!this.rId){
  352. this.$message({
  353. type: "warning",
  354. message: "请先选择维护人员角色再进行添加"
  355. });
  356. return;
  357. }
  358. let list = [{
  359. projectId:this.projectForm.id,
  360. contractId:this.cId?this.cId:undefined,
  361. userId:this.userId,
  362. roleId:this.rId
  363. }];
  364. saveUserInfoByProject(list).then(()=>{
  365. this.getUserByCondition();
  366. })
  367. },
  368. getUserByCondition(){
  369. findUserListByCondition({
  370. cId:this.cId,
  371. pId:this.projectForm.id,
  372. postId:'',
  373. rId:this.rId,
  374. }).then((res)=>{
  375. this.contractUserList = res.data.data;
  376. })
  377. },
  378. getUserByName(){
  379. findUserByName('').then((res)=>{
  380. this.userList = res.data.data;
  381. })
  382. },
  383. handleDelete(index,row){
  384. this.$confirm('是否将该用户移除出合同段', '提示', {
  385. confirmButtonText: '确定',
  386. cancelButtonText: '取消',
  387. type: 'warning'
  388. }).then(() => {
  389. removeUsersByIds(row.id).then(()=>{
  390. this.contractUserList.splice(index,1);
  391. this.$message({
  392. type: "success",
  393. message: "删除成功!"
  394. });
  395. })
  396. })
  397. },
  398. handleDeletes(){
  399. this.$confirm('是否将所有用户移除出合同段', '提示', {
  400. confirmButtonText: '确定',
  401. cancelButtonText: '取消',
  402. type: 'warning'
  403. }).then(() => {
  404. let ids = [];
  405. this.contractUserList.forEach((element)=>{
  406. ids.push(element.id);
  407. })
  408. removeUsersByIds(ids.join(',')).then(()=>{
  409. this.contractUserList = [];
  410. this.$message({
  411. type: "success",
  412. message: "删除成功!"
  413. });
  414. })
  415. })
  416. },
  417. getHighwayGradeList(){
  418. if(this.highwayGradeList.length >1){
  419. return;
  420. }
  421. getDictionary({
  422. code:'highway_grade'
  423. }).then((res)=>{
  424. res.data.data.forEach(element => {
  425. element.dictKey = Number(element.dictKey)
  426. });
  427. this.highwayGradeList = res.data.data;
  428. })
  429. },
  430. getContractList(){
  431. if(this.contractList.length < 1){
  432. findContractByProjectId(this.projectForm.id).then((res)=>{
  433. this.contractList = res.data.data;
  434. })
  435. }
  436. },
  437. getRoleList(){
  438. if(this.roleList.length > 1){
  439. return;
  440. }
  441. getRoleTree().then((res)=>{
  442. this.roleList = res.data.data
  443. })
  444. },
  445. wbsChange(value){
  446. //console.log(value)
  447. if(value.toString().indexOf(',') >= 0){
  448. //私有库
  449. let ids = value.toString().split(',');
  450. findProjectTree(ids[1],ids[0]).then((res)=>{
  451. if(Array.isArray(res.data.data)){
  452. this.leftTreeData = res.data.data;
  453. }else{
  454. this.leftTreeData = [];
  455. }
  456. })
  457. }else{
  458. //公有库
  459. getAlltree(this.userInfo.tenant_id,'1',value).then((res)=>{
  460. if(Array.isArray(res.data.data)){
  461. this.leftTreeData = res.data.data;
  462. }else{
  463. this.leftTreeData = [];
  464. }
  465. })
  466. }
  467. },
  468. getTreeList(){
  469. return new Promise((resolve)=>{
  470. if(this.treeList.length){
  471. resolve();
  472. }
  473. findWbsTreeList(this.templateType).then((res)=>{
  474. let arr = [{
  475. label:'公有库',
  476. options:[],
  477. },
  478. {
  479. label:'私有库',
  480. options:[],
  481. }];
  482. let data = res.data.data;
  483. if(data.wbsInfos && data.wbsInfos.length){
  484. data.wbsInfos.forEach((element)=>{
  485. element.label = element.wbsName;
  486. element.value = element.id;
  487. })
  488. arr[0].options = data.wbsInfos;
  489. }
  490. if(data.wbsTreePrivates && data.wbsTreePrivates.length){
  491. data.wbsTreePrivates.forEach((element)=>{
  492. element.label = element.projectName;
  493. element.value = element.wbsId +','+ element.projectId;
  494. })
  495. arr[1].options = data.wbsTreePrivates;
  496. }
  497. this.treeList = arr;
  498. }).finally(()=>{
  499. resolve();
  500. })
  501. })
  502. },
  503. treeChang(){
  504. this.typeChang[2] = true;
  505. }
  506. }
  507. };
  508. </script>
  509. <style scoped lang="scss">
  510. </style>