北京博音润迪官网

article.vue 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <template>
  2. <el-row>
  3. <div>
  4. <el-button @click="addInfo">添加文章</el-button>
  5. </div>
  6. </el-row>
  7. <el-row>
  8. <el-table :data="filterTableData" style="width: 100%">
  9. <el-table-column label="文章名称" prop="name" />
  10. <el-table-column label="文章内容" prop="content" />
  11. <!-- <el-table-column label="活动" width="120">
  12. <template #default="scope">
  13. <el-image style="width: 100px; height: 50px" :src="baseApiUrl + scope.row.fileInfo[scope.row.file]"
  14. :fit="'scale-down'" />
  15. </template>
  16. </el-table-column> -->
  17. <el-table-column label="创建时间" prop="createTime" style="width: 100px;" />
  18. <el-table-column align="right" style="width: 100px;">
  19. <template #header>
  20. <el-input v-model="search" size="small" placeholder="请输入标题" />
  21. </template>
  22. <template #default="scope">
  23. <el-button size="small" @click="handleEdit(scope.row)">Edit</el-button>
  24. <el-button size="small" type="danger" @click="handleDelete(scope.row.id)">Delete</el-button>
  25. </template>
  26. </el-table-column>
  27. </el-table>
  28. </el-row>
  29. <el-dialog v-model="centerDialogVisible" title="产品信息" width="500" center>
  30. <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto" class="demo-ruleForm"
  31. :size="'default'" status-icon>
  32. <el-form-item label="标题" prop="name">
  33. <el-input v-model="ruleForm.name" />
  34. </el-form-item>
  35. <el-form-item label="内容" prop="content">
  36. <el-input v-model="ruleForm.content" type="textarea" />
  37. </el-form-item>
  38. <el-form-item label="标题图片" prop="file">
  39. <el-upload v-model:file-list="fileList" :action="uploadUrl" list-type="picture-card"
  40. :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handeUploadSuccess" :limit="FILE_LIMIT"
  41. accept="image/*">
  42. <el-icon>
  43. <Plus />
  44. </el-icon>
  45. </el-upload>
  46. <el-dialog v-model="dialogVisible">
  47. <img w-full :src="dialogImageUrl" alt="Preview Image" />
  48. </el-dialog>
  49. </el-form-item>
  50. <el-form-item label="内容图片" prop="contentFile">
  51. <el-upload v-model:file-list="typeFileList" :action="uploadUrl" list-type="picture-card"
  52. :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handeTypeUploadSuccess" :limit="CONTENT_FILE_LIMIT"
  53. accept="image/*">
  54. <el-icon>
  55. <Plus />
  56. </el-icon>
  57. </el-upload>
  58. <el-dialog v-model="dialogVisible">
  59. <img w-full :src="dialogImageUrl" alt="Preview Image" />
  60. </el-dialog>
  61. </el-form-item>
  62. <el-form-item>
  63. </el-form-item>
  64. </el-form>
  65. <template #footer>
  66. <div class="dialog-footer">
  67. <el-button @click="centerDialogVisible = false">取消</el-button>
  68. <el-button type="primary" @click="submitForm(ruleFormRef)">
  69. 提交
  70. </el-button>
  71. </div>
  72. </template>
  73. </el-dialog>
  74. </template>
  75. <script lang="ts" setup>
  76. import { onMounted, ref, computed, reactive, toRaw } from 'vue'
  77. import request from '../../utils/request'
  78. import { Plus } from '@element-plus/icons-vue'
  79. import type { UploadProps, FormInstance } from 'element-plus'
  80. import { ElMessage, ElMessageBox } from 'element-plus'
  81. const baseApiUrl = process.env.VUE_APP_BASE_API_URL;
  82. const uploadUrl = baseApiUrl + '/system/accessories/upload'
  83. const FILE_LIMIT = 6;
  84. const CONTENT_FILE_LIMIT = 1;
  85. let centerDialogVisible = ref(false)
  86. let ruleForm = reactive<any>({
  87. id: 0,
  88. name: '',
  89. content: '',
  90. file: [],
  91. contentFile: [],
  92. })
  93. const fileList = ref([] as Array<any>);
  94. const typeFileList = ref([] as Array<any>);
  95. const ruleFormRef = ref<FormInstance>()
  96. const rules = reactive<any>({
  97. name: [
  98. { required: true, message: '请输入信息', trigger: 'blur' },
  99. { max: 15, message: '长度不能超过15', trigger: 'blur' },
  100. ],
  101. content: [
  102. {
  103. required: true,
  104. message: '请输入内容',
  105. trigger: 'blur',
  106. },
  107. { max: 1000, message: '长度不能超过1000', trigger: 'blur' },
  108. ],
  109. file: [
  110. {
  111. type: 'Array',
  112. required: true,
  113. message: '请上传图片',
  114. },
  115. ],
  116. contentFile: [
  117. {
  118. type: 'Array',
  119. required: true,
  120. message: '请上传图片',
  121. },
  122. ],
  123. })
  124. const handeUploadSuccess = (res: any, uploadFile: any) => {
  125. const { Id } = res.data;
  126. if (Id) {
  127. ruleForm.file.push(Id);
  128. uploadFile.uid = Id;
  129. uploadFile.name = Id;
  130. fileList.value[fileList.value.length -1] = uploadFile;
  131. }
  132. }
  133. const handeTypeUploadSuccess = (res: any, uploadFile: any) => {
  134. const { Id } = res.data;
  135. if (Id) {
  136. ruleForm.contentFile.push(Id);
  137. uploadFile.uid = Id;
  138. uploadFile.name = Id;
  139. typeFileList.value[typeFileList.value.length -1] = uploadFile;
  140. }
  141. }
  142. const submitForm = async (formEl: FormInstance | undefined) => {
  143. if (!formEl) return
  144. const valRes = await formEl.validate((valid) => {
  145. if (valid) {
  146. return true;
  147. } else {
  148. return true;
  149. }
  150. })
  151. if (!valRes) return;
  152. // console.log(toRaw(ruleForm), 'ruleForm')
  153. const params = toRaw(ruleForm);
  154. params.file = params.file.join(',');
  155. params.contentFile = params.contentFile.join(',');
  156. // 提交
  157. let res: any;
  158. if (ruleForm.id) {
  159. res = await request.put('/GwHome/gwhome', params);
  160. } else {
  161. delete params.id;
  162. res = await request.post('/GwHome/gwhome', params);
  163. }
  164. await alterRes(res);
  165. }
  166. const alterRes = async (res: any) => {
  167. if (res.state === 'success') {
  168. ElMessage({
  169. message: '操作成功',
  170. type: 'success',
  171. })
  172. await getList();
  173. centerDialogVisible.value = false;
  174. } else {
  175. ElMessage({
  176. message: res.message,
  177. type: 'error',
  178. })
  179. }
  180. }
  181. const search = ref('')
  182. const filterTableData = computed(() =>
  183. tableData.value.filter(
  184. (data: any) =>
  185. !search.value ||
  186. (data.name && data.name.toLowerCase().includes(search.value.toLowerCase()))
  187. )
  188. )
  189. const handleEdit = (row: any) => {
  190. ruleForm.name = row.name;
  191. ruleForm.content = row.content;
  192. ruleForm.file = row.file.split(',');
  193. ruleForm.contentFile = row.contentFile.split(',');
  194. ruleForm.id = row.id;
  195. fileList.value = [];
  196. typeFileList.value = [];
  197. // console.log(toRaw(ruleForm).nameFile, 'ruleForm.nameFile')
  198. if (ruleForm.file) {
  199. toRaw(ruleForm).file.forEach((o: any) => {
  200. fileList.value.push({
  201. uid: o,
  202. name: o,
  203. url: baseApiUrl + (row.fileInfo as any)[`${o}`],
  204. });
  205. })
  206. }
  207. if (ruleForm.contentFile) {
  208. toRaw(ruleForm).contentFile.forEach((o: any) => {
  209. typeFileList.value.push({
  210. uid: o,
  211. name: o,
  212. url: baseApiUrl + (row.contentFileInfo as any)[`${o}`],
  213. });
  214. })
  215. }
  216. centerDialogVisible.value = true;
  217. }
  218. const handleDelete = (id: number) => {
  219. ElMessageBox.confirm(
  220. '确定删除该活动吗?',
  221. 'Warning',
  222. {
  223. confirmButtonText: '确定',
  224. cancelButtonText: '取消',
  225. type: 'warning',
  226. }
  227. )
  228. .then(async () => {
  229. const res: any = await request.delete('/GwHome/gwhome/' + id);
  230. await alterRes(res);
  231. });
  232. }
  233. let tableData = ref([]);
  234. const getList = async () => {
  235. const res = await request.get('/GwHome/gwhome');
  236. if (res.data.length > 0) tableData.value = res.data;
  237. }
  238. onMounted(async () => {
  239. await getList();
  240. })
  241. const handleRemove: UploadProps['onRemove'] = (uploadFile: any, uploadFiles: any) => {
  242. console.log(uploadFile, uploadFiles)
  243. ruleForm.nameFile = ruleForm.nameFile.filter((o: string) => {
  244. return o !== uploadFile.uid;
  245. });
  246. ruleForm.typeFile = ruleForm.typeFile.filter((o: string) => {
  247. return o !== uploadFile.uid;
  248. });
  249. }
  250. const dialogImageUrl = ref('')
  251. const dialogVisible = ref(false)
  252. const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile: any) => {
  253. dialogImageUrl.value = uploadFile.url
  254. dialogVisible.value = true
  255. }
  256. const addInfo = () => {
  257. centerDialogVisible.value = true
  258. //
  259. ruleForm = reactive<any>({
  260. id: 0,
  261. name: '',
  262. content: '',
  263. file: [],
  264. contentFile: [],
  265. })
  266. fileList.value = [];
  267. typeFileList.value = [];
  268. }
  269. </script>