files.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. <template>
  2. <drawer-tabs-container>
  3. <div class="project-task-file">
  4. <!-- 搜索 -->
  5. <Row v-if="!simple" class="sreachBox">
  6. <div class="item">
  7. <div class="item-2">
  8. <sreachTitle :val="keys.name">{{$L('文件名')}}</sreachTitle>
  9. <Input v-model="keys.name" :placeholder="$L('关键词')"/>
  10. </div>
  11. <div class="item-2">
  12. <sreachTitle :val="keys.username">{{$L('上传者')}}</sreachTitle>
  13. <Input v-model="keys.username" :placeholder="$L('用户名')"/>
  14. </div>
  15. </div>
  16. <div class="item item-button">
  17. <Button type="text" v-if="$A.objImplode(keys)!=''" @click="sreachTab(true)">{{$L('取消筛选')}}</Button>
  18. <Button type="primary" icon="md-search" :loading="loadIng > 0" @click="sreachTab">{{$L('搜索')}}</Button type="primary">
  19. </div>
  20. </Row>
  21. <!-- 按钮 -->
  22. <Row class="butBox" :style="`float:left;margin-top:-32px;${simple?'display:none':''}`">
  23. <Upload
  24. name="files"
  25. ref="upload"
  26. :action="actionUrl"
  27. :data="params"
  28. multiple
  29. :format="uploadFormat"
  30. :show-upload-list="false"
  31. :max-size="10240"
  32. :on-success="handleSuccess"
  33. :on-format-error="handleFormatError"
  34. :on-exceeded-size="handleMaxSize"
  35. :before-upload="handleBeforeUpload">
  36. <Button :loading="loadIng > 0" type="primary" icon="ios-cloud-upload-outline" @click="">{{$L('上传文件')}}</Button>
  37. </Upload>
  38. </Row>
  39. <!-- 列表 -->
  40. <Table class="tableFill" ref="tableRef" :size="!simple?'default':'small'" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" @on-sort-change="sortChange" stripe></Table>
  41. <!-- 分页 -->
  42. <Page v-if="lastPage > 1 || !simple" :simple="simple" class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
  43. </div>
  44. </drawer-tabs-container>
  45. </template>
  46. <style lang="scss" scoped>
  47. .project-task-file {
  48. margin: 0 12px;
  49. .tableFill {
  50. margin: 12px 0 20px;
  51. }
  52. }
  53. </style>
  54. <script>
  55. import Vue from 'vue'
  56. import VueClipboard from 'vue-clipboard2'
  57. import DrawerTabsContainer from "../../DrawerTabsContainer";
  58. Vue.use(VueClipboard)
  59. export default {
  60. name: 'ProjectTaskFiles',
  61. components: {DrawerTabsContainer},
  62. props: {
  63. projectid: {
  64. default: 0
  65. },
  66. taskid: {
  67. default: 0
  68. },
  69. canload: {
  70. type: Boolean,
  71. default: true
  72. },
  73. simple: {
  74. type: Boolean,
  75. default: false
  76. },
  77. },
  78. data() {
  79. return {
  80. keys: {},
  81. sorts: {key:'', order:''},
  82. loadYet: false,
  83. loadIng: 0,
  84. columns: [],
  85. lists: [],
  86. listPage: 1,
  87. listTotal: 0,
  88. lastPage: 0,
  89. noDataText: "",
  90. uploadFormat: ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'],
  91. actionUrl: $A.apiUrl('project/files/upload'),
  92. params: {
  93. token: $A.getToken(),
  94. taskid: this.taskid,
  95. projectid: this.projectid
  96. },
  97. uploadList: [],
  98. }
  99. },
  100. created() {
  101. this.noDataText = this.$L("数据加载中.....");
  102. let columns = [];
  103. columns.push({
  104. "title": "",
  105. "width": 60,
  106. render: (h, params) => {
  107. if (!params.row.thumb) {
  108. return h('WLoading', {
  109. style: {
  110. width: "24px",
  111. height: "24px",
  112. verticalAlign: "middle",
  113. },
  114. });
  115. }
  116. return h('img', {
  117. style: {
  118. width: "28px",
  119. height: "28px",
  120. verticalAlign: "middle",
  121. },
  122. attrs: {
  123. src: params.row.thumb
  124. },
  125. });
  126. }
  127. });
  128. columns.push({
  129. "title": this.$L("文件名"),
  130. "key": 'name',
  131. "minWidth": 100,
  132. "tooltip": true,
  133. "sortable": true,
  134. render: (h, params) => {
  135. let arr = [h('span', params.row.name)];
  136. if (params.row.showProgress === true) {
  137. arr.push(h('Progress', {
  138. style: {
  139. display: 'block',
  140. marginTop: '-3px'
  141. },
  142. props: {
  143. percent: params.row.percentage || 100,
  144. },
  145. }));
  146. }
  147. return h('div', arr);
  148. },
  149. });
  150. columns.push({
  151. "title": this.$L("大小"),
  152. "key": 'size',
  153. "minWidth": 90,
  154. "maxWidth": 120,
  155. "align": "right",
  156. "sortable": true,
  157. render: (h, params) => {
  158. return h('span', $A.bytesToSize(params.row.size));
  159. },
  160. });
  161. if (!this.simple) {
  162. columns.push({
  163. "title": this.$L("下载次数"),
  164. "key": 'download',
  165. "align": "center",
  166. "sortable": true,
  167. "width": 100,
  168. });
  169. columns.push({
  170. "title": this.$L("上传者"),
  171. "key": 'username',
  172. "minWidth": 90,
  173. "maxWidth": 130,
  174. "sortable": true,
  175. render: (h, params) => {
  176. return h('UserView', {
  177. props: {
  178. username: params.row.username
  179. }
  180. });
  181. }
  182. });
  183. columns.push({
  184. "title": this.$L("上传时间"),
  185. "key": 'indate',
  186. "width": 160,
  187. "sortable": true,
  188. render: (h, params) => {
  189. return h('span', $A.formatDate("Y-m-d H:i:s", params.row.indate));
  190. }
  191. });
  192. }
  193. columns.push({
  194. "title": " ",
  195. "key": 'action',
  196. "align": 'right',
  197. "width": 120,
  198. render: (h, params) => {
  199. if (!params.row.id) {
  200. return null;
  201. }
  202. return h('div', [
  203. h('Tooltip', {
  204. props: { content: this.$L('下载'), transfer: true, delay: 600 },
  205. style: { position: 'relative' },
  206. }, [h('Icon', {
  207. props: { type: 'md-arrow-down', size: 16 },
  208. style: { margin: '0 3px', cursor: 'pointer' },
  209. }), h('a', {
  210. style: { position: 'absolute', top: '0', left: '0', right: '0', bottom: '0', 'zIndex': 1 },
  211. attrs: { href: $A.apiUrl('project/files/download?fileid=' + params.row.id), target: '_blank' },
  212. on: {
  213. click: () => {
  214. if (params.row.yetdown) {
  215. return;
  216. }
  217. params.row.yetdown = 1;
  218. this.$set(params.row, 'download', params.row.download + 1);
  219. }
  220. }
  221. })]),
  222. h('Tooltip', {
  223. props: { content: this.$L('重命名'), transfer: true, delay: 600 }
  224. }, [h('Icon', {
  225. props: { type: 'md-create', size: 16 },
  226. style: { margin: '0 3px', cursor: 'pointer' },
  227. on: {
  228. click: () => {
  229. this.renameFile(params.row);
  230. }
  231. }
  232. })]),
  233. h('Tooltip', {
  234. props: { content: this.$L('复制链接'), transfer: true, delay: 600 }
  235. }, [h('Icon', {
  236. props: { type: 'md-link', size: 16 },
  237. style: { margin: '0 3px', cursor: 'pointer', transform: 'rotate(-45deg)' },
  238. on: {
  239. click: () => {
  240. this.$copyText($A.apiUrl('project/files/download?fileid=' + params.row.id)).then(() => {
  241. this.$Message.success(this.$L('复制成功!'));
  242. }, () => {
  243. this.$Message.error(this.$L('复制失败!'));
  244. });
  245. }
  246. }
  247. })]),
  248. h('Tooltip', {
  249. props: { content: this.$L('删除'), transfer: true, delay: 600 }
  250. }, [h('Icon', {
  251. props: { type: 'md-trash', size: 16 },
  252. style: { margin: '0 3px', cursor: 'pointer' },
  253. on: {
  254. click: () => {
  255. this.deleteFile(params.row);
  256. }
  257. }
  258. })]),
  259. ]);
  260. }
  261. });
  262. this.columns = columns;
  263. },
  264. mounted() {
  265. if (this.canload) {
  266. this.loadYet = true;
  267. this.getLists(true);
  268. }
  269. this.uploadList = this.$refs.upload.fileList;
  270. },
  271. watch: {
  272. projectid() {
  273. if (this.loadYet) {
  274. this.getLists(true);
  275. }
  276. },
  277. taskid() {
  278. if (this.loadYet) {
  279. this.getLists(true);
  280. }
  281. },
  282. canload(val) {
  283. if (val && !this.loadYet) {
  284. this.loadYet = true;
  285. this.getLists(true);
  286. }
  287. },
  288. uploadList(files) {
  289. files.forEach((file) => {
  290. if (typeof file.username === "undefined") {
  291. file.username = $A.getUserName();
  292. file.indate = Math.round(new Date().getTime()/1000);
  293. this.lists.unshift(file);
  294. this.$emit('change', 'up');
  295. }
  296. });
  297. }
  298. },
  299. methods: {
  300. sreachTab(clear) {
  301. if (clear === true) {
  302. this.keys = {};
  303. }
  304. this.getLists(true);
  305. },
  306. sortChange(info) {
  307. this.sorts = {key:info.key, order:info.order};
  308. this.getLists(true);
  309. },
  310. setPage(page) {
  311. this.listPage = page;
  312. this.getLists();
  313. },
  314. setPageSize(size) {
  315. if (Math.max($A.runNum(this.listPageSize), 10) != size) {
  316. this.listPageSize = size;
  317. this.getLists();
  318. }
  319. },
  320. getLists(resetLoad) {
  321. if (resetLoad === true) {
  322. this.listPage = 1;
  323. }
  324. if (this.projectid == 0 && this.taskid == 0) {
  325. this.lists = [];
  326. this.listTotal = 0;
  327. this.noDataText = this.$L("没有相关的文件");
  328. return;
  329. }
  330. this.loadIng++;
  331. let whereData = $A.cloneData(this.keys);
  332. whereData.page = Math.max(this.listPage, 1);
  333. whereData.pagesize = Math.max($A.runNum(this.listPageSize), 10);
  334. whereData.projectid = this.projectid;
  335. whereData.taskid = this.taskid;
  336. whereData.sorts = this.sorts;
  337. this.noDataText = this.$L("数据加载中.....");
  338. $A.apiAjax({
  339. url: 'project/files/lists',
  340. data: whereData,
  341. complete: () => {
  342. this.loadIng--;
  343. },
  344. error: () => {
  345. this.noDataText = this.$L("数据加载失败!");
  346. },
  347. success: (res) => {
  348. if (res.ret === 1) {
  349. this.lists = res.data.lists;
  350. this.listTotal = res.data.total;
  351. this.lastPage = res.data.lastPage;
  352. this.noDataText = this.$L("没有相关的文件");
  353. } else {
  354. this.lists = [];
  355. this.listTotal = 0;
  356. this.lastPage = 0;
  357. this.noDataText = res.msg;
  358. }
  359. }
  360. });
  361. },
  362. renameFile(item) {
  363. this.renameValue = "";
  364. this.$Modal.confirm({
  365. render: (h) => {
  366. return h('div', [
  367. h('div', {
  368. style: {
  369. fontSize: '16px',
  370. fontWeight: '500',
  371. marginBottom: '20px',
  372. }
  373. }, this.$L('重命名文件名')),
  374. h('Input', {
  375. props: {
  376. value: this.renameValue,
  377. autofocus: true,
  378. placeholder: item.name || this.$L('请输入新的文件名称')
  379. },
  380. on: {
  381. input: (val) => {
  382. this.renameValue = val;
  383. }
  384. }
  385. })
  386. ])
  387. },
  388. loading: true,
  389. onOk: () => {
  390. if (this.renameValue) {
  391. let oldName = item.name;
  392. let newName = this.renameValue;
  393. if (!$A.rightExists(newName, '.' + item.ext)) {
  394. newName += '.' + item.ext;
  395. }
  396. this.$set(item, 'name', newName);
  397. $A.apiAjax({
  398. url: 'project/files/rename',
  399. data: {
  400. fileid: item.id,
  401. name: newName,
  402. },
  403. error: () => {
  404. this.$Modal.remove();
  405. this.$set(item, 'name', oldName);
  406. alert(this.$L('网络繁忙,请稍后再试!'));
  407. },
  408. success: (res) => {
  409. this.$Modal.remove();
  410. if (res.ret === 1) {
  411. this.$set(item, 'name', res.data.name);
  412. } else {
  413. this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
  414. this.$set(item, 'name', oldName);
  415. }
  416. }
  417. });
  418. } else {
  419. this.$Modal.remove();
  420. }
  421. },
  422. });
  423. },
  424. deleteFile(item) {
  425. this.$Modal.confirm({
  426. title: this.$L('删除文件'),
  427. content: this.$L('你确定要删除此文件吗?'),
  428. loading: true,
  429. onOk: () => {
  430. $A.apiAjax({
  431. url: 'project/files/delete',
  432. data: {
  433. fileid: item.id,
  434. },
  435. error: () => {
  436. this.$Modal.remove();
  437. alert(this.$L('网络繁忙,请稍后再试!'));
  438. },
  439. success: (res) => {
  440. this.$Modal.remove();
  441. this.lists.some((temp, index) => {
  442. if (temp.id == item.id) {
  443. this.lists.splice(index, 1);
  444. return true;
  445. }
  446. });
  447. setTimeout(() => {
  448. if (res.ret === 1) {
  449. this.$Message.success(res.msg);
  450. this.$emit('change', 'delete');
  451. } else {
  452. this.$Modal.error({title: this.$L('温馨提示'), content: res.msg });
  453. }
  454. }, 350);
  455. }
  456. });
  457. }
  458. });
  459. },
  460. uploadHandleClick() {
  461. this.$refs.upload.handleClick();
  462. },
  463. handleSuccess (res, file) {
  464. //上传完成
  465. if (res.ret === 1) {
  466. for (let key in res.data) {
  467. if (res.data.hasOwnProperty(key)) {
  468. file[key] = res.data[key];
  469. }
  470. }
  471. this.$emit('change', 'add');
  472. } else {
  473. this.$Modal.warning({
  474. title: this.$L('上传失败'),
  475. content: this.$L('文件 % 上传失败,%', file.name, res.msg)
  476. });
  477. this.$refs.upload.fileList.pop();
  478. this.lists.some((item, index) => {
  479. if (item.id == res.id) {
  480. this.lists.splice(index, 1);
  481. return true;
  482. }
  483. });
  484. this.$emit('change', 'error');
  485. }
  486. this.uploadList = this.$refs.upload.fileList;
  487. },
  488. handleFormatError (file) {
  489. //上传类型错误
  490. this.$Modal.warning({
  491. title: this.$L('文件格式不正确'),
  492. content: this.$L('文件 % 格式不正确,仅支持上传:%', file.name, this.uploadFormat.join(','))
  493. });
  494. },
  495. handleMaxSize (file) {
  496. //上传大小错误
  497. this.$Modal.warning({
  498. title: this.$L('超出文件大小限制'),
  499. content: this.$L('文件 % 太大,不能超过2M。', file.name)
  500. });
  501. },
  502. handleBeforeUpload () {
  503. //上传前判断
  504. this.params = {
  505. token: $A.getToken(),
  506. taskid: this.taskid,
  507. projectid: this.projectid
  508. };
  509. return true;
  510. },
  511. }
  512. }
  513. </script>