index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="100px">
  4. <el-form-item label="轮播图名称" prop="bannerName">
  5. <el-input
  6. v-model="queryParams.bannerName"
  7. placeholder="请输入轮播图名称"
  8. clearable
  9. @keyup.enter="handleQuery"
  10. />
  11. </el-form-item>
  12. <!-- <el-form-item label="跳转链接" prop="linkUrl">
  13. <el-input
  14. v-model="queryParams.linkUrl"
  15. placeholder="请输入跳转链接"
  16. clearable
  17. @keyup.enter="handleQuery"
  18. />
  19. </el-form-item>-->
  20. <el-form-item label="状态" prop="isActive">
  21. <el-select v-model="queryParams.isActive" placeholder="请选择状态" clearable>
  22. <el-option
  23. v-for="dict in banner_status"
  24. :key="dict.value"
  25. :label="dict.label"
  26. :value="dict.value"
  27. />
  28. </el-select>
  29. </el-form-item>
  30. <el-form-item label="系统类型" prop="sysType">
  31. <el-select v-model="queryParams.sysType" placeholder="请选择系统类型" clearable>
  32. <el-option
  33. v-for="dict in banner_sys_type"
  34. :key="dict.value"
  35. :label="dict.label"
  36. :value="dict.value"
  37. />
  38. </el-select>
  39. </el-form-item>
  40. <!-- <el-form-item label="部门id" prop="deptId">
  41. <el-input
  42. v-model="queryParams.deptId"
  43. placeholder="请输入部门id"
  44. clearable
  45. @keyup.enter="handleQuery"
  46. />
  47. </el-form-item>
  48. <el-form-item label="用户id" prop="userId">
  49. <el-input
  50. v-model="queryParams.userId"
  51. placeholder="请输入用户id"
  52. clearable
  53. @keyup.enter="handleQuery"
  54. />
  55. </el-form-item>-->
  56. <el-form-item>
  57. <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
  58. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  59. </el-form-item>
  60. </el-form>
  61. <el-row :gutter="10" class="mb8">
  62. <el-col :span="1.5">
  63. <el-button
  64. type="primary"
  65. plain
  66. icon="Plus"
  67. @click="handleAdd"
  68. v-hasPermi="['logistics:banner:add']"
  69. >新增</el-button>
  70. </el-col>
  71. <el-col :span="1.5">
  72. <el-button
  73. type="success"
  74. plain
  75. icon="Edit"
  76. :disabled="single"
  77. @click="handleUpdate"
  78. v-hasPermi="['logistics:banner:edit']"
  79. >修改</el-button>
  80. </el-col>
  81. <el-col :span="1.5">
  82. <el-button
  83. type="danger"
  84. plain
  85. icon="Delete"
  86. :disabled="multiple"
  87. @click="handleDelete"
  88. v-hasPermi="['logistics:banner:remove']"
  89. >删除</el-button>
  90. </el-col>
  91. <!-- <el-col :span="1.5">
  92. <el-button
  93. type="warning"
  94. plain
  95. icon="Download"
  96. @click="handleExport"
  97. v-hasPermi="['logistics:banner:export']"
  98. >导出</el-button>
  99. </el-col>-->
  100. <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
  101. </el-row>
  102. <el-table v-loading="loading" :data="bannerList" @selection-change="handleSelectionChange">
  103. <el-table-column type="selection" width="55" align="center" />
  104. <!-- <el-table-column label="轮播图id" align="center" prop="bannerId" />-->
  105. <el-table-column label="轮播图名称" align="center" prop="bannerName" />
  106. <el-table-column label="轮播图" align="center" prop="imageUrl" width="100">
  107. <template #default="scope">
  108. <img :src="scope.row.imageBase64 || ''" :width="50" :height="50"/>
  109. </template>
  110. </el-table-column>
  111. <el-table-column label="跳转链接" align="center" prop="linkUrl" width="150" :show-overflow-tooltip="true"/>
  112. <!-- <el-table-column label="排序" align="center" prop="sortOrder" />-->
  113. <el-table-column label="状态" align="center" prop="isActive">
  114. <template #default="scope">
  115. <dict-tag :options="banner_status" :value="scope.row.isActive"/>
  116. </template>
  117. </el-table-column>
  118. <el-table-column label="系统类型" align="center" prop="sysType">
  119. <template #default="scope">
  120. <dict-tag :options="banner_sys_type" :value="scope.row.sysType"/>
  121. </template>
  122. </el-table-column>
  123. <!-- <el-table-column label="备注" align="center" prop="remark" />-->
  124. <!-- <el-table-column label="部门id" align="center" prop="deptId" />-->
  125. <!-- <el-table-column label="用户id" align="center" prop="userId" />-->
  126. <el-table-column label="创建时间" align="center" prop="createTime" width="180">
  127. <template #default="scope">
  128. <span>{{ parseTime(scope.row.createTime) }}</span>
  129. </template>
  130. </el-table-column>
  131. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  132. <template #default="scope">
  133. <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['logistics:banner:edit']">修改</el-button>
  134. <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['logistics:banner:remove']">删除</el-button>
  135. </template>
  136. </el-table-column>
  137. </el-table>
  138. <pagination
  139. v-show="total>0"
  140. :total="total"
  141. v-model:page="queryParams.pageNum"
  142. v-model:limit="queryParams.pageSize"
  143. @pagination="getList"
  144. />
  145. <!-- 添加或修改轮播图对话框 -->
  146. <el-dialog :title="title" v-model="open" width="500px" append-to-body>
  147. <el-form ref="bannerRef" :model="form" :rules="rules" label-width="120px">
  148. <el-form-item label="轮播图名称" prop="bannerName">
  149. <el-input v-model="form.bannerName" placeholder="请输入轮播图名称" />
  150. </el-form-item>
  151. <el-form-item label="轮播图" prop="imageUrl">
  152. <image-upload
  153. v-model="form.imageUrl"
  154. :limit="1"
  155. :preview-base64="form.imagePreviewBase64"
  156. @update:preview-base64="val => form.imagePreviewBase64 = val"
  157. />
  158. </el-form-item>
  159. <!-- <el-form-item label="排序值" prop="sortOrder">
  160. <el-input v-model="form.sortOrder" placeholder="请输入排序值" />
  161. </el-form-item>-->
  162. <el-form-item label="状态" prop="isActive">
  163. <el-radio-group v-model="form.isActive">
  164. <el-radio
  165. v-for="dict in banner_status"
  166. :key="dict.value"
  167. :label="dict.value"
  168. >{{dict.label}}</el-radio>
  169. </el-radio-group>
  170. </el-form-item>
  171. <el-form-item label="系统类型" prop="sysType">
  172. <el-radio-group v-model="form.sysType">
  173. <el-radio
  174. v-for="dict in banner_sys_type"
  175. :key="dict.value"
  176. :label="dict.value"
  177. >{{dict.label}}</el-radio>
  178. </el-radio-group>
  179. </el-form-item>
  180. <el-form-item label="跳转链接" >
  181. <el-input v-model="form.linkUrl" placeholder="请输入跳转链接" />
  182. </el-form-item>
  183. <!-- <el-form-item label="备注" prop="remark">
  184. <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
  185. </el-form-item>
  186. <el-form-item label="删除标志" prop="delFlag">
  187. <el-input v-model="form.delFlag" placeholder="请输入删除标志" />
  188. </el-form-item>
  189. <el-form-item label="部门id" prop="deptId">
  190. <el-input v-model="form.deptId" placeholder="请输入部门id" />
  191. </el-form-item>
  192. <el-form-item label="用户id" prop="userId">
  193. <el-input v-model="form.userId" placeholder="请输入用户id" />
  194. </el-form-item>-->
  195. </el-form>
  196. <template #footer>
  197. <div class="dialog-footer">
  198. <el-button type="primary" @click="submitForm">确 定</el-button>
  199. <el-button @click="cancel">取 消</el-button>
  200. </div>
  201. </template>
  202. </el-dialog>
  203. </div>
  204. </template>
  205. <script setup name="Banner">
  206. import { listBanner, getBanner, delBanner, addBanner, updateBanner } from "@/api/logistics/banner"
  207. import { getFileBase64 } from "@/api/file" // 新增:下载接口
  208. const { proxy } = getCurrentInstance()
  209. const { banner_status, banner_sys_type } = proxy.useDict('banner_status', 'banner_sys_type')
  210. const bannerList = ref([])
  211. const open = ref(false)
  212. const loading = ref(true)
  213. const showSearch = ref(true)
  214. const ids = ref([])
  215. const single = ref(true)
  216. const multiple = ref(true)
  217. const total = ref(0)
  218. const title = ref("")
  219. const data = reactive({
  220. form: {},
  221. queryParams: {
  222. pageNum: 1,
  223. pageSize: 10,
  224. bannerName: null,
  225. imageUrl: null,
  226. linkUrl: null,
  227. isActive: null,
  228. sysType: null,
  229. deptId: null,
  230. userId: null
  231. },
  232. rules: {
  233. bannerName: [
  234. { required: true, message: "轮播图名称不能为空", trigger: "blur" }
  235. ],
  236. imageUrl: [
  237. { required: true, message: "图片路径不能为空", trigger: "blur" }
  238. ],
  239. linkUrl: [
  240. { required: true, message: "跳转链接不能为空", trigger: "blur" }
  241. ],
  242. isActive: [
  243. { required: true, message: "状态不能为空", trigger: "change" }
  244. ],
  245. sysType: [
  246. { required: true, message: "系统类型不能为空", trigger: "change" }
  247. ],
  248. }
  249. })
  250. const { queryParams, form, rules } = toRefs(data)
  251. /** 查询轮播图列表 */
  252. /** 查询轮播图列表 */
  253. async function getList() {
  254. loading.value = true
  255. const response = await listBanner(queryParams.value)
  256. const rows = response.rows
  257. // 并发获取每个图片的 base64
  258. const promises = rows.map(async (item) => {
  259. if (item.imageUrl) {
  260. try {
  261. const base64 = await getFileBase64(item.imageUrl)
  262. item.imageBase64 = base64
  263. } catch (error) {
  264. console.error('获取图片Base64失败', error)
  265. item.imageBase64 = '' // 可设置默认图片
  266. }
  267. }
  268. return item
  269. })
  270. await Promise.all(promises)
  271. bannerList.value = rows
  272. total.value = response.total
  273. loading.value = false
  274. }
  275. // 取消按钮
  276. function cancel() {
  277. open.value = false
  278. reset()
  279. }
  280. // 表单重置
  281. function reset() {
  282. form.value = {
  283. bannerId: null,
  284. bannerName: null,
  285. imageUrl: null,
  286. imagePreviewBase64: null, // 重置
  287. linkUrl: null,
  288. sortOrder: null,
  289. isActive: null,
  290. sysType: null,
  291. remark: null,
  292. delFlag: null,
  293. createTime: null,
  294. updateTime: null,
  295. createBy: null,
  296. updateBy: null,
  297. deptId: null,
  298. userId: null
  299. }
  300. proxy.resetForm("bannerRef")
  301. }
  302. /** 搜索按钮操作 */
  303. function handleQuery() {
  304. queryParams.value.pageNum = 1
  305. getList()
  306. }
  307. /** 重置按钮操作 */
  308. function resetQuery() {
  309. proxy.resetForm("queryRef")
  310. handleQuery()
  311. }
  312. // 多选框选中数据
  313. function handleSelectionChange(selection) {
  314. ids.value = selection.map(item => item.bannerId)
  315. single.value = selection.length != 1
  316. multiple.value = !selection.length
  317. }
  318. /** 新增按钮操作 */
  319. function handleAdd() {
  320. reset()
  321. open.value = true
  322. title.value = "添加轮播图"
  323. }
  324. /** 修改按钮操作 */
  325. async function handleUpdate(row) {
  326. reset()
  327. const _bannerId = row.bannerId || ids.value
  328. const response = await getBanner(_bannerId)
  329. form.value = response.data
  330. // 如果已有图片,获取其 base64 用于预览
  331. if (form.value.imageUrl) {
  332. try {
  333. const base64 = await getFileBase64(form.value.imageUrl)
  334. form.value.imagePreviewBase64 = base64
  335. } catch (error) {
  336. console.error('获取预览图片失败', error)
  337. }
  338. }
  339. open.value = true
  340. title.value = "修改轮播图"
  341. }
  342. /** 提交按钮 */
  343. function submitForm() {
  344. proxy.$refs["bannerRef"].validate(valid => {
  345. if (valid) {
  346. if (form.value.bannerId != null) {
  347. updateBanner(form.value).then(response => {
  348. proxy.$modal.msgSuccess("修改成功")
  349. open.value = false
  350. getList()
  351. })
  352. } else {
  353. addBanner(form.value).then(response => {
  354. proxy.$modal.msgSuccess("新增成功")
  355. open.value = false
  356. getList()
  357. })
  358. }
  359. }
  360. })
  361. }
  362. /** 删除按钮操作 */
  363. function handleDelete(row) {
  364. const _bannerIds = row.bannerId || ids.value
  365. proxy.$modal.confirm('是否确认删除轮播图编号为"' + _bannerIds + '"的数据项?').then(function() {
  366. return delBanner(_bannerIds)
  367. }).then(() => {
  368. getList()
  369. proxy.$modal.msgSuccess("删除成功")
  370. }).catch(() => {})
  371. }
  372. /** 导出按钮操作 */
  373. function handleExport() {
  374. proxy.download('logistics/banner/export', {
  375. ...queryParams.value
  376. }, `banner_${new Date().getTime()}.xlsx`)
  377. }
  378. getList()
  379. </script>