【愚公系列】2023年03月 WMS智能仓储系统-014.基础设置(菜单设置、用户管理、商品类别设置)

举报
愚公搬代码 发表于 2023/03/30 22:07:51 2023/03/30
【摘要】 前言基础设置主要分为以下几个模块:首页公司信息角色设置菜单设置用户管理商品类别设置商品管理供应商信息仓库设置货主信息运费设置客户信息 一、基础设置 1.菜单设置这边菜单是写死的,因为只是WMS需要的不多。 1.1 页面代码1、主页面代码<template> <div class="container"> <div> <!-- Main Content --> <...

前言

基础设置主要分为以下几个模块:

  • 首页
  • 公司信息
  • 角色设置
  • 菜单设置
  • 用户管理
  • 商品类别设置
  • 商品管理
  • 供应商信息
  • 仓库设置
  • 货主信息
  • 运费设置
  • 客户信息

image.png

一、基础设置

1.菜单设置

image.png

这边菜单是写死的,因为只是WMS需要的不多。
image.png

1.1 页面代码

1、主页面代码

<template>
  <div class="container">
    <div>
      <!-- Main Content -->
      <v-card class="mt-5">
        <v-card-text>
          <div class="operateArea">
            <v-row no-gutters>
              <!-- Operate Btn -->
              <v-col cols="12" sm="3" class="col">
                <tooltip-btn icon="mdi-plus" :tooltip-text="$t('system.page.add')" @click="method.add()"></tooltip-btn>
                <tooltip-btn icon="mdi-pencil-outline" :tooltip-text="$t('system.page.edit')" @click="method.editForm()"></tooltip-btn>
                <tooltip-btn icon="mdi-delete-outline" :tooltip-text="$t('system.page.delete')" @click="method.deleteForm()"></tooltip-btn>
                <tooltip-btn icon="mdi-refresh" :tooltip-text="$t('system.page.refresh')" @click="method.refresh()"></tooltip-btn>
                <!-- <tooltip-btn icon="mdi-export-variant" :tooltip-text="$t('system.page.export')" @click="method.exportTable"></tooltip-btn> -->
              </v-col>

              <!-- Search Input -->
              <v-col cols="12" sm="9">
                <!-- <v-row no-gutters @keyup.enter="method.sureSearch">
                  <v-col cols="12" sm="4">
                    <v-text-field
                      v-model="data.searchForm.userName"
                      clearable
                      hide-details
                      density="comfortable"
                      class="searchInput ml-5 mt-1"
                      :label="$t('login.userName')"
                      variant="solo"
                    >
                    </v-text-field>
                  </v-col>
                  <v-col cols="12" sm="4">
                    <v-text-field
                      v-model="data.searchForm.userName1"
                      clearable
                      hide-details
                      density="comfortable"
                      class="searchInput ml-5 mt-1"
                      :label="$t('login.userName')"
                      variant="solo"
                    >
                    </v-text-field>
                  </v-col>
                  <v-col cols="12" sm="4">
                    <v-text-field
                      v-model="data.searchForm.userName2"
                      clearable
                      hide-details
                      density="comfortable"
                      class="searchInput ml-5 mt-1"
                      :label="$t('login.userName')"
                      variant="solo"
                    >
                    </v-text-field>
                  </v-col>
                </v-row> -->
              </v-col>
            </v-row>
          </div>

          <!-- Table -->
          <div
            class="mt-5"
            :style="{
              height: cardHeight
            }"
          >
            <v-row :no-gutters="true">
              <v-col :cols="3" class="dataListCol">
                <v-card :height="tableHeight">
                  <NavListVue
                    :list-data="data.roleList"
                    :title="data.navListOptions.title"
                    :label-key="data.navListOptions.labelKey"
                    :index-key="data.navListOptions.indexKey"
                    :index-value="data.navListOptions.indexValue"
                    @item-click="method.navListClick"
                  />
                </v-card>
              </v-col>
              <v-col :cols="9">
                <vxe-table ref="xTable" :data="data.activeRoleMenuForm.detailList" :height="tableHeight" align="center">
                  <template #empty>
                    {{ i18n.global.t('system.page.noData') }}
                  </template>
                  <vxe-column type="seq" width="60"></vxe-column>
                  <vxe-column field="menu_name" :title="$t('base.roleMenu.menu_name')">
                    <template #default="{ row }">
                      <span>{{ $t(`router.sideBar.${row.menu_name}`) }}</span>
                    </template>
                  </vxe-column>
                </vxe-table>
              </v-col>
            </v-row>
          </div>
        </v-card-text>
      </v-card>
    </div>
    <!-- Add or modify data mode window -->
    <addOrUpdateDialog :show-dialog="data.showDialog" :form="data.dialogForm" @close="method.closeDialog" @saveSuccess="method.saveSuccess" />
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive, onMounted, ref } from 'vue'
import { computedCardHeight, computedTableHeight } from '@/constant/style'
import tooltipBtn from '@/components/tooltip-btn.vue'
import { DataProps, RoleMenuVO } from '@/types/Base/RoleMenu'
import { getRoleMenuAll, getRoleMenuById, deleteRoleMenu } from '@/api/base/roleMenu'
import { hookComponent } from '@/components/system'
import addOrUpdateDialog from './add-or-update-role-menu.vue'
import i18n from '@/languages/i18n'
import NavListVue from '@/components/page/nav-list.vue'
import { exportData } from '@/utils/exportTable'

const xTable = ref()

const data: DataProps = reactive({
  navListOptions: {
    title: i18n.global.t('base.roleMenu.role_name'),
    labelKey: 'role_name',
    indexKey: 'userrole_id',
    indexValue: ''
  },
  // Activation id
  activeRoleMenuForm: {
    userrole_id: 0,
    role_name: '',
    detailList: []
  },
  // searchForm: {
  //   userName: '',
  //   userName1: '',
  //   userName2: ''
  // },
  roleList: [],
  // Dialog info
  showDialog: false,
  dialogForm: {
    detailList: []
  }
})

const method = reactive({
  sureSearch: () => {
    // console.log(data.searchForm)
  },
  // Find Data by Pagination
  getCompanyList: async () => {
    // Clear detailed data before refreshing
    method.clearDialogForm()
    const { data: res } = await getRoleMenuAll()
    if (!res.isSuccess) {
      hookComponent.$message({
        type: 'error',
        content: res.errorMessage
      })
      return
    }
    data.roleList = res.data
    if (data.roleList.findIndex((item) => item.userrole_id === data.activeRoleMenuForm.userrole_id) > -1 && data.activeRoleMenuForm.userrole_id) {
      method.getRoleMenus(data.activeRoleMenuForm.userrole_id)
    } else if (data.roleList.length > 0) {
      method.navListClick(data.roleList[0])
    } else {
      data.activeRoleMenuForm = {
        userrole_id: 0,
        role_name: '',
        detailList: []
      }
    }
  },
  // Add user
  add: () => {
    method.clearDialogForm()
    data.showDialog = true
  },
  // Shut add or update dialog
  closeDialog: () => {
    data.showDialog = false
  },
  // after Add or update success.
  saveSuccess: () => {
    method.refresh()
    method.closeDialog()
  },
  // Refresh data
  refresh: () => {
    method.getCompanyList()
  },
  editForm() {
    if (!data.activeRoleMenuForm.userrole_id) {
      hookComponent.$message({
        type: 'error',
        content: i18n.global.t('base.roleMenu.beforeUpdateOrDel')
      })
      return
    }
    data.dialogForm = JSON.parse(JSON.stringify(data.activeRoleMenuForm))
    // Delete rowid of existing data
    for (const item of data.dialogForm.detailList) {
      if (item._X_ROW_KEY) {
        delete item._X_ROW_KEY
      }
    }
    data.showDialog = true
  },
  deleteForm() {
    if (!data.activeRoleMenuForm.userrole_id) {
      hookComponent.$message({
        type: 'error',
        content: i18n.global.t('base.roleMenu.beforeUpdateOrDel')
      })
      return
    }
    const row = data.activeRoleMenuForm
    hookComponent.$dialog({
      content: i18n.global.t('system.tips.beforeDeleteMessage'),
      handleConfirm: async () => {
        if (row.userrole_id) {
          const { data: res } = await deleteRoleMenu(row.userrole_id)
          if (!res.isSuccess) {
            hookComponent.$message({
              type: 'error',
              content: res.errorMessage
            })
            return
          }
          hookComponent.$message({
            type: 'success',
            content: `${ i18n.global.t('system.page.delete') }${ i18n.global.t('system.tips.success') }`
          })
          method.refresh()
        }
      }
    })
  },
  // Export table
  exportTable: () => {
    const $table = xTable.value
    exportData({
      table: $table,
      filename: i18n.global.t('router.sideBar.roleMenu'),
      columnFilterMethod({ column }: any) {
        return !['checkbox'].includes(column?.type) && !['operate'].includes(column?.field)
      }
    })
  },
  // Get detailed data
  getRoleMenus: async (userrole_id: number) => {
    const { data: res } = await getRoleMenuById(userrole_id)
    if (!res.isSuccess) {
      hookComponent.$message({
        type: 'error',
        content: res.errorMessage
      })
      return
    }
    data.activeRoleMenuForm = res.data
  },
  // Refresh dialog data
  clearDialogForm: () => {
    data.dialogForm = {
      detailList: []
    }
  },
  // Click navList
  navListClick: (item: RoleMenuVO) => {
    if (!item.userrole_id) {
      return
    }
    data.navListOptions.indexValue = String(item.userrole_id)
    method.getRoleMenus(item.userrole_id)
  }
})

onMounted(async () => {
  await method.getCompanyList()
})

const cardHeight = computed(() => computedCardHeight({ hasTab: false }))

const tableHeight = computed(() => computedTableHeight({ hasTab: false, hasPager: false }))
</script>

<style scoped lang="less">
.operateArea {
  width: 100%;
  min-width: 760px;
  display: flex;
  align-items: center;
  border-radius: 10px;
  padding: 0 10px;
}

.col {
  display: flex;
  align-items: center;
}
// Adjust the spacing between lists and tables
.dataListCol {
  box-sizing: border-box;
  padding-right: 10px !important;
}
.roleNameCol {
  width: 100%;
  height: 100%;
  cursor: pointer;
  // &:hover: {
  //   background-color: #9156fd;
  // }
}
.roleNameCol:hover {
  background-color: #9156fd;
  color: white;
}
.activeRow {
  background-color: #9156fd;
}
</style>

image.png

1.2 接口代码

/// <summary>
/// rolemenu controller
/// </summary>
[Route("rolemenu")]
[ApiController]
[ApiExplorerSettings(GroupName = "Base")]
public class RolemenuController : BaseController
{
    #region Args

    /// <summary>
    /// rolemenu Service
    /// </summary>
    private readonly IRolemenuService _rolemenuService;

    /// <summary>
    /// Localizer Service
    /// </summary>
    private readonly IStringLocalizer<ModernWMS.Core.MultiLanguage> _stringLocalizer;
    #endregion

    #region constructor
    /// <summary>
    /// constructor
    /// </summary>
    /// <param name="rolemenuService">rolemenu Service</param>
    /// <param name="stringLocalizer">Localizer</param>
    public RolemenuController(
        IRolemenuService rolemenuService
      , IStringLocalizer<ModernWMS.Core.MultiLanguage> stringLocalizer
        )
    {
        this._rolemenuService = rolemenuService;
        this._stringLocalizer = stringLocalizer;
    }
    #endregion

    #region Api
    /// <summary>
    /// 通过角色ID获取菜单
    /// </summary>
    /// <param name="userrole_id">user role id</param>
    /// <returns></returns>
    [HttpGet("authority")]
    public async  Task<ResultModel<List<MenuViewModel>>> GetMenusByRoleId(int userrole_id)
    {
        var data = await _rolemenuService.GetMenusByRoleId(userrole_id);
        if (data.Any())
        {
            return ResultModel<List<MenuViewModel>>.Success(data);
        }
        else
        {
            return ResultModel<List<MenuViewModel>>.Success(new List<MenuViewModel>());
        }
    }
    /// <summary>
    /// get all records
    /// </summary>
    /// <returns>args</returns>
    [HttpGet("all")]
    public async Task<ResultModel<List<RolemenuListViewModel>>> GetAllAsync()
    {
        var data = await _rolemenuService.GetAllAsync(CurrentUser);
        if (data.Any())
        {
            return ResultModel<List<RolemenuListViewModel>>.Success(data);
        }
        else
        {
            return ResultModel<List<RolemenuListViewModel>>.Success(new List<RolemenuListViewModel>());
        }
    }
    /// <summary>
    /// Get all menus
    /// </summary>
    /// <returns></returns>
    [HttpGet("menus")]
    public async Task<ResultModel<List<MenuViewModel>>> GetAllMenusAsync()
    {
        var data = await _rolemenuService.GetAllMenusAsync(CurrentUser);
        if (data.Any())
        {
            return ResultModel<List<MenuViewModel>>.Success(data);
        }
        else
        {
            return ResultModel<List<MenuViewModel>>.Success(new List<MenuViewModel>());
        }
    }
    /// <summary>
    /// get a record by id
    /// </summary>
    /// <returns>args</returns>
    [HttpGet]
    public async Task<ResultModel<RolemenuBothViewModel>> GetAsync(int userrole_id)
    {
        var data = await _rolemenuService.GetAsync(userrole_id);
        if (data != null && data.userrole_id > 0)
        {
            return ResultModel<RolemenuBothViewModel>.Success(data);
        }
        else
        {
            return ResultModel<RolemenuBothViewModel>.Error(_stringLocalizer["not_exists_entity"]);
        }
    }
    /// <summary>
    /// add a new record
    /// </summary>
    /// <param name="viewModel">args</param>
    /// <returns></returns>
    [HttpPost]
    public async Task<ResultModel<int>> AddAsync(RolemenuBothViewModel viewModel)
    {
        var (id, msg) = await _rolemenuService.AddAsync(viewModel, CurrentUser);
        if (id > 0)
        {
            return ResultModel<int>.Success(id);
        }
        else
        {
            return ResultModel<int>.Error(msg);
        }
    }

    /// <summary>
    /// update a record
    /// </summary>
    /// <param name="viewModel">args</param>
    /// <returns></returns>
    [HttpPut]
    public async Task<ResultModel<bool>> UpdateAsync(RolemenuBothViewModel viewModel)
    {
        var (flag, msg) = await _rolemenuService.UpdateAsync(viewModel, CurrentUser);
        if (flag)
        {
            return ResultModel<bool>.Success(flag);
        }
        else
        {
            return ResultModel<bool>.Error(msg, 400, flag);
        }
    }

    /// <summary>
    /// delete a record
    /// </summary>
    /// <param name="userrole_id">userrole id</param>
    /// <returns></returns>
    [HttpDelete]
    public async Task<ResultModel<string>> DeleteAsync(int userrole_id)
    {
        var (flag, msg) = await _rolemenuService.DeleteAsync(userrole_id);
        if (flag)
        {
            return ResultModel<string>.Success(msg);
        }
        else
        {
            return ResultModel<string>.Error(msg);
        }
    }
    #endregion

}

image.png

2.用户管理

image.png

2.2 接口代码

[Route("user")]
[ApiController]
[ApiExplorerSettings(GroupName = "Base")]
public class UserController : BaseController
{
    #region Args

    /// <summary>
    /// user Service
    /// </summary>
    private readonly IUserService _userService;

    /// <summary>
    /// Localizer Service
    /// </summary>
    private readonly IStringLocalizer<ModernWMS.Core.MultiLanguage> _stringLocalizer;
    #endregion

    #region constructor
    /// <summary>
    /// constructor
    /// </summary>
    /// <param name="userService">user Service</param>
    /// <param name="stringLocalizer">Localizer</param>
    public UserController(
         IUserService userService
       , IStringLocalizer<ModernWMS.Core.MultiLanguage> stringLocalizer
         )
    {
        this._userService = userService;
        this._stringLocalizer = stringLocalizer;
    }
    #endregion

    #region Api
    /// <summary>
    /// get select items
    /// </summary>
    /// <returns></returns>
    [HttpGet("select-item")]
    public async Task<ResultModel<List<FormSelectItem>>> GetSelectItemsAsnyc()
    {
        var datas = await _userService.GetSelectItemsAsnyc(CurrentUser);
        return ResultModel<List<FormSelectItem>>.Success(datas);
    }
    /// <summary>
    /// page search
    /// </summary>
    /// <param name="pageSearch">args</param>
    /// <returns></returns>
    [HttpPost("list")]
    public async Task<ResultModel<PageData<UserViewModel>>> PageAsync(PageSearch pageSearch)
    {
        var (data, totals) = await _userService.PageAsync(pageSearch, CurrentUser);

        return ResultModel<PageData<UserViewModel>>.Success(new PageData<UserViewModel>
        {
            Rows = data,
            Totals = totals
        });
    }

    /// <summary>
    /// Get all records
    /// </summary>
    /// <returns>args</returns>
    [HttpGet("all")]
    public async Task<ResultModel<List<UserViewModel>>> GetAllAsync()
    {
        var data = await _userService.GetAllAsync(CurrentUser);
        if (data.Any())
        {
            return ResultModel<List<UserViewModel>>.Success(data);
        }
        else
        {
            return ResultModel<List<UserViewModel>>.Success(new List<UserViewModel>());
        }
    }

    /// <summary>
    /// Get a record by id
    /// </summary>
    /// <returns>args</returns>
    [HttpGet]
    public async Task<ResultModel<UserViewModel>> GetAsync(int id)
    {
        var data = await _userService.GetAsync(id);
        if (data != null)
        {
            return ResultModel<UserViewModel>.Success(data);
        }
        else
        {
            return ResultModel<UserViewModel>.Error(_stringLocalizer["not_exists_entity"]);
        }
    }
    /// <summary>
    /// add a new record
    /// </summary>
    /// <param name="viewModel">args</param>
    /// <returns></returns>
    [HttpPost]
    public async Task<ResultModel<int>> AddAsync(UserViewModel viewModel)
    {
        viewModel.creator = CurrentUser.user_name;
        var (id, msg) = await _userService.AddAsync(viewModel, CurrentUser);
        if (id > 0)
        {
            return ResultModel<int>.Success(id);
        }
        else
        {
            return ResultModel<int>.Error(msg);
        }
    }
    /// <summary>
    /// 注册功能实现
    /// </summary>
    /// <param name="viewModel">args</param>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpPost("register")]
    public async Task<ResultModel<string>> Register(RegisterViewModel viewModel)
    {
        var (flag, msg) = await _userService.Register(viewModel);
        if (flag)
        {
            return ResultModel<string>.Success(msg);
        }
        else
        {
            return ResultModel<string>.Error(msg);
        }
    }
    /// <summary>
    /// import users by excel
    /// </summary>
    /// <param name="excel_datas">excel datas</param>
    /// <returns></returns>
    [HttpPost("excel")]
    public async Task<ResultModel<string>> ExcelAsync(List<UserExcelImportViewModel> excel_datas)
    {
        var (flag, msg) = await _userService.ExcelAsync(excel_datas, CurrentUser);
        if (flag)
        {
            return ResultModel<string>.Success(msg);
        }
        else
        {
            return ResultModel<string>.Error(msg);
        }
    }
    /// <summary>
    /// update a record
    /// </summary>
    /// <param name="viewModel">args</param>
    /// <returns></returns>
    [HttpPut]
    public async Task<ResultModel<bool>> UpdateAsync(UserViewModel viewModel)
    {
        var (flag, msg) = await _userService.UpdateAsync(viewModel, CurrentUser);
        if (flag)
        {
            return ResultModel<bool>.Success(flag);
        }
        else
        {
            return ResultModel<bool>.Error(msg, 400, flag);
        }
    }

    /// <summary>
    /// delete a record
    /// </summary>
    /// <param name="id">id</param>
    /// <returns></returns>
    [HttpDelete]
    public async Task<ResultModel<string>> DeleteAsync(int id)
    {
        var (flag, msg) = await _userService.DeleteAsync(id);
        if (flag)
        {
            return ResultModel<string>.Success(msg);
        }
        else
        {
            return ResultModel<string>.Error(msg);
        }
    }
    /// <summary>
    /// reset password
    /// </summary>
    /// <param name="viewModel">viewmodel</param>
    /// <returns></returns>
    [HttpPost("reset-pwd")]
    public async Task<ResultModel<string>> ResetPwd(BatchOperationViewModel viewModel)
    {
        var (flag, msg) = await _userService.ResetPwd(viewModel);
        if (flag)
        {
            return ResultModel<string>.Success(msg);
        }
        else
        {
            return ResultModel<string>.Error(msg);
        }
    }
    /// <summary>
    /// change password
    /// </summary>
    /// <param name="viewModel">viewmodel</param>
    /// <returns></returns>
    [HttpPost("change-pwd")]
    public async Task<ResultModel<string>> ChangePwd(UserChangePwdViewModel viewModel)
    {
        var (flag, msg) = await _userService.ChangePwd(viewModel);
        if (flag)
        {
            return ResultModel<string>.Success(msg);
        }
        else
        {
            return ResultModel<string>.Error(msg);
        }
    }
    #endregion

}

image.png

3.商品类别设置

image.png

3.1 页面代码

1、主页面代码

image.png

2、窗体代码

image.png

3.2 接口代码

    [Route("category")]
    [ApiController]
    [ApiExplorerSettings(GroupName = "Base")]
    public class CategoryController : BaseController
    {
        #region Args

        /// <summary>
        /// category Service
        /// </summary>
        private readonly ICategoryService _categoryService;

        /// <summary>
        /// Localizer Service
        /// </summary>
        private readonly IStringLocalizer<ModernWMS.Core.MultiLanguage> _stringLocalizer;
        #endregion

        #region constructor
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="categoryService">category Service</param>
        /// <param name="stringLocalizer">Localizer</param>
        public CategoryController(
            ICategoryService categoryService
          , IStringLocalizer<ModernWMS.Core.MultiLanguage> stringLocalizer
            )
        {
            this._categoryService = categoryService;
            this._stringLocalizer = stringLocalizer;
        }
        #endregion

        #region Api
        /// <summary>
        /// get all records
        /// </summary>
        /// <returns>args</returns>
        [HttpGet("all")]
        public async Task<ResultModel<List<CategoryViewModel>>> GetAllAsync()
        {
            var data = await _categoryService.GetAllAsync(CurrentUser);
            if (data.Any())
            {
                return ResultModel<List<CategoryViewModel>>.Success(data);
            }
            else
            {
                return ResultModel<List<CategoryViewModel>>.Success(new List<CategoryViewModel>());
            }
        }

        /// <summary>
        /// get a record by id
        /// </summary>
        /// <returns>args</returns>
        [HttpGet]
        public async Task<ResultModel<CategoryViewModel>> GetAsync(int id)
        {
            var data = await _categoryService.GetAsync(id);
            if (data != null)
            {
                return ResultModel<CategoryViewModel>.Success(data);
            }
            else
            {
                return ResultModel<CategoryViewModel>.Error(_stringLocalizer["not_exists_entity"]);
            }
        }
        /// <summary>
        /// add a new record
        /// </summary>
        /// <param name="viewModel">args</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultModel<int>> AddAsync(CategoryViewModel viewModel)
        {
            var (id, msg) = await _categoryService.AddAsync(viewModel, CurrentUser);
            if (id > 0)
            {
                return ResultModel<int>.Success(id);
            }
            else
            {
                return ResultModel<int>.Error(msg);
            }
        }

        /// <summary>
        /// update a record
        /// </summary>
        /// <param name="viewModel">args</param>
        /// <returns></returns>
        [HttpPut]
        public async Task<ResultModel<bool>> UpdateAsync(CategoryViewModel viewModel)
        {
            var (flag, msg) = await _categoryService.UpdateAsync(viewModel);
            if (flag)
            {
                return ResultModel<bool>.Success(flag);
            }
            else
            {
                return ResultModel<bool>.Error(msg, 400, flag);
            }
        }

        /// <summary>
        /// delete a record
        /// </summary>
        /// <param name="id">id</param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<ResultModel<string>> DeleteAsync(int id)
        {
            var (flag, msg) = await _categoryService.DeleteAsync(id);
            if (flag)
            {
                return ResultModel<string>.Success(msg);
            }
            else
            {
                return ResultModel<string>.Error(msg);
            }
        }
        #endregion

    }

image.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。