北京博音润迪官网

product.vue 10KB

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