MaterialMange.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  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, getMaterial, deleteResource } from '@/api/material'
  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 { tableRegister, tableState, tableMethods } = useTable({
  36. fetchDataApi: async () => {
  37. const { currentPage, pageSize } = tableState
  38. const res = await getMaterial({
  39. page: unref(currentPage),
  40. pageSize: unref(pageSize),
  41. name: unref(text)
  42. })
  43. res.data.content.map((item) => {
  44. item.materialIcon = PATH_URL + item.materialIcon
  45. item.icon = item.materialIcon
  46. })
  47. console.log('kankan2232', res.data.content)
  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: 'materialName',
  69. label: '材质名称'
  70. },
  71. {
  72. field: 'icon',
  73. label: '图标'
  74. },
  75. {
  76. field: 'action',
  77. label: t('tableDemo.action'),
  78. slots: {
  79. default: (data) => {
  80. return (
  81. <>
  82. <ElButton type="primary" onClick={() => edittab(data)}>
  83. {t('tableDemo.edit')}
  84. </ElButton>
  85. <ElButton type="danger" onClick={() => deletetab(data)}>
  86. {t('tableDemo.delete')}
  87. </ElButton>
  88. </>
  89. )
  90. }
  91. }
  92. }
  93. ])
  94. const imageUrl = ref('')
  95. const isedit = ref('添加')
  96. //删除
  97. const deletetab = async (data: TableSlotDefault) => {
  98. ElMessageBox.confirm('确定删除该数据?')
  99. .then(async () => {
  100. let arr = {
  101. materialIds: data.row.materialId
  102. }
  103. const res = await deleteResource(arr)
  104. refresh()
  105. refresh()
  106. if (res.code == 200) {
  107. ElMessage.success('删除成功')
  108. }
  109. refresh()
  110. })
  111. .catch(() => {
  112. // catch error
  113. })
  114. }
  115. const dialogVisible = ref(false)
  116. const token = userStore.getToken
  117. const Authorization = `Bearer ${token}`
  118. const headers = ref({ Authorization: Authorization })
  119. const { formRegister, formMethods } = useForm()
  120. const { getElFormExpose, getFormData } = formMethods
  121. const schema = reactive<FormSchema[]>([
  122. {
  123. field: 'materialName',
  124. label: '材质名称',
  125. component: 'Input',
  126. colProps: {
  127. span: 24
  128. },
  129. componentProps: {
  130. style: {
  131. width: '100%'
  132. },
  133. placeholder: '请输入材质名称'
  134. },
  135. formItemProps: {
  136. rules: [required()]
  137. }
  138. },
  139. {
  140. field: 'materialIcon',
  141. component: 'Upload',
  142. colProps: {
  143. span: 24
  144. },
  145. label: '图标',
  146. formItemProps: {
  147. rules: [required()]
  148. },
  149. componentProps: {
  150. action: PATH_URL + '/resource/manage/uploadImg',
  151. headers: headers,
  152. showFileList: false,
  153. onSuccess: async (_response, uploadFile) => {
  154. imageUrl.value = URL.createObjectURL(uploadFile.raw!)
  155. const formData = await getFormData()
  156. formData.materialIcon = _response.data
  157. },
  158. beforeUpload: (rawFile) => {
  159. console.log('kankangeshi', rawFile)
  160. if (rawFile.type !== 'image/png' && rawFile.type !== 'image/jpeg') {
  161. ElMessage.error('上传格式:png、jpg!')
  162. return false
  163. }
  164. return true
  165. },
  166. slots: {
  167. default: () => (
  168. <>
  169. {imageUrl.value ? <img src={imageUrl.value} class="avatar" /> : null}
  170. {!imageUrl.value ? (
  171. <ElIcon class="avatar-uploader-icon" size="large" style="font-size: 50px">
  172. +
  173. </ElIcon>
  174. ) : null}
  175. </>
  176. ),
  177. tip: () => <div class="el-upload__tip">上传格式:png、jpg,大小:56x56px;</div>
  178. }
  179. }
  180. },
  181. {
  182. field: 'jsonPath',
  183. component: 'Upload',
  184. label: '材质内容',
  185. colProps: {
  186. span: 24
  187. },
  188. componentProps: {
  189. limit: 1,
  190. action: PATH_URL + '/resource/v1/addJsonFile',
  191. headers: headers,
  192. fileList: [],
  193. multiple: true,
  194. onPreview: (uploadFile) => {
  195. console.log(uploadFile)
  196. },
  197. onRemove: async (file) => {
  198. const formData = await getFormData()
  199. formData.jsonPath = ''
  200. formData.compressFileName = ''
  201. formData.uploadCompress = false
  202. },
  203. onSuccess: async (_response, uploadFile) => {
  204. console.log('kankan_response', uploadFile)
  205. const formData = await getFormData()
  206. formData.jsonPath = _response.data
  207. formData.compressFileName = uploadFile.name
  208. },
  209. beforeRemove: (uploadFile) => {},
  210. onExceed: (files, uploadFiles) => {
  211. ElMessage.warning('只能上传一个资源,请移除后重新上传')
  212. },
  213. beforeUpload: (rawFile) => {
  214. console.log('kokokoko', rawFile)
  215. // if (rawFile.type !== 'application/x-zip-compressed' && rawFile.name.indexOf('.rar') == -1) {
  216. // ElMessage.error('只能上传RAR、ZIP文件')
  217. // return false
  218. // }
  219. // return true
  220. },
  221. slots: {
  222. default: () => <BaseButton type="primary">点击上传</BaseButton>,
  223. tip: () => <div class="el-upload__tip">文件类型:RAR\ZIP</div>
  224. }
  225. }
  226. }
  227. ])
  228. //编辑
  229. const edittab = async (data: TableSlotDefault) => {
  230. console.log('shanchu', data)
  231. isedit.value = '编辑'
  232. dialogVisible.value = true
  233. const formRef = await getElFormExpose()
  234. const formData = await getFormData()
  235. formData.materialName = data.row.materialName
  236. formData.compressFileName = data.row.compressFileName
  237. formData.jsonPath = data.row.jsonPath
  238. formData.materialIcon = data.row.materialIcon.replace(PATH_URL, '')
  239. imageUrl.value = data.row.materialIcon
  240. formData.materialId = data.row.materialId
  241. schema[2].componentProps.fileList = [
  242. {
  243. name: data.row.compressFileName,
  244. url: data.row.jsonPath
  245. }
  246. ]
  247. }
  248. // 添加编辑模板管理
  249. const signIn = async () => {
  250. const formRef = await getElFormExpose()
  251. const formData = await getFormData()
  252. //如果是编辑去掉icon的拼接
  253. console.log('kakkkkak', formData)
  254. await formRef?.validate(async (isValid) => {
  255. if (isValid) {
  256. const res = await saveResource(formData)
  257. if (res) {
  258. dialogVisible.value = false
  259. refresh()
  260. }
  261. }
  262. })
  263. }
  264. //多选删除
  265. const getSelections = async () => {
  266. const elTableRef = await getElTableExpose()
  267. const selections = elTableRef?.getSelectionRows()
  268. let arr = {
  269. materialIds: []
  270. }
  271. if (selections) {
  272. arr.materialIds = selections.map((item) => {
  273. return item.materialId
  274. })
  275. }
  276. if (arr.materialIds.length !== 0) {
  277. ElMessageBox.confirm('确定删除所选数据?')
  278. .then(async () => {
  279. console.log('kankan', arr)
  280. const res = await deleteResource(arr)
  281. console.log('kkkkkkss', res)
  282. if (res.code == 200) {
  283. ElMessage.success('删除成功')
  284. }
  285. refresh()
  286. })
  287. .catch(() => {
  288. // catch error
  289. })
  290. } else {
  291. ElMessage.warning('请选择数据')
  292. }
  293. }
  294. const tianjia = async () => {
  295. imageUrl.value = ''
  296. isedit.value = '添加'
  297. schema[2].componentProps.fileList = []
  298. dialogVisible.value = true
  299. }
  300. </script>
  301. <template>
  302. <ContentWrap>
  303. <div style="margin-bottom: 10px">
  304. <ElButton type="success" size="large" @click="tianjia" :icon="Edit">添加</ElButton>
  305. <ElButton type="danger" size="large" @click="getSelections" :icon="Delete">删除</ElButton>
  306. </div>
  307. <Table
  308. v-model:pageSize="pageSize"
  309. v-model:currentPage="currentPage"
  310. :columns="columns"
  311. :image-preview="['icon']"
  312. :data="dataList"
  313. row-key="id"
  314. headerAlign="center"
  315. align="center"
  316. :loading="loading"
  317. sortable
  318. :pagination="{
  319. total: total
  320. }"
  321. @register="tableRegister"
  322. @refresh="refresh"
  323. />
  324. </ContentWrap>
  325. <Dialog v-model="dialogVisible" maxHeight="390px" width="35rem" :title="isedit">
  326. <Form :schema="schema" @register="formRegister" />
  327. <template #footer>
  328. <div style="width: 100%; display: flex; justify-content: center">
  329. <BaseButton
  330. style="font-size: 1rem; height: 2.2rem; margin: auto"
  331. type="primary"
  332. class="w-[15%]"
  333. @click="signIn"
  334. >
  335. 确定
  336. </BaseButton>
  337. </div>
  338. </template>
  339. </Dialog>
  340. </template>
  341. <style>
  342. .el-image__preview {
  343. width: 56px !important;
  344. height: 56px !important;
  345. }
  346. </style>
  347. <style lang="less">
  348. .el-upload {
  349. position: relative;
  350. overflow: hidden;
  351. cursor: pointer;
  352. border: 1px dashed var(--el-border-color);
  353. border-radius: 6px;
  354. transition: var(--el-transition-duration-fast);
  355. }
  356. .el-upload:hover {
  357. border-color: var(--el-color-primary);
  358. }
  359. .el-icon.avatar-uploader-icon {
  360. width: 120px;
  361. height: 120px;
  362. font-size: 28px;
  363. color: #8c939d;
  364. text-align: center;
  365. }
  366. .avatar {
  367. width: 120px;
  368. height: 120px;
  369. }
  370. </style>