resource_list.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <template>
  2. <section class="content">
  3. <div class="box box-info">
  4. <div
  5. v-loading.body="fileLoading"
  6. v-loading.fullscreen="fileLoading"
  7. class="box-body"
  8. element-loading-text="请稍后..."
  9. >
  10. <!-- 表单 -->
  11. <el-form inline :model="formSearch">
  12. <el-form-item v-if="isSuperAdmin" label="学校">
  13. <el-select
  14. v-model="formSearch.rootOrgId"
  15. placeholder="请选择"
  16. style="width: 180px"
  17. filterable
  18. >
  19. <el-option
  20. v-for="item in rootSchoolSelect"
  21. :key="item.id"
  22. :label="item.name"
  23. :value="item.id"
  24. />
  25. </el-select>
  26. </el-form-item>
  27. <el-form-item label="名称">
  28. <el-input
  29. v-model="formSearch.name"
  30. placeholder="请输入名称"
  31. style="width: 180px"
  32. />
  33. </el-form-item>
  34. <el-form-item>
  35. <el-button
  36. size="small"
  37. type="primary"
  38. icon="el-icon-search"
  39. @click="handleSearchBtn"
  40. >
  41. 查询
  42. </el-button>
  43. </el-form-item>
  44. </el-form>
  45. <div class="block-seperator"></div>
  46. <span>当前目录:{{ curDir }}</span>
  47. <span style="float: right">
  48. <el-button
  49. size="small"
  50. type="primary"
  51. :disabled="parentDirBtn()"
  52. @click="parentDir"
  53. >
  54. 上一级
  55. </el-button>
  56. <el-button
  57. size="small"
  58. type="primary"
  59. icon="el-icon-plus"
  60. @click="addDir"
  61. >
  62. 新增目录
  63. </el-button>
  64. <el-button
  65. size="small"
  66. type="primary"
  67. icon="el-icon-plus"
  68. @click="addFile"
  69. >
  70. 新增文件
  71. </el-button>
  72. </span>
  73. <div style="width: 100%; margin-bottom: 10px"></div>
  74. <!-- 页面列表 -->
  75. <el-table :data="tableData" border resizable stripe style="width: 100%">
  76. <el-table-column width="50" label="ID">
  77. <span slot-scope="scope">{{ scope.row.id }}</span>
  78. </el-table-column>
  79. <el-table-column width="250" label="名称">
  80. <span slot-scope="scope">
  81. <span
  82. style="width: 30px; height: 20px; display: block; float: left"
  83. >
  84. <img
  85. v-if="scope.row.isFile == 0"
  86. src="../assets/img/dir.png"
  87. style="height: 20px; width: 20px"
  88. />
  89. </span>
  90. <span
  91. ><a
  92. v-if="scope.row.isFile == 0"
  93. href="javascript:void(0)"
  94. @click="toDir(scope.row)"
  95. >{{ scope.row.name }}</a
  96. ><a
  97. v-if="scope.row.isFile == 1"
  98. target="_blank"
  99. :href="scope.row.fileUrl"
  100. >{{ scope.row.name }}</a
  101. ></span
  102. ></span
  103. >
  104. </el-table-column>
  105. <el-table-column label="路径">
  106. <span slot-scope="scope">{{ scope.row.filePath }}</span>
  107. </el-table-column>
  108. <el-table-column width="180" label="创建时间">
  109. <span slot-scope="scope">{{ scope.row.creationTime }}</span>
  110. </el-table-column>
  111. <el-table-column :context="_self" label="操作" width="150">
  112. <div slot-scope="scope">
  113. <el-button
  114. size="mini"
  115. type="danger"
  116. plain
  117. @click="deleteRes(scope.row)"
  118. >
  119. <i class="el-icon-delete"></i> 删除
  120. </el-button>
  121. </div>
  122. </el-table-column>
  123. </el-table>
  124. <div class="page pull-right">
  125. <el-pagination
  126. v-if="paginationShow"
  127. :current-page="currentPage"
  128. :page-size="pageSize"
  129. :page-sizes="[10, 20, 50, 100, 200, 300]"
  130. layout="total, sizes, prev, pager, next, jumper"
  131. :total="total"
  132. @current-change="handleCurrentChange"
  133. @size-change="handleSizeChange"
  134. />
  135. </div>
  136. </div>
  137. <el-dialog
  138. title="新增目录"
  139. width="500px"
  140. :visible.sync="dirModel"
  141. :close-on-click-modal="false"
  142. @close="closeDirModel"
  143. >
  144. <el-form
  145. ref="dirForm"
  146. :key="dirModelKey"
  147. :inline="true"
  148. :model="dirForm"
  149. :rules="dirRules"
  150. label-width="90px"
  151. >
  152. <el-row>
  153. <el-form-item label="目录名称" prop="dirName">
  154. <el-input
  155. v-model="dirForm.dirName"
  156. class="pull-length"
  157. maxlength="50"
  158. placeholder="可输入字母,数字,-,_"
  159. />
  160. </el-form-item>
  161. </el-row>
  162. <el-row class="pull-center">
  163. <el-button type="primary" :loading="dirForm.loading" @click="subDir"
  164. >确定</el-button
  165. >
  166. <el-button @click="closeDirModel">取消</el-button>
  167. </el-row>
  168. </el-form>
  169. </el-dialog>
  170. <el-dialog
  171. title="新增文件"
  172. width="550px"
  173. :visible.sync="fileModel"
  174. :close-on-click-modal="false"
  175. @close="closeFileModel"
  176. >
  177. <el-form
  178. ref="fileForm"
  179. :key="fileModelKey"
  180. :inline="true"
  181. :model="fileForm"
  182. :rules="fileRules"
  183. label-width="90px"
  184. >
  185. <el-row>
  186. <el-form-item label="文件" prop="dataFile">
  187. <el-input
  188. v-model="fileForm.fileName"
  189. class="pull-length"
  190. :readonly="true"
  191. placeholder="文件最大限制10M"
  192. />
  193. </el-form-item>
  194. <el-form-item>
  195. <el-upload :before-upload="handleUploadFile" action="/upload">
  196. <el-button
  197. type="primary"
  198. size="small"
  199. icon="ios-cloud-upload-outline"
  200. >请选择文件
  201. </el-button>
  202. </el-upload>
  203. </el-form-item>
  204. </el-row>
  205. <el-row class="pull-center">
  206. <el-button
  207. type="primary"
  208. :loading="fileForm.loading"
  209. @click="subFile"
  210. >确定</el-button
  211. >
  212. <el-button @click="closeFileModel">取消</el-button>
  213. </el-row>
  214. </el-form>
  215. </el-dialog>
  216. </div>
  217. </section>
  218. </template>
  219. <script>
  220. import { CORE_API } from "@/constants/constants.js";
  221. import { mapState } from "vuex";
  222. export default {
  223. name: "ResourceList",
  224. data() {
  225. var validateFile = function (rule, value, callback) {
  226. if (value) {
  227. var upFileName = value.name;
  228. var reg = /^[a-zA-Z\\-_0-9\\.]{1,50}$/;
  229. if (!upFileName.match(reg)) {
  230. return callback(
  231. new Error("文件名长度最大为50且只能包含字母,数字,'-','_','.'")
  232. );
  233. } else if (value.size > 1024 * 1024 * 10) {
  234. return callback(new Error("文件大小限制为10M"));
  235. } else {
  236. callback();
  237. }
  238. } else {
  239. callback();
  240. }
  241. };
  242. return {
  243. fileLoading: false,
  244. dirModel: false,
  245. dirModelKey: Math.random(),
  246. fileModel: false,
  247. fileModelKey: Math.random(),
  248. curDir: "",
  249. parentIds: [],
  250. paginationShow: false,
  251. rootOrgList: [],
  252. formSearch: {
  253. parentId: -1,
  254. rootOrgId: null,
  255. code: "",
  256. name: "",
  257. },
  258. dirForm: {
  259. dirName: "",
  260. loading: false,
  261. },
  262. fileForm: {
  263. fileName: null,
  264. dataFile: null,
  265. loading: false,
  266. },
  267. loading: true,
  268. tableData: [],
  269. currentPage: 1,
  270. pageSize: 10,
  271. total: 10,
  272. dirRules: {
  273. dirName: [
  274. { required: true, message: "请输入目录名称", trigger: "blur" },
  275. {
  276. pattern: /^[a-zA-Z\\-_0-9]{1,50}$/,
  277. message: "目录名称必须为1-50位字母,数字,'-','_'组合",
  278. trigger: "blur",
  279. },
  280. ],
  281. },
  282. fileRules: {
  283. dataFile: [
  284. {
  285. required: true,
  286. type: "object",
  287. message: "请选择文件",
  288. trigger: "change",
  289. },
  290. {
  291. validator: validateFile,
  292. type: "object",
  293. trigger: "change",
  294. },
  295. ],
  296. },
  297. };
  298. },
  299. computed: {
  300. ...mapState({ user: (state) => state.user }),
  301. isSuperAdmin() {
  302. return this.user.roleList.some((role) => role.roleCode == "SUPER_ADMIN");
  303. },
  304. rootSchoolSelect() {
  305. let rootSchools = [];
  306. for (let i = 0; i < this.rootOrgList.length; i++) {
  307. let info = {
  308. name: this.rootOrgList[i].name + "(" + this.rootOrgList[i].id + ")",
  309. id: this.rootOrgList[i].id,
  310. };
  311. rootSchools.push(info);
  312. }
  313. return rootSchools;
  314. },
  315. },
  316. watch: {
  317. "formSearch.rootOrgId": {
  318. immediate: false,
  319. handler(val) {
  320. if (val == null) {
  321. this.curDir = "";
  322. } else {
  323. this.curDir = "/";
  324. this.formSearch.parentId = -1;
  325. this.handleSearchBtn();
  326. }
  327. },
  328. },
  329. },
  330. //初始化查询
  331. created() {
  332. this.init();
  333. },
  334. methods: {
  335. handleUploadFile(file) {
  336. this.fileForm.dataFile = file;
  337. this.fileForm.fileName = file.name;
  338. return false;
  339. },
  340. async subFile() {
  341. const res = await this.$refs.fileForm.validate();
  342. if (res === false) {
  343. return;
  344. }
  345. this.fileForm.loading = true;
  346. var params =
  347. "?parentId=" +
  348. this.formSearch.parentId +
  349. "&rootOrgId=" +
  350. this.formSearch.rootOrgId;
  351. var url = CORE_API + "/resource/addFile" + params;
  352. let formData = new FormData();
  353. formData.append("dataFile", this.fileForm.dataFile);
  354. this.$httpWithMsg
  355. .post(url, formData)
  356. .then(() => {
  357. this.$notify({
  358. type: "success",
  359. message: "上传成功!",
  360. });
  361. this.closeFileModel();
  362. this.searchForm();
  363. })
  364. .finally(() => (this.fileForm.loading = false));
  365. },
  366. closeFileModel() {
  367. this.fileModel = false;
  368. this.$refs.fileForm.resetFields();
  369. this.fileModelKey = Math.random();
  370. this.fileForm.fileName = null;
  371. this.fileForm.dataFile = null;
  372. },
  373. closeDirModel() {
  374. this.dirModel = false;
  375. this.dirForm.dirName = null;
  376. this.dirModelKey = Math.random();
  377. },
  378. async subDir() {
  379. let res = await this.$refs.dirForm.validate();
  380. if (!res) {
  381. return;
  382. }
  383. this.dirForm.loading = true;
  384. var url = CORE_API + "/resource/addDir";
  385. this.$httpWithMsg
  386. .post(url, {
  387. parentId: this.formSearch.parentId,
  388. rootOrgId: this.formSearch.rootOrgId,
  389. name: this.dirForm.dirName,
  390. })
  391. .then(() => {
  392. this.$notify({
  393. type: "success",
  394. message: "新增成功!",
  395. });
  396. this.closeDirModel();
  397. this.searchForm();
  398. })
  399. .finally(() => (this.dirForm.loading = false));
  400. },
  401. lastCurDir() {
  402. this.curDir = this.curDir.substring(0, this.curDir.length - 1);
  403. var index = this.curDir.lastIndexOf("/");
  404. this.curDir = this.curDir.substring(0, index + 1);
  405. },
  406. toDir(row) {
  407. this.curDir = this.curDir + row.name + "/";
  408. this.parentIds.push(this.formSearch.parentId);
  409. this.formSearch.parentId = row.id;
  410. this.currentPage = 1;
  411. this.searchForm();
  412. },
  413. parentDirBtn() {
  414. if (this.curDir == "/" || this.curDir == "") {
  415. return true;
  416. } else {
  417. return false;
  418. }
  419. },
  420. deleteRes(row) {
  421. this.$confirm("确定删除?", "提示", {
  422. confirmButtonText: "确定",
  423. cancelButtonText: "取消",
  424. type: "warning",
  425. }).then(() => {
  426. var url = CORE_API + "/resource/" + row.id;
  427. this.$httpWithMsg.delete(url).then(() => {
  428. this.$notify({
  429. type: "success",
  430. message: "删除成功!",
  431. });
  432. this.searchForm();
  433. });
  434. });
  435. },
  436. parentDir() {
  437. this.formSearch.parentId = this.parentIds.pop();
  438. this.lastCurDir();
  439. this.currentPage = 1;
  440. this.searchForm();
  441. },
  442. addFile() {
  443. if (this.formSearch.rootOrgId == null) {
  444. this.$notify({
  445. type: "warning",
  446. message: "请选择学校",
  447. });
  448. return;
  449. }
  450. this.fileModel = true;
  451. },
  452. addDir() {
  453. if (this.formSearch.rootOrgId == null) {
  454. this.$notify({
  455. type: "warning",
  456. message: "请选择学校",
  457. });
  458. return;
  459. }
  460. this.dirModel = true;
  461. },
  462. handleSearchBtn() {
  463. this.currentPage = 1;
  464. this.searchForm();
  465. },
  466. handleSizeChange(val) {
  467. this.pageSize = val;
  468. this.currentPage = 1;
  469. this.searchForm();
  470. },
  471. handleCurrentChange(val) {
  472. this.currentPage = val;
  473. this.searchForm();
  474. },
  475. //查询
  476. searchForm() {
  477. if (this.formSearch.rootOrgId == null) {
  478. this.$notify({
  479. type: "warning",
  480. message: "请选择学校",
  481. });
  482. return;
  483. }
  484. this.loading = true;
  485. this.fileLoading = true;
  486. var param = new URLSearchParams(this.formSearch);
  487. var url =
  488. CORE_API +
  489. "/resource/page/" +
  490. (this.currentPage - 1) +
  491. "/" +
  492. this.pageSize +
  493. "?" +
  494. param;
  495. this.$httpWithMsg
  496. .get(url)
  497. .then((response) => {
  498. this.tableData = response.data.list;
  499. this.total = response.data.total;
  500. this.loading = false;
  501. this.$nextTick(function () {
  502. this.paginationShow = true;
  503. });
  504. })
  505. .finally(() => (this.fileLoading = false));
  506. },
  507. init() {
  508. if (this.isSuperAdmin) {
  509. this.$httpWithMsg
  510. .get(CORE_API + "/org/getRootOrgList")
  511. .then((response) => {
  512. this.rootOrgList = response.data;
  513. });
  514. } else {
  515. this.formSearch.rootOrgId = this.user.rootOrgId;
  516. this.searchForm();
  517. }
  518. },
  519. },
  520. };
  521. </script>
  522. <style scoped>
  523. .page {
  524. margin-top: 10px;
  525. }
  526. .el-upload {
  527. width: 80px;
  528. }
  529. .pull-length {
  530. width: 300px;
  531. }
  532. .pull-center {
  533. margin-top: 20px;
  534. }
  535. </style>