lxz пре 2 година
родитељ
комит
2ab5481500

+ 12 - 0
src/api/sys/userAccountApi.ts

@@ -0,0 +1,12 @@
+import { defHttp } from '/@/utils/http/axios';
+enum Api {
+  userAccountInfo = '/user/accountInfo',
+  editPsw = '/oauth2/psw/updatePswl',
+}
+
+export const userAccountInfo = () => {
+  return defHttp.get({ url: Api.userAccountInfo });
+};
+export function editPsw(params: object) {
+  return defHttp.post({ url: Api.editPsw, params: params });
+}

+ 3 - 8
src/layouts/default/header/components/user-dropdown/index.vue

@@ -13,13 +13,7 @@
       <Menu @click="handleMenuClick">
         <MenuDivider v-if="getShowDoc" />
         <!-- <MenuItem key="accountCenter" :text="'个人中心'" icon="grommet-icons:user" /> -->
-        <MenuItem key="accountSetting" :text="'账户设置'" icon="grommet-icons:user-settings" />
-        <!-- <MenuItem
-          v-if="getUseLockPage"
-          key="lock"
-          :text="t('layout.header.tooltipLock')"
-          icon="ion:lock-closed-outline"
-        /> -->
+        <MenuItem key="accountSetting" :text="'个人中心'" icon="grommet-icons:user-settings" />
         <MenuItem key="clear" text="清空缓存" icon="rest|iconfont" />
         <MenuItem key="logout" text="退出" icon="poweroff|iconfont" />
       </Menu>
@@ -62,6 +56,7 @@
     name: 'UserDropdown',
     components: {
       Dropdown,
+      // eslint-disable-next-line vue/no-reserved-component-names
       Menu,
       MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
       MenuDivider: Menu.Divider,
@@ -114,7 +109,7 @@
 
       // account setting
       function handleClickAccountSetting() {
-        go('/account/setting');
+        go('/sys/accountCenter');
       }
 
       function handleMenuClick(e: { key: MenuEvent }) {

+ 4 - 0
src/utils/filters.ts

@@ -94,6 +94,10 @@ export const SexFilters = [
   { text: '女', value: '2' },
   { text: '未知', value: '3' },
 ];
+export const gender = [
+  { label: '男', value: '1' },
+  { label: '女', value: '2' },
+];
 
 export const SexSelect = [
   { label: '男', value: 1 },

+ 0 - 3
src/views/infra/job/jobTable/viewDrawer.vue

@@ -31,10 +31,7 @@
     typeStatus.value = await listDictModel({ dictCode: 'quartz_job_status' });
   });
   const [registerDrawer] = useDrawerInner(async data => {
-    console.log('::::::::::', data.record);
     const resData = await infraJobDetail(data.record.jobId);
-    // const resData = data.record;
-    console.log('::::::::11::', data.record);
     descData.value = {
       ...resData,
       jobGroup: formatDictValue(typeOptions.value, resData.jobGroup),

+ 0 - 92
src/views/sys/account/center/Application.vue

@@ -1,92 +0,0 @@
-<template>
-  <List :class="prefixCls">
-    <a-row :gutter="16">
-      <template v-for="item in list" :key="item.title">
-        <a-col :span="6">
-          <ListItem>
-            <Card :hoverable="true" :class="`${prefixCls}__card`">
-              <div :class="`${prefixCls}__card-title`">
-                <Icon class="icon" v-if="item.icon" :icon="item.icon" :color="item.color" />
-                {{ item.title }}
-              </div>
-              <div :class="`${prefixCls}__card-num`">
-                活跃用户:<span>{{ item.active }}</span> 万
-              </div>
-              <div :class="`${prefixCls}__card-num`">
-                新增用户:<span>{{ item.new }}</span>
-              </div>
-              <Icon
-                :class="`${prefixCls}__card-download`"
-                v-if="item.download"
-                :icon="item.download"
-              />
-            </Card>
-          </ListItem>
-        </a-col>
-      </template>
-    </a-row>
-  </List>
-</template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-  import { List, Card, Row, Col } from 'ant-design-vue';
-  import Icon from '/@/components/Icon/index';
-  import { applicationList } from './data';
-
-  export default defineComponent({
-    components: {
-      List,
-      ListItem: List.Item,
-      Card,
-      Icon,
-      [Row.name]: Row,
-      [Col.name]: Col,
-    },
-    setup() {
-      return {
-        prefixCls: 'account-center-application',
-        list: applicationList,
-      };
-    },
-  });
-</script>
-<style lang="less">
-  .account-center-application {
-    &__card {
-      width: 100%;
-      margin-bottom: -12px;
-
-      .ant-card-body {
-        padding: 16px;
-      }
-
-      &-title {
-        margin-bottom: 5px;
-        font-size: 16px;
-        font-weight: 500;
-
-        .icon {
-          margin-top: -5px;
-          font-size: 22px;
-        }
-      }
-
-      &-num {
-        margin-left: 24px;
-        line-height: 36px;
-        color: @text-color-secondary;
-
-        span {
-          margin-left: 5px;
-          font-size: 18px;
-        }
-      }
-
-      &-download {
-        float: right;
-        font-size: 20px !important;
-        color: @primary-color;
-      }
-    }
-  }
-</style>

+ 0 - 97
src/views/sys/account/center/Article.vue

@@ -1,97 +0,0 @@
-<template>
-  <List item-layout="vertical" :class="prefixCls">
-    <template v-for="item in list" :key="item.title">
-      <ListItem>
-        <ListItemMeta>
-          <template #description>
-            <div :class="`${prefixCls}__content`">
-              {{ item.content }}
-            </div>
-          </template>
-          <template #title>
-            <p :class="`${prefixCls}__title`">
-              {{ item.title }}
-            </p>
-            <div>
-              <template v-for="tag in item.description" :key="tag">
-                <Tag class="mb-2">
-                  {{ tag }}
-                </Tag>
-              </template>
-            </div>
-          </template>
-        </ListItemMeta>
-        <div>
-          <template v-for="action in actions" :key="action.text">
-            <div :class="`${prefixCls}__action`">
-              <Icon
-                v-if="action.icon"
-                :class="`${prefixCls}__action-icon`"
-                :icon="action.icon"
-                :color="action.color"
-              />
-              {{ action.text }}
-            </div>
-          </template>
-          <span :class="`${prefixCls}__time`">{{ item.time }}</span>
-        </div>
-      </ListItem>
-    </template>
-  </List>
-</template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-  import { List, Tag } from 'ant-design-vue';
-  import Icon from '/@/components/Icon/index';
-  import { actions, articleList } from './data';
-
-  export default defineComponent({
-    components: {
-      List,
-      ListItem: List.Item,
-      ListItemMeta: List.Item.Meta,
-      Tag,
-      Icon,
-    },
-    setup() {
-      return {
-        prefixCls: 'account-center-article',
-        list: articleList,
-        actions,
-      };
-    },
-  });
-</script>
-<style lang="less" scoped>
-  .account-center-article {
-    &__title {
-      margin-bottom: 12px;
-      font-size: 18px;
-    }
-
-    &__content {
-      color: rgba(0, 0, 0, 0.65);
-    }
-
-    &__action {
-      display: inline-block;
-      padding: 0 16px;
-      color: rgba(0, 0, 0, 0.45);
-
-      &:nth-child(1),
-      &:nth-child(2) {
-        border-right: 1px solid rgba(206, 206, 206, 0.4);
-      }
-
-      &-icon {
-        margin-right: 3px;
-      }
-    }
-
-    &__time {
-      position: absolute;
-      right: 20px;
-      color: rgba(0, 0, 0, 0.45);
-    }
-  }
-</style>

+ 0 - 71
src/views/sys/account/center/Project.vue

@@ -1,71 +0,0 @@
-<template>
-  <List :class="prefixCls">
-    <a-row :gutter="16">
-      <template v-for="item in list" :key="item.title">
-        <a-col :span="6">
-          <ListItem>
-            <Card :hoverable="true" :class="`${prefixCls}__card`">
-              <img :src="demoImg" />
-              <div :class="`${prefixCls}__card-title`">
-                {{ item.title }}
-              </div>
-              <div :class="`${prefixCls}__card-content`">
-                {{ item.content }}
-              </div>
-            </Card>
-          </ListItem>
-        </a-col>
-      </template>
-    </a-row>
-  </List>
-</template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-  import { List, Card, Row, Col } from 'ant-design-vue';
-  import demoImg from '/@/assets/images/header.png';
-  import { projectList } from './data';
-
-  export default defineComponent({
-    components: {
-      List,
-      ListItem: List.Item,
-      Card,
-      [Row.name]: Row,
-      [Col.name]: Col,
-    },
-    setup() {
-      return {
-        prefixCls: 'account-center-project',
-        list: projectList,
-        demoImg,
-      };
-    },
-  });
-</script>
-<style lang="less">
-  .account-center-project {
-    &__card {
-      width: 100%;
-
-      .ant-card-body {
-        padding: 0 0 24px 0;
-      }
-
-      img {
-        width: 100%;
-        height: 130px;
-      }
-
-      &-title {
-        margin: 5px 10px;
-        font-size: 16px;
-        font-weight: 500;
-        color: rgba(0, 0, 0, 0.85);
-      }
-
-      &-content {
-        margin: 5px 10px;
-      }
-    }
-  }
-</style>

+ 58 - 0
src/views/sys/account/center/basicInformation.vue

@@ -0,0 +1,58 @@
+<template>
+  <div>
+    <BasicForm @register="registerForm" layout="vertical" />
+    <a-button @click="handleReset">重置</a-button>
+    <a-button type="primary" @click="handleSubmit">保存</a-button>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { BasicForm, useForm } from '/@/components/Form';
+  // import { useMessage } from '/@/hooks/web/useMessage';
+  import { InformationFormSchema } from './data';
+  // import { Upload } from 'ant-design-vue';
+  import { userAccountInfo } from '/@/api/sys/userAccountApi';
+  import { onMounted } from 'vue';
+
+  onMounted(async () => {
+    const res = await userAccountInfo();
+    console.log('res::::::::::::', res);
+    await setFieldsValue({ ...res.basicInfo });
+  });
+
+  // const { createMessage } = useMessage();
+  const [registerForm, { setFieldsValue, validate }] = useForm({
+    labelWidth: 120,
+    schemas: InformationFormSchema,
+    showActionButtonGroup: false,
+    actionColOptions: {
+      span: 23,
+    },
+    baseColProps: {
+      span: 18,
+    },
+    wrapperCol: {
+      span: 24,
+    },
+  });
+  // 提交按钮事件
+  async function handleSubmit() {
+    const values = await validate();
+    console.log('abc', values);
+    //   await sysSettingEdit(values);
+    //   createMessage.success('修改成功');
+  }
+  async function handleReset() {
+    const res = await userAccountInfo();
+
+    await setFieldsValue(res);
+  }
+</script>
+
+<style lang="less" scoped>
+  .img-avatar {
+    display: block;
+    width: 60px;
+    height: 60px;
+  }
+</style>

+ 93 - 0
src/views/sys/account/center/data.ts

@@ -0,0 +1,93 @@
+import { FormSchema } from '/@/components/Form';
+import { gender } from '/@/utils/filters';
+
+export const InformationFormSchema: FormSchema[] = [
+  {
+    label: '用户昵称',
+    field: 'username',
+    required: true,
+    component: 'Input',
+    componentProps: {
+      placeholder: '请输入用户昵称',
+    },
+  },
+  {
+    label: '手机号码',
+    field: 'phone',
+    required: true,
+    component: 'Input',
+    componentProps: {
+      placeholder: '请输入手机号码',
+    },
+    rules: [{ len: 11 }],
+  },
+  {
+    label: '用户邮箱',
+    field: 'email',
+    required: true,
+    component: 'Input',
+    componentProps: {
+      placeholder: '请输入用户邮箱',
+    },
+  },
+  {
+    label: '性别',
+    field: 'gender',
+    required: true,
+    component: 'RadioGroup',
+    componentProps: {
+      options: gender,
+    },
+  },
+];
+export const pswFormSchema: FormSchema[] = [
+  {
+    label: '旧密码',
+    field: 'oldPsw',
+    required: true,
+    component: 'InputPassword',
+    componentProps: {
+      placeholder: '请输入旧密码',
+    },
+  },
+  {
+    label: '新密码',
+    field: 'newPsw',
+    required: true,
+    component: 'InputPassword',
+    componentProps: {
+      placeholder: '请输入新密码',
+    },
+    rules: [
+      {
+        min: 6,
+      },
+    ],
+  },
+  {
+    label: '确认密码',
+    field: 'confirmPsw',
+    required: true,
+    component: 'InputPassword',
+    componentProps: {
+      rules: [{ min: 6 }],
+      placeholder: '请重新输入新密码',
+    },
+    dynamicRules: ({ values }) => {
+      return [
+        {
+          required: true,
+          validator: (_, value) => {
+            if (!value) {
+              return Promise.reject('不能为空');
+            }
+            if (value !== values.newPsw) {
+              return Promise.reject('两次输入的密码不一致!');
+            }
+            return Promise.resolve();
+          },
+        },
+      ];
+    },
+  },
+];

+ 0 - 132
src/views/sys/account/center/data.tsx

@@ -1,132 +0,0 @@
-export interface ListItem {
-  title: string;
-  icon: string;
-  color?: string;
-}
-
-export interface TabItem {
-  key: string;
-  name: string;
-  component: string;
-}
-
-export const tags: string[] = [
-  '很有想法的',
-  '专注设计',
-  '川妹子',
-  '大长腿',
-  '海纳百川',
-  '前端开发',
-  'vue3',
-];
-<span class="iconify" data-icon="jam:codepen-circle" data-inline="false"></span>;
-export const teams: ListItem[] = [
-  {
-    icon: 'ri:alipay-fill',
-    title: '科学搬砖组',
-    color: '#ff4000',
-  },
-  {
-    icon: 'emojione-monotone:letter-a',
-    title: '中二少年团',
-    color: '#7c51b8',
-  },
-  {
-    icon: 'ri:alipay-fill',
-    title: '高逼格设计',
-    color: '#00adf7',
-  },
-  {
-    icon: 'jam:codepen-circle',
-    title: '程序员日常',
-    color: '#00adf7',
-  },
-  {
-    icon: 'fa:behance-square',
-    title: '科学搬砖组',
-    color: '#7c51b8',
-  },
-  {
-    icon: 'jam:codepen-circle',
-    title: '程序员日常',
-    color: '#ff4000',
-  },
-];
-
-export const details: ListItem[] = [
-  {
-    icon: 'ic:outline-contacts',
-    title: '交互专家',
-  },
-  {
-    icon: 'grommet-icons:cluster',
-    title: '某某某事业群',
-  },
-  {
-    icon: 'bx:bx-home-circle',
-    title: '福建省厦门市',
-  },
-];
-
-export const achieveList: TabItem[] = [
-  {
-    key: '1',
-    name: '文章',
-    component: 'Article',
-  },
-  {
-    key: '2',
-    name: '应用',
-    component: 'Application',
-  },
-  {
-    key: '3',
-    name: '项目',
-    component: 'Project',
-  },
-];
-
-export const actions: any[] = [
-  { icon: 'clarity:star-line', text: '156', color: '#018ffb' },
-  { icon: 'bx:bxs-like', text: '156', color: '#459ae8' },
-  { icon: 'bx:bxs-message-dots', text: '2', color: '#42d27d' },
-];
-
-export const articleList = (() => {
-  const result: any[] = [];
-  for (let i = 0; i < 4; i++) {
-    result.push({
-      title: 'Vben Admin',
-      description: ['Vben', '设计语言', 'Typescript'],
-      content: '基于Vue Next, TypeScript, Ant Design实现的一套完整的企业级后台管理系统。',
-      time: '2020-11-14 11:20',
-    });
-  }
-  return result;
-})();
-
-export const applicationList = (() => {
-  const result: any[] = [];
-  for (let i = 0; i < 8; i++) {
-    result.push({
-      title: 'Vben Admin',
-      icon: 'emojione-monotone:letter-a',
-      color: '#1890ff',
-      active: '100',
-      new: '1,799',
-      download: 'bx:bx-download',
-    });
-  }
-  return result;
-})();
-
-export const projectList = (() => {
-  const result: any[] = [];
-  for (let i = 0; i < 8; i++) {
-    result.push({
-      title: 'Vben Admin',
-      content: '基于Vue Next, TypeScript, Ant Design实现的一套完整的企业级后台管理系统。',
-    });
-  }
-  return result;
-})();

+ 65 - 0
src/views/sys/account/center/editPws.vue

@@ -0,0 +1,65 @@
+<template>
+  <div>
+    <BasicForm @register="registerForm" layout="vertical" />
+    <a-button @click="handleReset">重置</a-button>
+    <a-button type="primary" @click="handleSubmit">保存</a-button>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { BasicForm, useForm } from '/@/components/Form';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { pswFormSchema } from './data';
+  // import { Upload } from 'ant-design-vue';
+  import { userAccountInfo, editPsw } from '/@/api/sys/userAccountApi';
+  import { onMounted, ref } from 'vue';
+  const id = ref('');
+  // const errorMsg = ref(null);
+  onMounted(async () => {
+    const res = await userAccountInfo();
+    console.log('res::::::::::::', res.basicInfo.org.id);
+    id.value = res.basicInfo.org.id;
+    await setFieldsValue({ ...res.basicInfo });
+  });
+  const { createMessage } = useMessage();
+  const [registerForm, { setFieldsValue, validate }] = useForm({
+    labelWidth: 120,
+    schemas: pswFormSchema,
+    showActionButtonGroup: false,
+    actionColOptions: {
+      span: 23,
+    },
+    baseColProps: {
+      span: 18,
+    },
+    wrapperCol: {
+      span: 24,
+    },
+  });
+  // 提交按钮事件
+  async function handleSubmit() {
+    const values = await validate();
+    console.log('abc', values);
+    values.id = id.value;
+    try {
+      await editPsw(values);
+      createMessage.success('修改成功');
+    } catch (err) {
+      console.log('error', err);
+      // console.log('Error', );
+    }
+  }
+  async function handleReset() {
+    const res = await userAccountInfo();
+
+    await setFieldsValue(res);
+  }
+</script>
+
+<style lang="less" scoped>
+  .img-avatar {
+    display: block;
+    width: 60px;
+    height: 60px;
+  }
+</style>

+ 62 - 147
src/views/sys/account/center/index.vue

@@ -1,155 +1,70 @@
 <template>
-  <div :class="prefixCls">
-    <a-row :class="`${prefixCls}-top`">
-      <a-col :span="9" :class="`${prefixCls}-col`">
-        <a-row>
-          <a-col :span="8">
-            <div :class="`${prefixCls}-top__avatar`">
-              <img width="70" :src="avatar" />
-              <span>Vben</span>
-              <div>海纳百川,有容乃大</div>
-            </div>
-          </a-col>
-          <a-col :span="16">
-            <div :class="`${prefixCls}-top__detail`">
-              <template v-for="detail in details" :key="detail.title">
-                <p>
-                  <Icon :icon="detail.icon" />
-                  {{ detail.title }}
-                </p>
-              </template>
-            </div>
-          </a-col>
-        </a-row>
-      </a-col>
-      <a-col :span="7" :class="`${prefixCls}-col`">
-        <CollapseContainer title="标签" :canExpan="false">
-          <template v-for="tag in tags" :key="tag">
-            <Tag class="mb-2">
-              {{ tag }}
-            </Tag>
-          </template>
-        </CollapseContainer>
-      </a-col>
-      <a-col :span="8" :class="`${prefixCls}-col`">
-        <CollapseContainer :class="`${prefixCls}-top__team`" title="团队" :canExpan="false">
-          <div v-for="(team, index) in teams" :key="index" :class="`${prefixCls}-top__team-item`">
-            <Icon :icon="team.icon" :color="team.color" />
-            <span>{{ team.title }}</span>
-          </div>
-        </CollapseContainer>
-      </a-col>
-    </a-row>
-    <div :class="`${prefixCls}-bottom`">
-      <Tabs>
-        <template v-for="item in achieveList" :key="item.key">
-          <TabPane :tab="item.name">
-            <component :is="item.component" />
-          </TabPane>
-        </template>
-      </Tabs>
-    </div>
-  </div>
+  <PageWrapper dense contentFullHeight contentClass="flex">
+    <a-card class="w-1/2 xl:w-1/2">
+      <List>
+        <h1>11111</h1>
+        <ListItem>11111</ListItem>
+        <ListItem>22222</ListItem>
+        <ListItem>33333</ListItem>
+        <ListItem>44444</ListItem>
+      </List>
+    </a-card>
+    <a-card
+      class="w-1/2 xl:w-1/2"
+      :active-tab-key="noTitleKey"
+      :tab-list="tabListNoTitle"
+      @tabChange="key => onTabChange(key, 'noTitleKey')"
+    >
+      <p v-if="noTitleKey === 'basicInformation'">
+        <basicInformation />
+      </p>
+      <p v-if="noTitleKey === 'editPws'">
+        <editPws />
+      </p>
+      <p v-if="noTitleKey === 'socialContact'">
+        <socialContact />
+      </p>
+    </a-card>
+  </PageWrapper>
 </template>
 
-<script lang="ts">
-  import { Tag, Tabs, Row, Col } from 'ant-design-vue';
-  import { defineComponent, computed } from 'vue';
-  import { CollapseContainer } from '/@/components/Container/index';
-  import Icon from '/@/components/Icon/index';
-  import Article from './Article.vue';
-  import Application from './Application.vue';
-  import Project from './Project.vue';
+<script setup lang="ts">
+  import { ref } from 'vue';
+  import { List, ListItem } from 'ant-design-vue';
+  import { PageWrapper } from '/@/components/Page';
+  // import { userAccountInfo } from '/@/api/sys/userAccountApi';
+  import basicInformation from './basicInformation.vue';
+  import editPws from './editPws.vue';
+  import socialContact from './socialContact.vue';
+  // onMounted(async () => {
+  //   const res = await userAccountInfo();
+  //   console.log(res);
+  // });
 
-  import headerImg from '/@/assets/images/header.png';
-  import { tags, teams, details, achieveList } from './data';
-  import { useUserStore } from '/@/store/modules/user';
-
-  export default defineComponent({
-    components: {
-      CollapseContainer,
-      Icon,
-      Tag,
-      Tabs,
-      TabPane: Tabs.TabPane,
-      Article,
-      Application,
-      Project,
-      [Row.name]: Row,
-      [Col.name]: Col,
+  const key = ref('basicInformation');
+  const noTitleKey = ref('basicInformation');
+  // :tab-list="tabListNoTitle"
+  const tabListNoTitle = [
+    {
+      key: 'basicInformation',
+      tab: '基本资料',
     },
-    setup() {
-      const userStore = useUserStore();
-      const avatar = computed(() => userStore.getUserInfo.avatar || headerImg);
-      return {
-        prefixCls: 'account-center',
-        avatar,
-        tags,
-        teams,
-        details,
-        achieveList,
-      };
+    {
+      key: 'editPws',
+      tab: '修改密码',
     },
-  });
-</script>
-<style lang="less" scoped>
-  .account-center {
-    &-col:not(:last-child) {
-      padding: 0 10px;
-
-      &:not(:last-child) {
-        border-right: 1px dashed rgb(206, 206, 206, 0.5);
-      }
-    }
-
-    &-top {
-      padding: 10px;
-      margin: 16px 16px 12px 16px;
-      background-color: @component-background;
-      border-radius: 3px;
-
-      &__avatar {
-        text-align: center;
-
-        img {
-          margin: auto;
-          border-radius: 50%;
-        }
-
-        span {
-          display: block;
-          font-size: 20px;
-          font-weight: 500;
-        }
-
-        div {
-          margin-top: 3px;
-          font-size: 12px;
-        }
-      }
-
-      &__detail {
-        padding-left: 20px;
-        margin-top: 15px;
-      }
-
-      &__team {
-        &-item {
-          display: inline-block;
-          padding: 4px 24px;
-        }
-
-        span {
-          margin-left: 3px;
-        }
-      }
-    }
+    {
+      key: 'socialContact',
+      tab: '社交信息',
+    },
+  ];
 
-    &-bottom {
-      padding: 10px;
-      margin: 0 16px 16px 16px;
-      background-color: @component-background;
-      border-radius: 3px;
+  const onTabChange = (value, type) => {
+    if (type === 'key') {
+      key.value = value;
+    } else if (type === 'noTitleKey') {
+      noTitleKey.value = value;
     }
-  }
-</style>
+  };
+</script>
+<style lang="less"></style>

+ 80 - 0
src/views/sys/account/center/socialContact.vue

@@ -0,0 +1,80 @@
+<template>
+  <div>
+    <BasicForm @register="registerForm" layout="vertical">
+      <template #logo>
+        <Upload
+          name="file"
+          :showUploadList="false"
+          :beforeUpload="handleBeforeUpload"
+          accept=".jpg,.jpeg,.gif,.png,.webp"
+        >
+          <img :src="logo" class="img-avatar" />
+        </Upload>
+      </template>
+    </BasicForm>
+    <a-button @click="handleReset">重置</a-button>
+    <a-button type="primary" @click="handleSubmit">保存</a-button>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { BasicForm, useForm } from '/@/components/Form';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { InformationFormSchema } from './data';
+  import { Upload } from 'ant-design-vue';
+  import { sysSettingEdit, sysSettingDetail, sysSettingDefault } from '/@/api/sys/sysSettingApi';
+  import { onMounted, ref } from 'vue';
+  import { fileToBase64 } from '/@/utils/file/base64Conver';
+
+  onMounted(async () => {
+    const res = await sysSettingDetail();
+    logo.value = res.logo;
+    await setFieldsValue({ ...res });
+  });
+
+  const { createMessage } = useMessage();
+  const [registerForm, { setFieldsValue, validate }] = useForm({
+    labelWidth: 120,
+    schemas: InformationFormSchema,
+    showActionButtonGroup: false,
+    actionColOptions: {
+      span: 23,
+    },
+    baseColProps: {
+      span: 18,
+    },
+    wrapperCol: {
+      span: 24,
+    },
+  });
+
+  const logo = ref(null);
+
+  // 提交按钮事件
+  async function handleSubmit() {
+    const values = await validate();
+    console.log('abc', values);
+    if (logo.value) {
+      values.logo = logo.value;
+    }
+    await sysSettingEdit(values);
+    createMessage.success('修改成功');
+  }
+  async function handleReset() {
+    const res = await sysSettingDefault();
+
+    await setFieldsValue(res);
+  }
+  async function handleBeforeUpload(file) {
+    logo.value = await fileToBase64(file);
+    return false;
+  }
+</script>
+
+<style lang="less" scoped>
+  .img-avatar {
+    display: block;
+    width: 60px;
+    height: 60px;
+  }
+</style>