ResourceManage.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. <!--
  2. * @Author: 半生瓜 1515706227@qq.com
  3. * @Date: 2024-05-06 19:31:40
  4. * @LastEditors: 半生瓜 1515706227@qq.com
  5. * @LastEditTime: 2024-05-28 00:03:36
  6. * @FilePath: \vue-element-plus-admin-mini\src\views\zy\Menu12.vue
  7. * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  8. -->
  9. <script setup lang="tsx">
  10. import { ElInput } from 'element-plus'
  11. import { ref } from 'vue'
  12. import { Dialog } from '@/components/Dialog'
  13. import { ContentWrap } from '@/components/ContentWrap'
  14. import { useI18n } from '@/hooks/web/useI18n'
  15. import { Table, TableColumn, TableSlotDefault } from '@/components/Table'
  16. import { upTemplate, saveTemplate } from '@/api/table'
  17. import { saveResource, getResource, deleteResource } from '@/api/resource'
  18. import { reactive, unref } from 'vue'
  19. import { ElButton, ElMessageBox, ElMessage, ElIcon } from 'element-plus'
  20. import { useTable } from '@/hooks/web/useTable'
  21. import { Search, Edit, Delete } from '@element-plus/icons-vue'
  22. import { useValidator } from '@/hooks/web/useValidator'
  23. import { Form, FormSchema } from '@/components/Form'
  24. import { useForm } from '@/hooks/web/useForm'
  25. import { BaseButton } from '@/components/Button'
  26. import { useUserStore } from '@/store/modules/user'
  27. import { log } from 'console'
  28. const PATH_URL = window.VITE_API_BASE_PATH
  29. const { required } = useValidator()
  30. const text = ref('')
  31. const userStore = useUserStore()
  32. defineOptions({
  33. name: 'TemplateManage'
  34. })
  35. const compare = ref('')
  36. const { tableRegister, tableState, tableMethods } = useTable({
  37. fetchDataApi: async () => {
  38. const { currentPage, pageSize } = tableState
  39. const res = await getResource({
  40. page: unref(currentPage),
  41. pageSize: unref(pageSize),
  42. name: unref(text)
  43. })
  44. res.data.content.map((item) => {
  45. console.log('opopopop', item)
  46. item.icon = PATH_URL + item.icon
  47. })
  48. return {
  49. list: res.data.content,
  50. total: res.data.totalElements
  51. }
  52. }
  53. })
  54. const { loading, dataList, total, currentPage, pageSize } = tableState
  55. const { refresh, getElTableExpose } = tableMethods
  56. const { t } = useI18n()
  57. const columns = reactive<TableColumn[]>([
  58. {
  59. field: 'selection',
  60. type: 'selection'
  61. },
  62. {
  63. field: 'index',
  64. label: t('tableDemo.index'),
  65. type: 'index'
  66. },
  67. {
  68. field: 'categoryName',
  69. label: '资源库分类'
  70. },
  71. {
  72. field: 'icon',
  73. label: '图标'
  74. },
  75. {
  76. field: 'modelCount',
  77. label: '对象数量'
  78. },
  79. {
  80. field: 'action',
  81. label: t('tableDemo.action'),
  82. slots: {
  83. default: (data) => {
  84. return (
  85. <>
  86. <ElButton type="primary" onClick={() => edittab(data)}>
  87. {t('tableDemo.edit')}
  88. </ElButton>
  89. <ElButton type="danger" onClick={() => deletetab(data)}>
  90. {t('tableDemo.delete')}
  91. </ElButton>
  92. </>
  93. )
  94. }
  95. }
  96. }
  97. ])
  98. const imageUrl = ref('')
  99. const isedit = ref('添加')
  100. //删除
  101. const deletetab = async (data: TableSlotDefault) => {
  102. ElMessageBox.confirm('确定删除该数据?')
  103. .then(async () => {
  104. let arr = {
  105. categoryId: [data.row.categoryId]
  106. }
  107. const res = await deleteResource(arr)
  108. refresh()
  109. refresh()
  110. if (res.code == 200) {
  111. ElMessage.success('删除成功')
  112. }
  113. refresh()
  114. })
  115. .catch(() => {
  116. // catch error
  117. })
  118. }
  119. const dialogVisible = ref(false)
  120. const token = userStore.getToken
  121. const Authorization = `Bearer ${token}`
  122. const headers = ref({ Authorization: Authorization })
  123. const { formRegister, formMethods } = useForm()
  124. const { getElFormExpose, getFormData } = formMethods
  125. const schema = reactive<FormSchema[]>([
  126. {
  127. field: 'categoryName',
  128. label: '资源分类',
  129. component: 'Input',
  130. colProps: {
  131. span: 24
  132. },
  133. componentProps: {
  134. style: {
  135. width: '100%'
  136. },
  137. placeholder: '请输入资源名称'
  138. },
  139. formItemProps: {
  140. rules: [required()]
  141. }
  142. },
  143. {
  144. field: 'icon',
  145. component: 'Upload',
  146. colProps: {
  147. span: 24
  148. },
  149. label: '图标',
  150. formItemProps: {
  151. rules: [required()]
  152. },
  153. componentProps: {
  154. action: PATH_URL + '/resource/manage/uploadImg',
  155. headers: headers,
  156. showFileList: false,
  157. onSuccess: async (_response, uploadFile) => {
  158. imageUrl.value = URL.createObjectURL(uploadFile.raw!)
  159. const formData = await getFormData()
  160. formData.icon = _response.data
  161. },
  162. beforeUpload: (rawFile) => {
  163. console.log('kankangeshi', rawFile)
  164. if (rawFile.type !== 'image/png' && rawFile.type !== 'image/jpeg') {
  165. ElMessage.error('上传格式:png、jpg!')
  166. return false
  167. }
  168. return true
  169. },
  170. slots: {
  171. default: () => (
  172. <>
  173. {imageUrl.value ? <img src={imageUrl.value} class="avatar" /> : null}
  174. {!imageUrl.value ? (
  175. <ElIcon class="avatar-uploader-icon" size="large" style="font-size: 50px">
  176. +
  177. </ElIcon>
  178. ) : null}
  179. </>
  180. ),
  181. tip: () => <div class="el-upload__tip">上传格式:png、jpg,大小:56x56px;</div>
  182. }
  183. }
  184. },
  185. {
  186. field: 'compressFilePath',
  187. component: 'Upload',
  188. label: '资源内容',
  189. colProps: {
  190. span: 24
  191. },
  192. componentProps: {
  193. limit: 1,
  194. action: PATH_URL + '/resource/manage/addModelCompress',
  195. headers: headers,
  196. fileList: [],
  197. multiple: true,
  198. onPreview: (uploadFile) => {
  199. console.log(uploadFile)
  200. },
  201. onRemove: async (file) => {
  202. const formData = await getFormData()
  203. formData.compressFilePath = ''
  204. formData.compressFileName = ''
  205. formData.uploadCompress = false
  206. },
  207. onSuccess: async (_response, uploadFile) => {
  208. console.log('kankan_response', uploadFile)
  209. const formData = await getFormData()
  210. formData.compressFilePath = _response.data
  211. formData.compressFileName = uploadFile.name
  212. },
  213. beforeRemove: (uploadFile) => {},
  214. onExceed: (files, uploadFiles) => {
  215. ElMessage.warning('只能上传一个资源,请移除后重新上传')
  216. },
  217. beforeUpload: (rawFile) => {
  218. console.log('kokokoko', rawFile)
  219. if (rawFile.name.indexOf('.zip') == -1 && rawFile.name.indexOf('.rar') == -1) {
  220. ElMessage.error('只能上传RAR、ZIP文件')
  221. return false
  222. }
  223. return true
  224. },
  225. slots: {
  226. default: () => <BaseButton type="primary">点击上传</BaseButton>,
  227. tip: () => <div class="el-upload__tip">文件类型:RAR\ZIP</div>
  228. }
  229. }
  230. }
  231. ])
  232. //编辑
  233. const edittab = async (data: TableSlotDefault) => {
  234. console.log('shanchu', data)
  235. isedit.value = '编辑'
  236. dialogVisible.value = true
  237. const formRef = await getElFormExpose()
  238. const formData = await getFormData()
  239. formData.categoryName = data.row.categoryName
  240. formData.compressFileName = data.row.compressFileName
  241. formData.compressFilePath = data.row.compressFilePath
  242. compare.value = data.row.compressFilePath
  243. formData.icon = data.row.icon.replace(PATH_URL, '')
  244. imageUrl.value = data.row.icon
  245. formData.categoryId = data.row.categoryId
  246. schema[2].componentProps.fileList = [
  247. {
  248. name: data.row.compressFileName,
  249. url: data.row.compressFilePath
  250. }
  251. ]
  252. }
  253. // 添加编辑模板管理
  254. const signIn = async () => {
  255. const formRef = await getElFormExpose()
  256. const formData = await getFormData()
  257. console.log('lplplp', formData.compressFilePath)
  258. if (
  259. formData.compressFilePath !== compare.value &&
  260. formData.compressFilePath !== '' &&
  261. formData.compressFilePath
  262. ) {
  263. formData.uploadCompress = true
  264. } else {
  265. formData.uploadCompress = false
  266. }
  267. //如果是编辑去掉icon的拼接
  268. console.log('kakkkkak', formData)
  269. await formRef?.validate(async (isValid) => {
  270. if (isValid) {
  271. const res = await saveResource(formData)
  272. if (res) {
  273. dialogVisible.value = false
  274. refresh()
  275. }
  276. }
  277. })
  278. }
  279. //搜索
  280. const handersearch = function () {
  281. tableState.currentPage.value = 1
  282. refresh()
  283. }
  284. //多选删除
  285. const getSelections = async () => {
  286. const elTableRef = await getElTableExpose()
  287. const selections = elTableRef?.getSelectionRows()
  288. let arr = {
  289. categoryId: []
  290. }
  291. if (selections) {
  292. arr.categoryId = selections.map((item) => {
  293. return item.categoryId
  294. })
  295. }
  296. if (arr.categoryId.length !== 0) {
  297. ElMessageBox.confirm('确定删除所选数据?')
  298. .then(async () => {
  299. console.log('kankan', arr)
  300. const res = await deleteResource(arr)
  301. console.log('kkkkkkss', res)
  302. if (res.code == 200) {
  303. ElMessage.success('删除成功')
  304. }
  305. refresh()
  306. })
  307. .catch(() => {
  308. // catch error
  309. })
  310. } else {
  311. ElMessage.warning('请选择数据')
  312. }
  313. }
  314. const tianjia = async () => {
  315. imageUrl.value = ''
  316. isedit.value = '添加'
  317. schema[2].componentProps.fileList = []
  318. dialogVisible.value = true
  319. compare.value = ''
  320. }
  321. </script>
  322. <template>
  323. <ContentWrap>
  324. <div style="margin-bottom: 10px">
  325. <span style="color: #606266"> 资源分类:</span>
  326. <el-input
  327. v-model="text"
  328. style="width: 200px; height: 43px; margin: 7px"
  329. placeholder="请输入资源分类名称"
  330. />
  331. <ElButton type="primary" size="large" @click="handersearch" :icon="Search">搜索</ElButton>
  332. <ElButton type="success" size="large" @click="tianjia" :icon="Edit">添加</ElButton>
  333. <ElButton type="danger" size="large" @click="getSelections" :icon="Delete">删除</ElButton>
  334. </div>
  335. <Table
  336. v-model:pageSize="pageSize"
  337. v-model:currentPage="currentPage"
  338. :columns="columns"
  339. :image-preview="['icon']"
  340. :data="dataList"
  341. row-key="id"
  342. headerAlign="center"
  343. align="center"
  344. :loading="loading"
  345. sortable
  346. :pagination="{
  347. total: total
  348. }"
  349. @register="tableRegister"
  350. @refresh="refresh"
  351. />
  352. </ContentWrap>
  353. <Dialog v-model="dialogVisible" maxHeight="390px" width="35rem" :title="isedit">
  354. <Form :schema="schema" @register="formRegister" />
  355. <template #footer>
  356. <div style="width: 100%; display: flex; justify-content: center">
  357. <BaseButton
  358. style="font-size: 1rem; height: 2.2rem; margin: auto"
  359. type="primary"
  360. class="w-[15%]"
  361. @click="signIn"
  362. >
  363. 确定
  364. </BaseButton>
  365. </div>
  366. </template>
  367. </Dialog>
  368. </template>
  369. <style>
  370. .el-image__preview {
  371. width: 56px !important;
  372. height: 56px !important;
  373. }
  374. </style>
  375. <style lang="less">
  376. .el-upload {
  377. position: relative;
  378. overflow: hidden;
  379. cursor: pointer;
  380. border: 1px dashed var(--el-border-color);
  381. border-radius: 6px;
  382. transition: var(--el-transition-duration-fast);
  383. }
  384. .el-upload:hover {
  385. border-color: var(--el-color-primary);
  386. }
  387. .el-icon.avatar-uploader-icon {
  388. width: 120px;
  389. height: 120px;
  390. font-size: 28px;
  391. color: #8c939d;
  392. text-align: center;
  393. }
  394. .avatar {
  395. width: 120px;
  396. height: 120px;
  397. }
  398. </style>