project.vue 36 KB

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