project.vue 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. <template>
  2. <div class="w-main project">
  3. <v-title>{{$L('项目')}}</v-title>
  4. <div class="w-nav">
  5. <div class="nav-row">
  6. <div class="w-nav-left">
  7. <div class="page-nav-left">
  8. <span class="hover" @click="addShow=true"><i class="ft icon">&#xE740;</i> {{$L('新建项目')}}</span>
  9. <div v-if="loadIng > 0" class="page-nav-loading"><w-loading></w-loading></div>
  10. <div v-else class="page-nav-refresh"><em @click="getLists(true)">{{$L('刷新')}}</em></div>
  11. </div>
  12. </div>
  13. <div class="w-nav-flex"></div>
  14. <div class="w-nav-right m768-show">
  15. <Dropdown @on-click="handleProject" trigger="click" transfer>
  16. <Icon type="md-menu" size="18"/>
  17. <DropdownMenu slot="list">
  18. <DropdownItem name="myjoin">{{$L('参与的项目')}}</DropdownItem>
  19. <DropdownItem name="myfavor">{{$L('收藏的项目')}}</DropdownItem>
  20. <DropdownItem name="mycreate">{{$L('我管理的项目')}}</DropdownItem>
  21. </DropdownMenu>
  22. </Dropdown>
  23. </div>
  24. <div class="w-nav-right m768-hide">
  25. <span class="ft hover" @click="handleProject('myjoin', null)"><i class="ft icon">&#xE75E;</i> {{$L('参与的项目')}}</span>
  26. <span class="ft hover" @click="handleProject('myfavor', null)"><i class="ft icon">&#xE720;</i> {{$L('收藏的项目')}}</span>
  27. <span class="ft hover" @click="handleProject('mycreate', null)"><i class="ft icon">&#xE764;</i> {{$L('我管理的项目')}}</span>
  28. </div>
  29. </div>
  30. </div>
  31. <w-content>
  32. <!-- 列表 -->
  33. <ul class="project-list">
  34. <li v-for="item in lists">
  35. <div class="project-item">
  36. <div class="project-head">
  37. <div v-if="item.loadIng === true" class="project-loading">
  38. <w-loading></w-loading>
  39. </div>
  40. <div class="project-title" @click="handleProject('open', item)">{{item.title}}</div>
  41. <div class="project-setting">
  42. <Dropdown class="right-info" trigger="click" @on-click="handleProject($event, item)" transfer>
  43. <Icon class="project-setting-icon" type="md-settings" size="16"/>
  44. <Dropdown-menu slot="list">
  45. <Dropdown-item name="open">{{$L('打开')}}</Dropdown-item>
  46. <Dropdown-item name="favor">{{$L('收藏')}}</Dropdown-item>
  47. <Dropdown-item v-if="item.isowner" name="rename">{{$L('重命名')}}</Dropdown-item>
  48. <Dropdown-item v-if="item.isowner" name="transfer">{{$L('移交项目')}}</Dropdown-item>
  49. <Dropdown-item v-if="item.isowner" name="delete">{{$L('删除')}}</Dropdown-item>
  50. <Dropdown-item v-else name="out">{{$L('退出')}}</Dropdown-item>
  51. </Dropdown-menu>
  52. </Dropdown>
  53. </div>
  54. </div>
  55. <div class="project-num" @click="handleProject('open', item)">
  56. <div class="project-circle">
  57. <i-circle
  58. :size="100"
  59. :trail-width="8"
  60. :stroke-width="8"
  61. :percent="selfProportion(item.self_complete, item.self_count)"
  62. stroke-linecap="round"
  63. stroke-color="#62C5FE">
  64. <div class="project-circle-box">
  65. <div class="project-circle-num">
  66. <em>{{item.self_complete}}</em>
  67. <span>{{item.self_count}}</span>
  68. </div>
  69. <div class="project-circle-title">{{$L('个人总计')}}</div>
  70. </div>
  71. </i-circle>
  72. </div>
  73. <div class="project-situation">
  74. <ul>
  75. <li>{{$L('项目总任务数')}}<em>{{item.complete + item.unfinished}}</em></li>
  76. <li>{{$L('项目已完成数')}}<em>{{item.complete}}</em></li>
  77. <li>{{$L('项目未完成数')}}<em>{{item.unfinished}}</em></li>
  78. </ul>
  79. </div>
  80. </div>
  81. <div class="project-bottom">
  82. <div class="project-iconbtn">
  83. <Icon class="project-iconbtn-icon" type="md-stats" />
  84. <div class="project-iconbtn-text" @click.stop="handleProject('statistics', item)">{{$L('项目统计')}}</div>
  85. </div>
  86. <div class="project-iconbtn">
  87. <Icon class="project-iconbtn-icon" type="md-filing"/>
  88. <div class="project-iconbtn-text" @click.stop="handleProject('archived', item)">{{$L('已归档任务')}}</div>
  89. </div>
  90. <div class="project-iconbtn project-people" @click.stop="handleProject('member', item)">
  91. <UserImg v-for="(uItem, uKey) in item.people_lists" class="userimg-icon" :key="uKey" :info="uItem" two-words show-title/>
  92. <div v-if="item.people_count > 99" class="userimg-count" :title="item.people_count">99+</div>
  93. <div v-else-if="item.people_count > 5" class="userimg-count">{{item.people_count}}</div>
  94. </div>
  95. </div>
  96. </div>
  97. </li>
  98. </ul>
  99. <!-- 分页 -->
  100. <Page v-if="listTotal > 0" class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" :pageSize="listPageSize" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[20,40,60,100]" placement="top" transfer show-elevator show-sizer show-total :simple="windowMax768"></Page>
  101. </w-content>
  102. <Modal
  103. v-model="addShow"
  104. :title="$L('新建项目')"
  105. :closable="false"
  106. :mask-closable="false"
  107. class-name="simple-modal">
  108. <Form ref="add" :model="formAdd" :rules="ruleAdd" :label-width="80" @submit.native.prevent>
  109. <FormItem prop="title" :label="$L('项目名称')">
  110. <Input type="text" v-model="formAdd.title"></Input>
  111. </FormItem>
  112. <FormItem prop="labels" :label="$L('项目模板')">
  113. <Select v-model="formAdd.template" @on-change="(res) => {$set(formAdd, 'labels', labelLists[res].value)}">
  114. <Option v-for="(item, index) in labelLists" :value="index" :key="index">{{ item.label }}</Option>
  115. </Select>
  116. </FormItem>
  117. <FormItem :label="$L('项目流程')">
  118. <div style="line-height:38px">
  119. <span v-for="(item, index) in formAdd.labels">
  120. <span v-if="index > 0">&gt;</span>
  121. <Tag @on-close="() => { formAdd.labels.splice(index, 1)}" closable size="large" color="primary">{{item}}</Tag>
  122. </span>
  123. </div>
  124. <div v-if="formAdd.labels.length > 0" style="margin-top:4px;"></div>
  125. <div style="margin-bottom:-16px">
  126. <Button icon="ios-add" type="dashed" @click="addLabels">{{$L('添加流程')}}</Button>
  127. </div>
  128. </FormItem>
  129. </Form>
  130. <div slot="footer">
  131. <Button type="default" @click="addShow=false">{{$L('取消')}}</Button>
  132. <Button type="primary" :loading="loadIng > 0" @click="onAdd">{{$L('添加')}}</Button>
  133. </div>
  134. </Modal>
  135. <WDrawer v-model="projectDrawerShow" maxWidth="1000">
  136. <Tabs v-if="projectDrawerShow" v-model="projectDrawerTab">
  137. <TabPane :label="$L('已归档任务')" name="archived">
  138. <project-archived :canload="projectDrawerShow && projectDrawerTab == 'archived'" :projectid="handleProjectId"></project-archived>
  139. </TabPane>
  140. <TabPane :label="$L('项目统计')" name="statistics">
  141. <project-statistics :canload="projectDrawerShow && projectDrawerTab == 'statistics'" :projectid="handleProjectId"></project-statistics>
  142. </TabPane>
  143. <TabPane :label="$L('成员管理')" name="member">
  144. <project-users :canload="projectDrawerShow && projectDrawerTab == 'member'" :projectid="handleProjectId"></project-users>
  145. </TabPane>
  146. </Tabs>
  147. </WDrawer>
  148. <WDrawer v-model="projectListDrawerShow" maxWidth="740">
  149. <Tabs v-if="projectListDrawerShow" v-model="projectListDrawerTab">
  150. <TabPane :label="$L('参与的项目')" name="myjoin">
  151. <project-my-join :canload="projectListDrawerShow && projectListDrawerTab == 'myjoin'"></project-my-join>
  152. </TabPane>
  153. <TabPane :label="$L('收藏的项目')" name="myfavor">
  154. <project-my-favor :canload="projectListDrawerShow && projectListDrawerTab == 'myfavor'"></project-my-favor>
  155. </TabPane>
  156. <TabPane :label="$L('管理的项目')" name="mycreate">
  157. <project-my-manage :canload="projectListDrawerShow && projectListDrawerTab == 'mycreate'"></project-my-manage>
  158. </TabPane>
  159. </Tabs>
  160. </WDrawer>
  161. </div>
  162. </template>
  163. <style lang="scss" scoped>
  164. .project {
  165. ul.project-list {
  166. padding: 5px;
  167. max-width: 2200px;
  168. margin: 0 auto;
  169. li {
  170. float: left;
  171. width: 20%;
  172. display: flex;
  173. @media (max-width: 2000px) {
  174. width: 25%;
  175. }
  176. @media (max-width: 1400px) {
  177. width: 33.33%;
  178. }
  179. @media (max-width: 1080px) {
  180. width: 50%;
  181. }
  182. @media (max-width: 640px) {
  183. width: 100%;
  184. }
  185. .project-item {
  186. flex: 1;
  187. margin: 10px;
  188. width: 100%;
  189. height: 313px;
  190. padding: 20px;
  191. background-color: #ffffff;
  192. border-radius: 4px;
  193. display: flex;
  194. flex-direction: column;
  195. .project-head{
  196. display: flex;
  197. flex-direction: row;
  198. .project-loading {
  199. width: 18px;
  200. height: 18px;
  201. margin-right: 6px;
  202. margin-top: 3px;
  203. }
  204. .project-title{
  205. flex: 1;
  206. font-size: 16px;
  207. padding-right: 6px;
  208. overflow:hidden;
  209. text-overflow:ellipsis;
  210. white-space:nowrap;
  211. color: #333333;
  212. cursor: pointer;
  213. }
  214. .project-setting{
  215. width: 30px;
  216. text-align: right;
  217. .project-setting-icon {
  218. cursor: pointer;
  219. color: #333333;
  220. &:hover {
  221. color: #0396f2;
  222. }
  223. }
  224. }
  225. }
  226. .project-num {
  227. flex: 1;
  228. padding: 34px 0;
  229. display: flex;
  230. flex-direction: row;
  231. align-items: center;
  232. justify-content: center;
  233. cursor: pointer;
  234. position: relative;
  235. &:before {
  236. content: "";
  237. position: absolute;
  238. width: 1px;
  239. height: 60%;
  240. background-color: #EFEFEF;
  241. }
  242. .project-circle {
  243. flex: 1;
  244. text-align: center;
  245. margin-right: 10px;
  246. .project-circle-box {
  247. display: flex;
  248. flex-direction: column;
  249. align-items: center;
  250. justify-content: center;
  251. .project-circle-num {
  252. display: flex;
  253. align-items: flex-end;
  254. font-weight: 600;
  255. em {
  256. color: #62C5FE;
  257. font-size: 26px;
  258. }
  259. span {
  260. color: #666666;
  261. &:before {
  262. content: "/";
  263. }
  264. }
  265. }
  266. .project-circle-title {
  267. font-size: 12px;
  268. padding-top: 4px;
  269. color: #999999;
  270. }
  271. }
  272. }
  273. .project-situation {
  274. flex: 1;
  275. position: relative;
  276. ul {
  277. display: flex;
  278. flex-direction: column;
  279. position: absolute;
  280. top: 50%;
  281. left: 50%;
  282. transform: translate(-50%, -50%);
  283. > li {
  284. width: 100%;
  285. color: #BBBBBB;
  286. font-size: 12px;
  287. white-space: nowrap;
  288. display: flex;
  289. align-items: center;
  290. padding: 6px 0;
  291. line-height: 20px;
  292. > em {
  293. padding-left: 14px;
  294. font-size: 18px;
  295. color: #666666;
  296. font-weight: 500;
  297. }
  298. }
  299. }
  300. }
  301. }
  302. .project-bottom {
  303. display: flex;
  304. flex-direction: column;
  305. border-top: 1px solid #EFEFEF;
  306. padding: 18px 0;
  307. cursor: default;
  308. position: relative;
  309. .project-iconbtn {
  310. flex: 1;
  311. width: 50%;
  312. text-align: center;
  313. display: flex;
  314. align-items: center;
  315. padding: 4px 0;
  316. &.project-people {
  317. width: auto;
  318. min-width: 36px;
  319. position: absolute;
  320. bottom: 18px;
  321. right: 0;
  322. cursor: pointer;
  323. justify-content: flex-end;
  324. .userimg-icon,
  325. .userimg-count {
  326. width: 36px;
  327. height: 36px;
  328. border-radius: 18px;
  329. margin-left: -16px;
  330. border: 2px solid #ffffff;
  331. }
  332. .userimg-count {
  333. transform: scale(1);
  334. color: #ffffff;
  335. font-size: 16px;
  336. font-weight: 500;
  337. line-height: 32px;
  338. background-color: #62C5FE;
  339. }
  340. }
  341. .project-iconbtn-icon {
  342. font-size: 16px;
  343. margin-right: 6px;
  344. color: #999;
  345. }
  346. .project-iconbtn-text {
  347. color: #999999;
  348. cursor: pointer;
  349. &:hover {
  350. color: #0396f2;
  351. }
  352. }
  353. }
  354. }
  355. }
  356. }
  357. &:before,
  358. &:after {
  359. display: table;
  360. content: "";
  361. }
  362. &:after {
  363. clear: both;
  364. }
  365. }
  366. }
  367. </style>
  368. <script>
  369. import Vue from 'vue'
  370. import TagInput from '../components/TagInput'
  371. Vue.component('TagInput', TagInput)
  372. import WContent from "../components/WContent";
  373. import ProjectArchived from "../components/project/archived";
  374. import ProjectUsers from "../components/project/users";
  375. import ProjectStatistics from "../components/project/statistics";
  376. import ProjectMyFavor from "../components/project/my/favor";
  377. import ProjectMyJoin from "../components/project/my/join";
  378. import ProjectMyManage from "../components/project/my/manage";
  379. import Project from "../mixins/project";
  380. import WDrawer from "../components/iview/WDrawer";
  381. export default {
  382. components: {
  383. WDrawer,
  384. ProjectMyManage,
  385. ProjectMyJoin,
  386. ProjectMyFavor, ProjectStatistics, ProjectUsers, ProjectArchived, WContent},
  387. mixins: [
  388. Project
  389. ],
  390. data () {
  391. return {
  392. loadIng: 0,
  393. addShow: false,
  394. formAdd: {
  395. title: '',
  396. labels: [],
  397. template: 0,
  398. },
  399. ruleAdd: {},
  400. labelLists: [],
  401. lists: [],
  402. listPage: 1,
  403. listTotal: 0,
  404. listPageSize: 20,
  405. projectDrawerShow: false,
  406. projectDrawerTab: 'archived',
  407. projectListDrawerShow: false,
  408. projectListDrawerTab: 'myjoin',
  409. handleProjectId: 0,
  410. }
  411. },
  412. mounted() {
  413. this.getLists(true);
  414. //
  415. $A.setOnTaskInfoListener('pages/project',(act, detail) => {
  416. let item = this.lists.find((item) => { return item.id == detail.projectid });
  417. if (!item) {
  418. return;
  419. }
  420. const persons = detail.persons ? !!detail.persons.find(({username}) => username == this.usrName) : null;
  421. const unfinishedNum = (add) => {
  422. if (add) {
  423. item.unfinished++;
  424. persons === true && item.self_count++;
  425. } else {
  426. item.unfinished--;
  427. persons === true && item.self_count--;
  428. }
  429. };
  430. const completeNum = (add) => {
  431. if (add) {
  432. item.complete++;
  433. persons === true && item.self_complete++;
  434. } else {
  435. item.complete--;
  436. persons === true && item.self_complete--;
  437. }
  438. };
  439. switch (act) {
  440. case 'deleteproject': // 删除项目
  441. case 'deletelabel': // 删除分类
  442. this.getLists(true);
  443. break;
  444. case "create": // 创建任务
  445. unfinishedNum(true);
  446. break;
  447. case "delete": // 删除任务
  448. case "archived": // 归档
  449. if (detail.complete) {
  450. completeNum();
  451. } else {
  452. unfinishedNum();
  453. }
  454. break;
  455. case "unarchived": // 取消归档
  456. if (detail.complete) {
  457. completeNum(true);
  458. } else {
  459. unfinishedNum(true);
  460. }
  461. break;
  462. case "complete": // 标记完成
  463. completeNum(true);
  464. unfinishedNum();
  465. break;
  466. case "unfinished": // 标记未完成
  467. completeNum();
  468. unfinishedNum(true);
  469. break;
  470. }
  471. }, true);
  472. },
  473. deactivated() {
  474. this.addShow = false;
  475. this.projectDrawerShow = false;
  476. this.projectListDrawerShow = false;
  477. },
  478. watch: {
  479. usrName() {
  480. this.usrLogin && this.getLists(true);
  481. },
  482. },
  483. methods: {
  484. initLanguage() {
  485. this.labelLists = [{
  486. label: this.$L('空白模板'),
  487. value: [],
  488. }, {
  489. label: this.$L('软件开发'),
  490. value: [this.$L('产品规划'),this.$L('前端开发'),this.$L('后端开发'),this.$L('测试'),this.$L('发布'),this.$L('其它')],
  491. }, {
  492. label: this.$L('产品开发'),
  493. value: [this.$L('产品计划'), this.$L('正在设计'), this.$L('正在研发'), this.$L('测试'), this.$L('准备发布'), this.$L('发布成功')],
  494. }];
  495. this.ruleAdd = {
  496. title: [
  497. { required: true, message: this.$L('请填写项目名称!'), trigger: 'change' },
  498. { type: 'string', min: 2, message: this.$L('项目名称至少2个字!'), trigger: 'change' }
  499. ]
  500. };
  501. },
  502. setPage(page) {
  503. this.listPage = page;
  504. this.getLists();
  505. },
  506. setPageSize(size) {
  507. if (Math.max($A.runNum(this.listPageSize), 20) != size) {
  508. this.listPageSize = size;
  509. this.getLists();
  510. }
  511. },
  512. getLists(resetLoad) {
  513. if (resetLoad === true) {
  514. this.listPage = 1;
  515. }
  516. this.loadIng++;
  517. $A.apiAjax({
  518. url: 'project/lists',
  519. data: {
  520. page: Math.max(this.listPage, 1),
  521. pagesize: Math.max($A.runNum(this.listPageSize), 20),
  522. },
  523. complete: () => {
  524. this.loadIng--;
  525. },
  526. success: (res) => {
  527. if (res.ret === 1) {
  528. this.lists = res.data.lists;
  529. this.listTotal = res.data.total;
  530. }else{
  531. this.lists = [];
  532. this.listTotal = 0;
  533. }
  534. }
  535. });
  536. },
  537. addLabels() {
  538. this.labelsValue = "";
  539. this.$Modal.confirm({
  540. render: (h) => {
  541. return h('div', [
  542. h('div', {
  543. style: {
  544. fontSize: '16px',
  545. fontWeight: '500',
  546. marginBottom: '20px',
  547. }
  548. }, this.$L('添加流程')),
  549. h('TagInput', {
  550. props: {
  551. value: this.labelsValue,
  552. autofocus: true,
  553. placeholder: this.$L('请输入流程名称,多个可用英文逗号分隔。')
  554. },
  555. on: {
  556. input: (val) => {
  557. this.labelsValue = val;
  558. }
  559. }
  560. })
  561. ])
  562. },
  563. onOk: () => {
  564. if (this.labelsValue) {
  565. let array = $A.trim(this.labelsValue).split(",");
  566. array.forEach((name) => {
  567. if ($A.trim(name)) {
  568. this.formAdd.labels.push($A.trim(name));
  569. }
  570. });
  571. }
  572. },
  573. })
  574. },
  575. onAdd() {
  576. this.$refs.add.validate((valid) => {
  577. if (valid) {
  578. this.loadIng++;
  579. $A.apiAjax({
  580. url: 'project/add',
  581. data: this.formAdd,
  582. complete: () => {
  583. this.loadIng--;
  584. },
  585. success: (res) => {
  586. if (res.ret === 1) {
  587. this.addShow = false;
  588. this.$Message.success(res.msg);
  589. this.$refs.add.resetFields();
  590. this.$set(this.formAdd, 'template', 0);
  591. //
  592. this.getLists(true);
  593. } else {
  594. this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
  595. }
  596. }
  597. });
  598. }
  599. });
  600. },
  601. openComplete(item) {
  602. if (item.complete > 0) {
  603. this.openProject(item.id, item, '已完成')
  604. } else {
  605. this.handleProject('open', item);
  606. }
  607. },
  608. handleProject(event, item) {
  609. if (item) {
  610. this.handleProjectId = item.id;
  611. }
  612. switch (event) {
  613. case 'favor': {
  614. this.favorProject('add', item.id);
  615. break;
  616. }
  617. case 'rename': {
  618. this.renameProject(item);
  619. break;
  620. }
  621. case 'transfer': {
  622. this.transferProject(item);
  623. break;
  624. }
  625. case 'delete': {
  626. this.deleteProject(item.id, () => {
  627. this.getLists();
  628. });
  629. break;
  630. }
  631. case 'out': {
  632. this.outProject(item.id, () => {
  633. this.getLists();
  634. });
  635. break;
  636. }
  637. case 'open': {
  638. this.openProject(item.id, item);
  639. break;
  640. }
  641. case 'archived':
  642. case 'member':
  643. case 'statistics': {
  644. this.projectDrawerShow = true;
  645. this.projectDrawerTab = event;
  646. break;
  647. }
  648. case 'myjoin':
  649. case 'myfavor':
  650. case 'mycreate': {
  651. this.projectListDrawerShow = true;
  652. this.projectListDrawerTab = event;
  653. break;
  654. }
  655. }
  656. },
  657. renameProject(item) {
  658. this.renameValue = "";
  659. this.$Modal.confirm({
  660. render: (h) => {
  661. return h('div', [
  662. h('div', {
  663. style: {
  664. fontSize: '16px',
  665. fontWeight: '500',
  666. marginBottom: '20px',
  667. }
  668. }, this.$L('重命名项目')),
  669. h('Input', {
  670. props: {
  671. value: this.renameValue,
  672. autofocus: true,
  673. placeholder: this.$L('请输入新的项目名称')
  674. },
  675. on: {
  676. input: (val) => {
  677. this.renameValue = val;
  678. }
  679. }
  680. })
  681. ])
  682. },
  683. loading: true,
  684. onOk: () => {
  685. if (this.renameValue) {
  686. this.$set(item, 'loadIng', true);
  687. let title = this.renameValue;
  688. $A.apiAjax({
  689. url: 'project/rename',
  690. data: {
  691. projectid: item.id,
  692. title: title,
  693. },
  694. complete: () => {
  695. this.$set(item, 'loadIng', false);
  696. },
  697. error: () => {
  698. this.$Modal.remove();
  699. alert(this.$L('网络繁忙,请稍后再试!'));
  700. },
  701. success: (res) => {
  702. this.$Modal.remove();
  703. this.$set(item, 'title', title);
  704. setTimeout(() => {
  705. if (res.ret === 1) {
  706. this.$Message.success(res.msg);
  707. } else {
  708. this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
  709. }
  710. }, 350);
  711. }
  712. });
  713. } else {
  714. this.$Modal.remove();
  715. }
  716. },
  717. });
  718. },
  719. transferProject(item) {
  720. this.transferValue = "";
  721. this.$Modal.confirm({
  722. render: (h) => {
  723. return h('div', [
  724. h('div', {
  725. style: {
  726. fontSize: '16px',
  727. fontWeight: '500',
  728. marginBottom: '20px',
  729. }
  730. }, this.$L('移交项目')),
  731. h('UserInput', {
  732. props: {
  733. value: this.transferValue,
  734. nousername: item.username,
  735. placeholder: this.$L('请输入昵称/用户名搜索')
  736. },
  737. on: {
  738. input: (val) => {
  739. this.transferValue = val;
  740. }
  741. }
  742. })
  743. ])
  744. },
  745. loading: true,
  746. onOk: () => {
  747. if (this.transferValue) {
  748. this.$set(item, 'loadIng', true);
  749. let username = this.transferValue;
  750. $A.apiAjax({
  751. url: 'project/transfer',
  752. data: {
  753. projectid: item.id,
  754. username: username,
  755. },
  756. complete: () => {
  757. this.$set(item, 'loadIng', false);
  758. },
  759. error: () => {
  760. this.$Modal.remove();
  761. alert(this.$L('网络繁忙,请稍后再试!'));
  762. },
  763. success: (res) => {
  764. this.$Modal.remove();
  765. this.getLists();
  766. setTimeout(() => {
  767. if (res.ret === 1) {
  768. this.$Message.success(res.msg);
  769. } else {
  770. this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
  771. }
  772. }, 350);
  773. }
  774. });
  775. } else {
  776. this.$Modal.remove();
  777. }
  778. },
  779. });
  780. },
  781. selfProportion(complete, count) {
  782. if (count <= 0) {
  783. return 100;
  784. }
  785. return Math.round(complete / count * 100)
  786. }
  787. },
  788. }
  789. </script>