index.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <template>
  2. <div class="p-2">
  3. <el-card shadow="hover" v-loading="loading">
  4. <template #header>
  5. <div class="card-header">
  6. <span class="title">登录图片设置</span>
  7. </div>
  8. </template>
  9. <div class="tips-section">
  10. <p>网站登录页顶部4张图片,每次刷新可随机显示,最多可设置上传4张。</p>
  11. <p>选择上传文件并提交表单生效,图片请依照输入框下提示文字内容选项。</p>
  12. <p>背景色指图片下方区域颜色,适用于较宽分辨率下浏览页面时整体充满窗宽,因此请注择和上传图片最为接近或相邻原的色彩。</p>
  13. </div>
  14. <!-- 图片1 -->
  15. <div class="image-section" v-for="(item, index) in imageList" :key="index">
  16. <div class="image-title">
  17. <span class="label">图片{{ index + 1 }}:</span>
  18. <span class="hint">请使用1000*480像素jpg/gif/png格式的图片</span>
  19. </div>
  20. <div class="image-content">
  21. <div class="image-preview">
  22. <el-image
  23. v-if="item.image"
  24. :src="item.image"
  25. fit="cover"
  26. style="width: 280px; height: 140px;"
  27. />
  28. <div v-else class="empty-image">
  29. <el-icon size="40"><Picture /></el-icon>
  30. </div>
  31. </div>
  32. <div class="image-actions">
  33. <div class="upload-btn">
  34. <image-upload v-model="item.image" :limit="1" :fileSize="5" :isShowTip="false" />
  35. </div>
  36. <div class="color-picker">
  37. <span>背景色:</span>
  38. <el-color-picker v-model="item.bgColor" />
  39. </div>
  40. <div class="action-btns">
  41. <el-button @click="handleReset(index)">重 置</el-button>
  42. <el-button type="primary" @click="handleConfirm(index)">确 认</el-button>
  43. </div>
  44. </div>
  45. </div>
  46. </div>
  47. </el-card>
  48. </div>
  49. </template>
  50. <script setup name="LoginSetting" lang="ts">
  51. import { listPlatformConfig, addPlatformConfig, updatePlatformConfig } from '@/api/system/platformConfig';
  52. import { ComponentInternalInstance, getCurrentInstance, ref, reactive, onMounted } from 'vue';
  53. import { Picture } from '@element-plus/icons-vue';
  54. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  55. const loading = ref(true);
  56. const configList = ref<any[]>([]);
  57. const imageList = reactive([
  58. { image: '', bgColor: '#409EFF', configKeyImage: 'loginImage1', configKeyColor: 'loginBgColor1' },
  59. { image: '', bgColor: '#409EFF', configKeyImage: 'loginImage2', configKeyColor: 'loginBgColor2' },
  60. { image: '', bgColor: '#409EFF', configKeyImage: 'loginImage3', configKeyColor: 'loginBgColor3' },
  61. { image: '', bgColor: '#409EFF', configKeyImage: 'loginImage4', configKeyColor: 'loginBgColor4' }
  62. ]);
  63. const getList = async () => {
  64. loading.value = true;
  65. try {
  66. const res = await listPlatformConfig({ configType: '1', pageNum: 1, pageSize: 100 });
  67. configList.value = res.rows || [];
  68. configList.value.forEach((item: any) => {
  69. imageList.forEach((img, index) => {
  70. if (item.configKey === img.configKeyImage) {
  71. imageList[index].image = item.value || '';
  72. }
  73. if (item.configKey === img.configKeyColor) {
  74. imageList[index].bgColor = item.value || '#409EFF';
  75. }
  76. });
  77. });
  78. } finally {
  79. loading.value = false;
  80. }
  81. };
  82. const handleReset = (index: number) => {
  83. imageList[index].image = '';
  84. imageList[index].bgColor = '#409EFF';
  85. };
  86. const handleConfirm = async (index: number) => {
  87. const item = imageList[index];
  88. // 保存图片
  89. const existImage = configList.value.find((c: any) => c.configKey === item.configKeyImage);
  90. if (existImage) {
  91. await updatePlatformConfig({ ...existImage, value: item.image });
  92. } else {
  93. await addPlatformConfig({ configType: '1', configKey: item.configKeyImage, name: `登录图片${index + 1}`, value: item.image });
  94. }
  95. // 保存背景色
  96. const existColor = configList.value.find((c: any) => c.configKey === item.configKeyColor);
  97. if (existColor) {
  98. await updatePlatformConfig({ ...existColor, value: item.bgColor });
  99. } else {
  100. await addPlatformConfig({ configType: '1', configKey: item.configKeyColor, name: `登录背景色${index + 1}`, value: item.bgColor });
  101. }
  102. proxy?.$modal.msgSuccess('保存成功');
  103. getList();
  104. };
  105. onMounted(() => {
  106. getList();
  107. });
  108. </script>
  109. <style scoped>
  110. .card-header {
  111. display: flex;
  112. justify-content: space-between;
  113. align-items: center;
  114. }
  115. .card-header .title {
  116. font-size: 16px;
  117. font-weight: bold;
  118. }
  119. .tips-section {
  120. margin-bottom: 20px;
  121. padding: 10px;
  122. background: #f5f7fa;
  123. border-radius: 4px;
  124. }
  125. .tips-section p {
  126. margin: 5px 0;
  127. color: #606266;
  128. font-size: 13px;
  129. }
  130. .image-section {
  131. margin-bottom: 30px;
  132. padding-bottom: 20px;
  133. border-bottom: 1px solid #ebeef5;
  134. }
  135. .image-section:last-child {
  136. border-bottom: none;
  137. }
  138. .image-title {
  139. margin-bottom: 15px;
  140. }
  141. .image-title .label {
  142. font-weight: bold;
  143. color: #409EFF;
  144. }
  145. .image-title .hint {
  146. color: #409EFF;
  147. font-size: 13px;
  148. }
  149. .image-content {
  150. display: flex;
  151. align-items: flex-start;
  152. gap: 30px;
  153. }
  154. .image-preview {
  155. width: 280px;
  156. height: 140px;
  157. border: 1px solid #dcdfe6;
  158. border-radius: 4px;
  159. overflow: hidden;
  160. }
  161. .empty-image {
  162. width: 100%;
  163. height: 100%;
  164. display: flex;
  165. align-items: center;
  166. justify-content: center;
  167. background: #f5f7fa;
  168. color: #909399;
  169. }
  170. .image-actions {
  171. display: flex;
  172. flex-direction: column;
  173. gap: 15px;
  174. }
  175. .color-picker {
  176. display: flex;
  177. align-items: center;
  178. gap: 10px;
  179. }
  180. .action-btns {
  181. display: flex;
  182. gap: 10px;
  183. }
  184. </style>