From 6af033cedb5d85539e8fd3d825604bb4c73e718b Mon Sep 17 00:00:00 2001
From: 陶杰 <1378534974@qq.com>
Date: 星期三, 04 十二月 2024 10:17:37 +0800
Subject: [PATCH] 1.常规配置:基本配置 2.登录页:图片、公司名称、备案号、公司logo 3.主体页:图片、公司名称、备案号、公司logo

---
 pages/login.vue       |   54 ++++++
 layouts/default.vue   |   46 +++++
 pages/regular/sys.vue |  339 ++++++++++++++++++++++++++++++++++++++++++
 services/base.js      |    5 
 4 files changed, 437 insertions(+), 7 deletions(-)

diff --git a/layouts/default.vue b/layouts/default.vue
index 7aea5b1..7ab15f6 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -1,16 +1,16 @@
 <template>
   <div class="back-layout">
-    <div
-      v-if="isMobile && !menuShrink"
-      class="back-layout__backdrop"
-      @click="onBackdropClick"
-    />
+    <div v-if="isMobile && !menuShrink" class="back-layout__backdrop" @click="onBackdropClick" />
     <base-sidebar></base-sidebar>
     <div class="back-layout__right">
       <base-nav></base-nav>
       <tags-view v-if="enableTagView"></tags-view>
       <div class="back-layout__main">
         <nuxt />
+      </div>
+      <div class="copyright">
+        <img class="copyright-logo" :src="logoUrl" /> {{ copyright?.base_website_name }} 版权所有 |
+        {{ copyright?.base_regisition_num }}
       </div>
     </div>
   </div>
@@ -24,9 +24,14 @@
     TagsView,
   },
   middleware: ['auth', 'permission'],
+  created() {
+    this.getCopyRight()
+  },
   data() {
     return {
       enableTagView: this.$config.enableTagView,
+      copyright: {},
+      logoUrl: '',
     }
   },
   computed: {
@@ -39,6 +44,16 @@
     onBackdropClick() {
       this.$store.commit('app/SET_MENU_SHRINK', true)
     },
+
+    async getCopyRight() {
+      const { code, data } = await this.$services.base.getBaseInfo()
+      if (code === 0) {
+        this.copyright = data
+        this.copyright.base_bg_url = JSON.parse(data.base_bg_url || [])
+        this.copyright.base_logo_url = JSON.parse(data.base_logo_url || [])
+        this.logoUrl = this.copyright?.base_logo_url[0]?.url
+      }
+    },
   },
 }
 </script>
@@ -49,6 +64,7 @@
   height: 100%;
   overflow: hidden;
   display: flex;
+
   &__backdrop {
     background-color: rgba(0, 0, 0, 0.3);
     width: 100%;
@@ -57,6 +73,7 @@
     position: absolute;
     z-index: 999;
   }
+
   &__right {
     flex: 1;
     height: 100%;
@@ -65,11 +82,30 @@
     display: flex;
     flex-direction: column;
   }
+
   &__main {
     flex: 1;
     background-color: $bg-color;
     overflow: auto;
     padding: 20px;
   }
+
+  .copyright {
+    margin: auto;
+    margin-top: 10px;
+    height: 20px;
+    display: flex;
+    justify-content: center;
+    align-content: center;
+    font-size: 12px;
+    color: gray;
+
+    .copyright-logo {
+      width: 15px;
+      height: 15px;
+      border-radius: 50px;
+      /* 设置圆角 */
+    }
+  }
 }
 </style>
diff --git a/pages/login.vue b/pages/login.vue
index cdb67cc..10a8104 100644
--- a/pages/login.vue
+++ b/pages/login.vue
@@ -1,9 +1,18 @@
 <template>
-  <div class="login-page">
+
+  <div class="login-page" 
+  :style="{ 
+    backgroundImage: 'url(' + bgUrl + ')', 
+    backgroundSize: 'cover', 
+    backgroundPosition: 'center',
+    height: '100vh' }
+  "
+  >
     <div class="form-content">
       <div class="text-22 font-bold text-mainTitle">HELLO</div>
       <div class="text-26 font-bold text-mainTitle">
-        欢迎来到<span class="text-primary">{{ platformName }}</span>
+        <!-- 欢迎来到<span class="text-primary">{{ platformName }}</span> -->
+        欢迎来到<span class="text-primary">{{ copyright?.base_website_name }}</span>
       </div>
       <div class="flex items-center justify-center mt-50 mb-20">
         <div
@@ -118,8 +127,15 @@
           >登录</el-button
         >
       </el-form>
+
+      <div class="copyright">
+          <img class="copyright-logo" :src="logoUrl" /> {{ copyright?.base_website_name }} 版权所有 |
+          {{ copyright?.base_regisition_num }}
+      </div>
     </div>
+    
   </div>
+  
 </template>
 
 <script>
@@ -152,6 +168,9 @@
         },
         code: { required: true, message: '请输入图形验证码', trigger: 'blur' },
       },
+      copyright:{},
+      logoUrl:'',
+      bgUrl:'https://hmy-flower.oss-cn-shanghai.aliyuncs.com/87/878c638c06cf4c3080e6b7139f9a955cdshsp.png',
     }
   },
   watch: {
@@ -162,10 +181,22 @@
     },
   },
   async mounted() {
+    await this.getCopyRight()
     // 获取验证码图形
     await this.getCapacha()
   },
   methods: {
+
+    async getCopyRight() {
+      const { code, data } = await this.$services.base.getBaseInfo()
+      if (code === 0) {
+        this.copyright = data
+        this.copyright.base_bg_url = JSON.parse(data.base_bg_url || [])
+        this.copyright.base_logo_url = JSON.parse(data.base_logo_url || [])
+        this.logoUrl = this.copyright?.base_logo_url[0]?.url
+        this.bgUrl=this.copyright?.base_bg_url[0]?.url
+      }
+    },
     async getCapacha() {
       const { captchaCodeId, imageSrc } =
         await this.$services.base.createCaptcha()
@@ -278,5 +309,24 @@
       }
     }
   }
+
+  .copyright {
+    width:100%;
+    margin: auto;
+    margin-top: 10px;
+    height: 20px;
+    display: flex;
+    justify-content: center;
+    align-content: center;
+    font-size: 12px;
+    color: gray;
+
+    .copyright-logo {
+      width: 15px;
+      height: 15px;
+      border-radius: 50px;
+      /* 设置圆角 */
+    }
+  }
 }
 </style>
diff --git a/pages/regular/sys.vue b/pages/regular/sys.vue
new file mode 100644
index 0000000..6c79517
--- /dev/null
+++ b/pages/regular/sys.vue
@@ -0,0 +1,339 @@
+<template>
+    <div>
+        <el-card class="box-card">
+            <div slot="header" class="clearfix">
+                <span>系统配置</span>
+                <!-- <el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button> -->
+            </div>
+
+            <el-tabs v-model="activeName" type="card" class="setupClass-tab" @tab-click="handleClick">
+                <el-tab-pane v-for="(item, index) in tabList" :key="item.id" :label="item.paramGroupName"
+                    :name="item.paramGroup">
+
+                    <el-form :model="formModels[item.id]" :rules="formRules[item.id]" label-width="120px"
+                        :ref="(el) => (formRefs[index] = el)" style="width: 100%">
+
+                        <el-form-item v-for="(param) in item.paramList" :key="param.id" :label="param.paramName"
+                            :prop="param.paramKey">
+
+                            <el-input v-if="param.paramControlType === 'input'"
+                                v-model="formModels[item.id][param.paramKey]" :placeholder="param.paramPlaceholder"
+                                clearable />
+
+                            <el-upload v-if="param.paramControlType === 'image'" :action="uploadUrl"
+                                list-type="picture-card" :file-list="formModels[item.id][param.paramKey]"
+                                :limit="param.paramLimit" 
+                                :on-preview="handlePictureCardPreview"
+                                :on-remove="(file) => handleRemove(file, param)"
+                                :on-success="(response, file, fileList) => handleUploadSuccess(response, file, fileList, param)">
+                                <i class="el-icon-plus"></i>
+                            </el-upload>
+                        </el-form-item>
+
+                        <el-form-item v-if="item.paramList && item.paramList.length > 0">
+                            <el-button type="primary" @click="submitForm(index)">提交</el-button>
+                            <el-button @click="resetForm(index)">重置</el-button>
+                        </el-form-item>
+                    </el-form>
+                </el-tab-pane>
+            </el-tabs>
+        </el-card>
+
+        <!-- 预览弹窗 -->
+        <el-dialog :visible.sync="previewVisible">
+            <img :src="previewImage" alt="Preview Image" style="width: 100%;" />
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+
+import utils from 'el-business-utils'
+
+export default {
+    data() {
+        return {
+            uploadUrl: '',
+            activeName: 'first',
+            tabList: [],
+            previewVisible: false,
+            previewImage: '',
+            curTab: {},
+            curIndex: 0,
+            formRefs: [],
+            formModels: {}, // 存储每个 tab 的 formModel
+            srcFormModels: {}, // 原始表单数据
+            formRules: {}, // 存储每个 tab 的 formRules
+        };
+    },
+
+    created() {
+        const config = process.env.config
+        this.uploadUrl = utils.joinPath(config.httpBaseUri, `flower/api/upload/oss/file`)
+    },
+    async mounted() {
+        await this.getConfigParamGroup();
+    },
+
+    methods: {
+        handleClick(tab, event) {
+            this.chooseTab(tab.index)
+        },
+
+        chooseTab(index) {
+            this.curTab = this.tabList[index];
+            this.curIndex = index;
+            this.getConfigParam();
+        },
+
+        async getConfigParamGroup() {
+            const { code, data } = await this.$elBusHttp.request('flower/v2/config-param-group/list', { params: {} });
+            if (code === 0) {
+                this.tabList = [...data];
+                this.activeName = data[0]?.paramGroup || '';
+                this.tabList.forEach(item => {
+                    this.$set(this.formModels, item.id, {});
+                    this.$set(this.srcFormModels, item.id, {}); // 初始化 srcFormModels
+                    this.$set(this.formRules, item.id, {});
+                });
+                if (data[0]) {
+                    this.curTab = this.tabList[0];
+                    this.curIndex = 0;
+                    this.getConfigParam();
+                }
+
+            }
+        },
+
+        createFormModel(paramList) {
+            // 创建一个空的对象,用于存储参数
+            const model = {};
+            paramList.forEach(param => {
+                // 如果param.paramControlType是image的话,则将值反序列化成ArrayList
+                if (param.paramControlType === 'image') {
+                    model[param.paramKey] = this.parseFileList(param.paramValue) || [];
+                } else {
+                    // 默认处理为字符串
+                    model[param.paramKey] = param.paramValue || '';
+                }
+            });
+            return model;
+        },
+
+        createFormRules(paramList) {
+            const rules = {};
+            paramList.forEach(param => {
+                if (param.paramRequire) {
+                    const trigger = param.paramControlType === 'input' ? 'blur' : 'change';
+                    const rule = [
+                        { required: true, message: `${param.paramPlaceholder}`, trigger }
+                    ];
+
+                    // 如果param_limit存在且不为null/undefined,添加最大值校验
+                    if (param.paramLimit) {
+                        // 如果paramControlType是'input',执行最大值校验
+                        if (param.paramControlType !== 'image') {
+                            rule.push({
+                                max: param.paramLimit,
+                                message: `${param.paramName}最大值为 ${param.paramLimit}!`,
+                                trigger
+                            });
+                        } else {
+                            // 如果是image类型,添加自定义验证,判断数组长度
+                            rule.push({
+                                validator: (rule, value, callback) => {
+                                    if (Array.isArray(value) && value.length > param.paramLimit) {
+                                        callback(new Error(`${param.paramName}最多上传 ${param.paramLimit} 张图片`));
+                                    } else {
+                                        callback();  // 验证通过
+                                    }
+                                },
+                                trigger
+                            });
+                        }
+                    }
+
+                    rules[param.paramKey] = rule;
+                }
+            });
+            return rules;
+        },
+
+        async getConfigParam() {
+            const { code, data } = await this.$elBusHttp.request('flower/v2/config-param/list', {
+                params: { paramGroupId: this.curTab.id },
+            });
+            if (code === 0) {
+                this.tabList[this.curIndex].paramList = [...data];
+
+                // 构造 formModel 和 formRules,并分别存储到对应的对象中
+                const formData = this.createFormModel(data);
+                this.$set(this.formModels, this.curTab.id, { ...formData });
+                this.$set(this.srcFormModels, this.curTab.id, { ...formData }); // 初始化 srcFormModels
+                this.$set(this.formRules, this.curTab.id, this.createFormRules(data));
+            }
+        },
+
+        handleRemove(file, param) {
+            const srcFormModel = this.srcFormModels[this.curTab.id];
+            const currentFormModel = this.formModels[this.curTab.id];
+            if (file?.response?.code === '0') {
+                const data = file?.response?.data;
+                if (data && data[0]) {
+                    const removeFile = data[0]
+                    const updatedFileList = currentFormModel[param.paramKey].filter(item => item.url !== removeFile.url);
+                    // 保存原有的图片控件属性值
+                    if (updatedFileList.length === 0) {
+                        // 如果文件列表为空,设置为空字符串
+                        this.$set(currentFormModel, param.paramKey, []);
+                    } else {
+                        // 否则,更新为新的文件列表 JSON 字符串
+                        this.$set(currentFormModel, param.paramKey, updatedFileList);
+
+                    }
+
+                }
+
+            } else if (file && file?.url) {
+                const updatedFileList = currentFormModel[param.paramKey].filter(item => item.url !== file.url);
+                // 保存原有的图片控件属性值
+                if (updatedFileList.length === 0) {
+                    // 如果文件列表为空,设置为空字符串
+                    this.$set(currentFormModel, param.paramKey, []);
+                } else {
+                    // 否则,更新为新的文件列表 JSON 字符串
+                    this.$set(currentFormModel, param.paramKey, updatedFileList);
+
+                }
+            }
+
+        },
+
+        parseFileList(fileListString) {
+            try {
+                return JSON.parse(fileListString || '[]');
+            } catch (error) {
+                console.error('Error parsing fileList JSON:', error);
+                return [];
+            }
+        },
+        parseFileListCompare(fileListString, groupId, paramKey) {
+            console.log("parseFileListCompare")
+            try {
+                return JSON.parse(fileListString || '[]');
+            } catch (error) {
+                console.error('Error parsing fileList JSON:', error);
+                return [];
+            }
+
+            // const newVal = this.formModels[groupId][paramKey]
+            // const srcVal = this.srcFormModels[groupId][paramKey]
+            // if (newVal !== srcVal) {
+            //     try {
+            //         return JSON.parse(fileListString || '[]');
+            //     } catch (error) {
+            //         console.error('Error parsing fileList JSON:', error);
+            //         return [];
+            //     }
+            // }
+        },
+
+        handleUploadSuccess(response, file, fileList, param) {
+            if (response.code === '0') {
+                const currentFormModel = this.formModels[this.curTab.id];
+                const existingFileList = currentFormModel[param.paramKey];
+                const newFile = response.data[0];
+                const updatedFileList = [...existingFileList, newFile];
+                // this.$set(currentFormModel, param.paramKey, JSON.stringify(updatedFileList));
+                currentFormModel[param.paramKey] = updatedFileList;
+            } else {
+                this.$message.error('文件上传失败');
+            }
+        },
+
+        handlePictureCardPreview(file) {
+            if (file.url) {
+                this.previewImage = file.url;
+                this.previewVisible = true;
+            } else {
+                this.$message.error('无法预览该文件');
+            }
+        },
+
+        submitForm(index) {
+            console.log("submitForm")
+            console.log(this.formModels[this.curTab.id])
+            console.log(this.formRules[this.curTab.id])
+
+            const formRef = this.formRefs[index];
+            if (formRef) {
+                formRef.validate(async (valid) => {
+                    if (valid) {
+
+                        // 这里需要将表单的属性匹配到当前的tabList下的paramList的列
+                        const tmpParamList = this.tabList[this.curIndex].paramList;
+                        // 遍历
+                        const submitFormModel = this.formModels[this.curTab.id]
+                        // 遍历 submitFormModel 的属性
+                        Object.keys(submitFormModel).forEach((key) => {
+                            // 在 tmpParamList 中找到 paramKey 与当前属性 key 匹配的记录
+                            const paramItem = tmpParamList.find((item) => item.paramKey === key);
+                            if (paramItem) {
+                                // 将 paramValue 设置为表单中对应属性的值
+                                paramItem.paramValue = submitFormModel[key];
+                            }
+                        });
+                        console.log("修改后的值")
+                        console.log(tmpParamList)
+                        const resultArray = tmpParamList
+                            .filter((item) => item.id !== undefined) // 确保 id 存在
+                            .map((item) => ({
+                                id: item.id,
+                                paramValue: item.paramControlType === 'image' ? JSON.stringify(item.paramValue) : item.paramValue
+                            }));
+
+                        await this.$elBusUtil.confirm('确定要提交吗?')
+                        const { code } = await this.$elBusHttp.request(
+                            'flower/v2/config-param/update/batch',
+                            {
+                                method: 'put',
+                                data: {
+                                    paramList: resultArray,
+                                },
+                            }
+                        )
+                        if (code === 0) {
+                            await this.getConfigParam()
+                            this.$message.success('更新成功')
+
+                        }
+
+
+                        // this.$message.success('表单校验成功!');
+                        // console.log('提交的表单数据: ', this.formModels[this.tabList[index].id]);
+                    } else {
+                        this.$message.error('表单校验失败,请检查填写内容!');
+                    }
+                });
+            } else {
+                console.error(`表单引用未找到: formRefs[${index}]`);
+            }
+        },
+
+        resetForm(index) {
+            // console.log()
+            // const formRef = this.formRefs[index];
+            // if (formRef) {
+            //     formRef.resetFields();
+
+            //     this.$message.info('表单已重置');
+            // } else {
+            //     console.error(`未找到表单引用: formRefs[${index}]`);
+            // }
+            this.chooseTab(index)
+            this.activeName = this.tabList[index]?.paramGroup
+
+        },
+    },
+};
+</script>
diff --git a/services/base.js b/services/base.js
index fa007de..8080da9 100644
--- a/services/base.js
+++ b/services/base.js
@@ -15,6 +15,11 @@
     },
     getAreaJson(){
       return http.request('flower/api/pub/china/area/json')
+    },
+    getBaseInfo(){
+      return http.request('flower/v2/config-param/base/info')
     }
+
+
   }
 }

--
Gitblit v1.9.3