Compare commits

...

52 Commits

Author SHA1 Message Date
ccongli 48f9bdca7c Merge branch 'contract'
1 year ago
ccongli e08e65995f 前端项目修正初始化-2
1 year ago
ccongli 76d9a8bf86 前端项目修正初始化-1
1 year ago
ccongli 29d30c5581 前端项目修正初始化-1
1 year ago
ccongli 45a8e573e0 合同基础、详情信息业务开发v3
1 year ago
杨世强 42020ecc7b 1
1 year ago
杨世强 599015f6c1 Merge branch 'master' into ysq-dev-0811
1 year ago
qiuhongwu e320886ff7 Merge branch 'qhw-dev-1010'
1 year ago
qiuhongwu e955c98eab 企业中心业务组织配置
1 year ago
ccongli a5a703479a 合同基础、详情信息业务开发v2
1 year ago
杨世强 39135c13a8 Merge branch 'master' into ysq-dev-0811
1 year ago
杨世强 cbafb07278 部门列表
1 year ago
ccongli c79db68acb 合同基础、详情信息业务开发v1
1 year ago
17602169347 615a86d50a 个人中心提交
1 year ago
17602169347 2c16788d8f 代码提交
1 year ago
ccongli 39ad4dfb72 忽略文件更新
1 year ago
杨世强 f19083e8a7 Merge branch 'master' of http://222.71.165.188:3000/linkage/YX-SCM
1 year ago
杨世强 0350cdae6b 部门列表
1 year ago
qiuhongwu ba7c34ac0e ijiao
1 year ago
杨世强 d1ce48e28b Merge branch 'ysq-dev-0811'
1 year ago
杨世强 f95b8abb5d 部门树状列表
1 year ago
qiuhongwu 98a0015579 Merge branch 'master' of http://222.71.165.188:3000/linkage/YX-SCM
1 year ago
qiuhongwu e566c2bac7 11
1 year ago
mhsnet add9532e04 分支机构功能
1 year ago
杨世强 ccc73b1696 部门列表
1 year ago
ccongli 19a3825c62 前端项目名称变更
1 year ago
杨世强 d19160843e 部门人员信息
1 year ago
LI-CCONG\李聪聪 6d37489385 Merge branch 'ccongli-dev-0920'
1 year ago
huchuanhu 68f2af1d49 个人中心
1 year ago
tengxi 7fa223db42 后端个人加字段,个人设置提交
1 year ago
mhsnet dbc20379eb 企业信息静态页初始效果
1 year ago
杨世强 78f052b3ac Merge branch 'ysq-dev-0811'
1 year ago
杨世强 c31ed02f9b 业务组织配置
1 year ago
17602169347 c1f4520e85 客户供应商前端
1 year ago
mhsnet a871d77903 企业中心(基本信息|认证信息|分支机构|组织信息)
1 year ago
qiuhongwu 52df6c6b76 cun
1 year ago
17602169347 716df92a68 10.8权限和供应商和客户提交
1 year ago
qiuhongwu 1e104717cb Merge branch 'qhw-dev-0927'
1 year ago
qiuhongwu 43ea91d5f1 Merge branch 'master' of http://222.71.165.188:3000/linkage/YX-SCM
1 year ago
qiuhongwu 1ada243d7f ti
1 year ago
tengxi 5bb22e3c7a 新客户
1 year ago
tengxi 984d9b94a5 提交新客户管理
1 year ago
杨世强 7a83d4e067 Merge branch 'master' into ysq-dev-0811
1 year ago
杨世强 b517aec7d7 业务线修改
1 year ago
qiuhongwu fa8365f84e Merge branch 'qhw-dev-0927'
1 year ago
tengxi 30e63f041f Merge branch 'master' of http://222.71.165.188:3000/linkage/YX-SCM
1 year ago
tengxi 4ae74fe524 客户
1 year ago
LI-CCONG\李聪聪 9d8fa16a10 测试环境配置更新
1 year ago
杨世强 0edbecba34 业务线
1 year ago
tengxi 82a0445962 提交
1 year ago
tengxi 54b7c20332 1
1 year ago
LI-CCONG\李聪聪 b358c9989f 解决新建菜单目录时系统异常问题
1 year ago

1
.gitignore vendored

@ -49,4 +49,3 @@ rebel.xml
application-my.yaml
/yunxi-ui-app/unpackage/
/yunxi-module-xxjj/yunxi-module-xxjj-biz/src/main/java/com/yunxi/scm/module/xxjj/controller/admin/supplier/vo/SupplierCreateReqVO.java

@ -1,17 +0,0 @@
# 端口号
VITE_PORT = 80
# 网站标题
VITE_GLOB_APP_TITLE = 芋道管理系统
# 简称,用于配置文件名字 不要出现空格、数字开头等特殊字符
VITE_GLOB_APP_SHORT_NAME = Yudao_Admin
# 租户开关
VITE_GLOB_APP_TENANT_ENABLE = true
# 验证码的开关
VITE_GLOB_APP_CAPTCHA_ENABLE = true
# 百度统计
VITE_APP_BAIDU_CODE = eb21166668bf766b9d059a6fd1c10777

@ -1,28 +0,0 @@
# 本地开发环境
NODE_ENV=development
# 资源公共路径,需要以 /开头和结尾
VITE_PUBLIC_PATH = /
# 本地开发代理,可以解决跨域及多地址代理
# 如果接口地址匹配到则会转发到http://localhost:3000防止本地出现跨域问题
# 可以有多个,注意多个不能换行,否则代理将会失效
VITE_PROXY = [["/dev-api","http://192.168.0.162:8091/admin-api"],["/upload","http://192.168.0.162:8091/admin-api/infra/file/upload"]]
# VITE_PROXY=[["/api","http://vben.xingyuv.com/test"]]
# 是否删除Console.log
VITE_DROP_CONSOLE = false
# 基础页面地址,例如 swagger 等页面
VITE_GLOB_BASE_URL = "http://192.168.0.162:8091"
# 接口地址,如果没有跨域问题,直接在这里配置即可
VITE_GLOB_API_URL = /dev-api
# 文件上传接口 可选
VITE_GLOB_UPLOAD_URL = /upload
# 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换
VITE_GLOB_API_URL_PREFIX =
# 百度统计
VITE_APP_BAIDU_CODE = eb21166668bf766b9d059a6fd1c10777

@ -1,33 +0,0 @@
node_modules
.DS_Store
dist
.npmrc
.cache
tests/server/static
tests/server/static/upload
*.local
# local env files
.env.local
.env.*.local
.eslintcache
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
# .vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
package-lock.json
.history

@ -1,8 +0,0 @@
#!/bin/sh
# shellcheck source=./_/husky.sh
. "$(dirname "$0")/_/husky.sh"
PATH="/usr/local/bin:$PATH"
npx --no-install commitlint --edit "$1"

@ -1,9 +0,0 @@
#!/bin/sh
command_exists () {
command -v "$1" >/dev/null 2>&1
}
# Workaround for Windows 10, Git Bash and Yarn
if command_exists winpty && test -t 1; then
exec < /dev/tty
fi

@ -1,10 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
. "$(dirname "$0")/common.sh"
[ -n "$CI" ] && exit 0
PATH="/usr/local/bin:$PATH"
# Format and submit code according to lintstagedrc.js configuration
npm run lint:lint-staged

@ -1,20 +0,0 @@
{
"recommendations": [
"christian-kohler.path-intellisense",
"vscode-icons-team.vscode-icons",
"davidanson.vscode-markdownlint",
"stylelint.vscode-stylelint",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"usernamehw.errorlens",
"mrmlnc.vscode-less",
"lokalise.i18n-ally",
"redhat.vscode-yaml",
"csstools.postcss",
"mikestead.dotenv",
"eamodio.gitlens",
"antfu.iconify",
"antfu.unocss",
"Vue.volar"
]
}

@ -1,13 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome",
"url": "http://localhost:80",
"webRoot": "${workspaceFolder}/src",
"sourceMaps": true
}
]
}

@ -1,181 +0,0 @@
{
"typescript.tsdk": "./node_modules/typescript/lib",
"npm.packageManager": "pnpm",
"editor.tabSize": 2,
"prettier.printWidth": 140, //
"editor.defaultFormatter": "esbenp.prettier-vscode",
"files.eol": "\n",
"search.exclude": {
"**/node_modules": true,
"**/*.log": true,
"**/*.log*": true,
"**/bower_components": true,
"**/dist": true,
"**/elehukouben": true,
"**/.git": true,
"**/.gitignore": true,
"**/.svn": true,
"**/.DS_Store": true,
"**/.idea": true,
"**/.vscode": false,
"**/yarn.lock": true,
"pnpm-lock.yaml": true,
"**/tmp": true,
"out": true,
"dist": true,
"public": true,
"node_modules": true,
"CHANGELOG.md": true,
"examples": true,
"res": true,
"screenshots": true,
"yarn-error.log": true,
"**/.yarn": true
},
"files.exclude": {
"**/.cache": true,
"**/.editorconfig": true,
"**/.eslintcache": true,
"**/bower_components": true,
"**/.idea": true,
"**/tmp": true,
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true
},
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/.vscode/**": true,
"**/node_modules/**": true,
"**/tmp/**": true,
"**/bower_components/**": true,
"**/dist/**": true,
"**/yarn.lock": true
},
"stylelint.enable": true,
"stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"],
"path-intellisense.mappings": {
"@/": "${workspaceRoot}/src"
},
"prettier.enable": false,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": false
},
"eslint.rules.customizations": [
{
"rule": "@stylistic/*",
"severity": "off"
}
],
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml"
],
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": false,
"source.fixAll.stylelint": true
}
},
"i18n-ally.localesPaths": ["src/locales/lang"],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
"i18n-ally.enabledParsers": ["ts"],
"i18n-ally.sourceLanguage": "en",
"i18n-ally.displayLanguage": "zh-CN",
"i18n-ally.enabledFrameworks": ["vue", "react"],
"cSpell.words": [
"antd",
"antdv",
"antfu",
"antv",
"brotli",
"browserslist",
"Cascader",
"codemirror",
"commitlint",
"cropperjs",
"echarts",
"esnext",
"esno",
"iconify",
"INTLIFY",
"lintstagedrc",
"logicflow",
"nprogress",
"pinia",
"pnpm",
"qrcode",
"sider",
"sortablejs",
"stylelint",
"tailwind",
"tailwindcss",
"tinymce",
"unocss",
"unref",
"vben",
"vditor",
"videojs",
"vitejs",
"vuedraggable",
"vueuse",
"xingyuv",
"yudao",
"zxcvbn"
],
//
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.expand": false,
"explorer.fileNesting.patterns": {
"*.ts": "$(capture).test.ts, $(capture).test.tsx",
"*.tsx": "$(capture).test.ts, $(capture).test.tsx",
"*.env": "$(capture).env.*",
"package.json": ".hintrc,pnpm-lock.yaml,yarn.lock,LICENSE,README*,CHANGELOG*,CNAME,.gitattributes,.gitignore,prettier.config.js,stylelint.config.js,commitlint.config.js,.stylelintignore,.prettierignore,.gitpod.yml,.eslintrc.js,.eslintignore"
},
"eslint.codeAction.showDocumentation": {
"enable": true
},
"terminal.integrated.scrollback": 10000,
"nuxt.isNuxtApp": false
}

@ -1,69 +0,0 @@
import { generate } from '@ant-design/colors'
export const primaryColor = '#0960bd'
export const darkMode = 'light'
type Fn = (...arg: any) => any
type GenerateTheme = 'default' | 'dark'
export interface GenerateColorsParams {
mixLighten: Fn
mixDarken: Fn
tinycolor: any
color?: string
}
export function generateAntColors(color: string, theme: GenerateTheme = 'default') {
return generate(color, {
theme,
})
}
export function getThemeColors(color?: string) {
const tc = color || primaryColor
const lightColors = generateAntColors(tc)
const primary = lightColors[5]
const modeColors = generateAntColors(primary, 'dark')
return [...lightColors, ...modeColors]
}
export function generateColors({ color = primaryColor, mixLighten, mixDarken, tinycolor }: GenerateColorsParams) {
const arr = Array.from({ length: 19 }).fill(0)
const lightens = arr.map((_t, i) => {
return mixLighten(color, i / 5)
})
const darkens = arr.map((_t, i) => {
return mixDarken(color, i / 5)
})
const alphaColors = arr.map((_t, i) => {
return tinycolor(color)
.setAlpha(i / 20)
.toRgbString()
})
const shortAlphaColors = alphaColors.map(item => item.replace(/\s/g, '').replace(/0\./g, '.'))
const tinycolorLightens = arr
.map((_t, i) => {
return tinycolor(color)
.lighten(i * 5)
.toHexString()
})
.filter(item => item !== '#ffffff')
const tinycolorDarkens = arr
.map((_t, i) => {
return tinycolor(color)
.darken(i * 5)
.toHexString()
})
.filter(item => item !== '#000000')
return [...lightens, ...darkens, ...alphaColors, ...shortAlphaColors, ...tinycolorDarkens, ...tinycolorLightens].filter(
item => !item.includes('-'),
)
}

@ -1,6 +0,0 @@
/**
* The name of the configuration file entered in the production environment
*/
export const GLOB_CONFIG_FILE_NAME = '_app.config.js'
export const OUTPUT_DIR = 'dist'

@ -1,18 +0,0 @@
import { resolve } from 'node:path'
import { generateAntColors, primaryColor } from '../config/themeConfig'
/**
* less global variable
*/
export function generateModifyVars() {
const palettes = generateAntColors(primaryColor)
const primaryColorObj: Record<string, string> = {}
for (let index = 0; index < 10; index++)
primaryColorObj[`primary-${index + 1}`] = palettes[index]
return {
hack: `true; @import (reference) "${resolve('src/design/config.less')}";`,
}
}

@ -1,68 +0,0 @@
import path from 'node:path'
import fs from 'fs-extra'
import inquirer from 'inquirer'
import colors from 'picocolors'
import pkg from '../../../package.json'
async function generateIcon() {
const dir = path.resolve(process.cwd(), 'node_modules/@iconify/json')
const raw = await fs.readJSON(path.join(dir, 'collections.json'))
const collections = Object.entries(raw).map(([id, v]) => ({
...(v as any),
id,
}))
const choices = collections.map(item => ({ key: item.id, value: item.id, name: item.name }))
inquirer
.prompt([
{
type: 'list',
name: 'useType',
choices: [
{ key: 'local', value: 'local', name: 'Local' },
{ key: 'onLine', value: 'onLine', name: 'OnLine' },
],
message: 'How to use icons?',
},
{
type: 'list',
name: 'iconSet',
choices,
message: 'Select the icon set that needs to be generated?',
},
{
type: 'input',
name: 'output',
message: 'Select the icon set that needs to be generated?',
default: 'src/components/Icon/data',
},
])
.then(async (answers) => {
const { iconSet, output, useType } = answers
const outputDir = path.resolve(process.cwd(), output)
await fs.ensureDir(outputDir)
const genCollections = collections.filter(item => [iconSet].includes(item.id))
const prefixSet: string[] = []
for (const info of genCollections) {
const data = await fs.readJSON(path.join(dir, 'json', `${info.id}.json`))
if (data) {
const { prefix } = data
const isLocal = useType === 'local'
const icons = Object.keys(data.icons).map(item => `${isLocal ? `${prefix}:` : ''}${item}`)
fs.writeFileSync(
path.join(output, 'icons.data.ts'),
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`,
)
prefixSet.push(prefix)
}
}
await fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite'))
console.log(`${colors.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`)
})
}
generateIcon()

@ -1,7 +0,0 @@
/**
* Get the configuration file variable name
* @param env
*/
export function getConfigFileName(env: Record<string, any>) {
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, '')
}

@ -1,48 +0,0 @@
/**
* Generate additional configuration files when used for packaging. The file can be configured with some global variables, so that it can be changed directly externally without repackaging
*/
import fs, { writeFileSync } from 'fs-extra'
import colors from 'picocolors'
import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant'
import { getEnvConfig, getRootPath } from '../utils'
import { getConfigFileName } from '../getConfigFileName'
import pkg from '../../package.json'
interface CreateConfigParams {
configName: string
config: any
configFileName?: string
}
function createConfig(params: CreateConfigParams) {
const { configName, config, configFileName } = params
try {
const windowConf = `window.${configName}`
// Ensure that the variable will not be modified
let configStr = `${windowConf}=${JSON.stringify(config)};`
configStr += `
Object.freeze(${windowConf});
Object.defineProperty(window, "${configName}", {
configurable: false,
writable: false,
});
`.replace(/\s/g, '')
fs.mkdirp(getRootPath(OUTPUT_DIR))
writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr)
console.log(`${colors.cyan(`✨ [${pkg.name}]`)} - configuration file is build successfully:`)
console.log(`${colors.gray(`${OUTPUT_DIR}/${colors.green(configFileName)}`)}\n`)
}
catch (error: any) {
console.log(colors.red(`configuration file configuration file failed to package:\n${error}`))
}
}
export function runBuildConfig() {
const config = getEnvConfig()
const configFileName = getConfigFileName(config)
createConfig({ config, configName: configFileName, configFileName: GLOB_CONFIG_FILE_NAME })
}

@ -1,23 +0,0 @@
// #!/usr/bin/env node
import colors from 'picocolors'
import pkg from '../../package.json'
import { runBuildConfig } from './buildConf'
export function runBuild() {
try {
const argvList = process.argv.splice(2)
// Generate configuration file
if (!argvList.includes('disabled-config'))
runBuildConfig()
console.log(`${colors.cyan(`[${pkg.name}]`)}` + ' - build successfully!')
}
catch (error: any) {
console.log(colors.red(`vite build error:\n${error}`))
process.exit(1)
}
}
runBuild()

@ -1,93 +0,0 @@
import fs from 'node:fs'
import path from 'node:path'
import dotenv from 'dotenv'
export function isDevFn(mode: string): boolean {
return mode === 'development'
}
export function isProdFn(mode: string): boolean {
return mode === 'production'
}
/**
* Whether to generate package preview
*/
export function isReportMode(): boolean {
return process.env.REPORT === 'true'
}
// Read all environment variable configuration files to process.env
export function wrapperEnv(envConf: Recordable): ViteEnv {
const ret: any = {}
for (const envName of Object.keys(envConf)) {
let realName = envConf[envName].replace(/\\n/g, '\n')
realName = realName === 'true' ? true : realName === 'false' ? false : realName
if (envName === 'VITE_PORT')
realName = Number(realName)
if (envName === 'VITE_PROXY' && realName) {
try {
realName = JSON.parse(realName.replace(/'/g, '"'))
}
catch (error) {
realName = ''
}
}
ret[envName] = realName
// if (typeof realName === 'string') {
// process.env[envName] = realName;
// } else if (typeof realName === 'object') {
// process.env[envName] = JSON.stringify(realName);
// }
}
return ret
}
/**
*
*/
function getConfFiles() {
const script = process.env.npm_lifecycle_script
const reg = /--mode ([a-z_\d]+)/
const result = reg.exec(script as string) as any
if (result) {
const mode = result[1] as string
return ['.env', `.env.${mode}`]
}
return ['.env', '.env.production']
}
/**
* Get the environment variables starting with the specified prefix
* @param match prefix
* @param confFiles ext
*/
export function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) {
let envConfig = {}
confFiles.forEach((item) => {
try {
const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)))
envConfig = { ...envConfig, ...env }
}
catch (e) {
console.error(`Error in parsing ${item}`, e)
}
})
const reg = new RegExp(`^(${match})`)
Object.keys(envConfig).forEach((key) => {
if (!reg.test(key))
Reflect.deleteProperty(envConfig, key)
})
return envConfig
}
/**
* Get user root directory
* @param dir file path
*/
export function getRootPath(...dir: string[]) {
return path.resolve(process.cwd(), ...dir)
}

@ -1,35 +0,0 @@
const include = [
'qs',
'vue',
'less',
'axios',
'pinia',
'dayjs',
'echarts',
'cropperjs',
'crypto-js',
'lodash-es',
'nprogress',
'vue-i18n',
'vue-types',
'vue-router',
'codemirror',
'sortablejs',
'vuedraggable',
'echarts/core',
'echarts/charts',
'echarts/components',
'echarts/renderers',
'@vueuse/core',
'@zxcvbn-ts/core',
'@iconify/iconify',
'vue-json-pretty',
'ant-design-vue',
'ant-design-vue/es/style',
'ant-design-vue/es/locale/zh_CN',
'ant-design-vue/es/locale/en_US',
]
const exclude = ['@iconify/json']
export { include, exclude }

@ -1,35 +0,0 @@
/**
* Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated
* https://github.com/anncwb/vite-plugin-compression
*/
import type { PluginOption } from 'vite'
import compressPlugin from 'vite-plugin-compression'
export function configCompressPlugin(
compress: 'gzip' | 'brotli' | 'none' = 'none',
deleteOriginFile = false,
): PluginOption | PluginOption[] {
const compressList = compress.split(',')
const plugins: PluginOption[] = []
if (compressList.includes('gzip')) {
plugins.push(
compressPlugin({
ext: '.gz',
deleteOriginFile,
}),
)
}
if (compressList.includes('brotli')) {
plugins.push(
compressPlugin({
ext: '.br',
algorithm: 'brotliCompress',
deleteOriginFile,
}),
)
}
return plugins
}

@ -1,40 +0,0 @@
/**
* Plugin to minimize and use ejs template syntax in index.html.
* https://github.com/xingyuv/vite-vue-plugin-html
*/
import type { PluginOption } from 'vite'
import { createHtmlPlugin } from 'vite-vue-plugin-html'
import pkg from '../../../package.json'
import { GLOB_CONFIG_FILE_NAME } from '../../constant'
export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) {
const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env
const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/`
const getAppConfigSrc = () => {
return `${path || '/'}${GLOB_CONFIG_FILE_NAME}?v=${pkg.version}-${new Date().getTime()}`
}
const htmlPlugin: PluginOption[] = createHtmlPlugin({
minify: isBuild,
inject: {
// Inject data into ejs template
data: {
title: VITE_GLOB_APP_TITLE,
},
// Embed the generated app.config.js file
tags: isBuild
? [
{
tag: 'script',
attrs: {
src: getAppConfigSrc(),
},
},
]
: [],
},
})
return htmlPlugin
}

@ -1,53 +0,0 @@
import type { PluginOption } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import progress from 'vite-plugin-progress'
import purgeIcons from 'vite-plugin-purge-icons'
import VitePluginCertificate from 'vite-plugin-mkcert'
import UnoCSS from 'unocss/vite'
import { configPwaConfig } from './pwa'
import { configHtmlPlugin } from './html'
import { configCompressPlugin } from './compress'
import { configVisualizerConfig } from './visualizer'
import { configSvgIconsPlugin } from './svgSprite'
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
const { VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv
const vitePlugins: PluginOption[] = [
// have to
vue(),
// have to
vueJsx(),
// UnoCSS
UnoCSS(),
// 打包进度条
progress(),
VitePluginCertificate({
source: 'coding',
}),
]
// vite-vue-plugin-html
vitePlugins.push(configHtmlPlugin(viteEnv, isBuild))
// vite-plugin-svg-icons
vitePlugins.push(configSvgIconsPlugin(isBuild))
// vite-plugin-purge-icons
vitePlugins.push(purgeIcons())
// rollup-plugin-visualizer
vitePlugins.push(configVisualizerConfig())
// The following plugins only work in the production environment
if (isBuild) {
// rollup-plugin-gzip
vitePlugins.push(configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE))
// vite-plugin-pwa
vitePlugins.push(configPwaConfig(viteEnv))
}
return vitePlugins
}

@ -1,33 +0,0 @@
/**
* Zero-config PWA for Vite
* https://github.com/antfu/vite-plugin-pwa
*/
import { VitePWA } from 'vite-plugin-pwa'
export function configPwaConfig(env: ViteEnv) {
const { VITE_USE_PWA, VITE_GLOB_APP_TITLE, VITE_GLOB_APP_SHORT_NAME } = env
if (VITE_USE_PWA) {
// vite-plugin-pwa
const pwaPlugin = VitePWA({
manifest: {
name: VITE_GLOB_APP_TITLE,
short_name: VITE_GLOB_APP_SHORT_NAME,
icons: [
{
src: './resource/img/pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: './resource/img/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
},
],
},
})
return pwaPlugin
}
return []
}

@ -1,18 +0,0 @@
/**
* Vite Plugin for fast creating SVG sprites.
* https://github.com/anncwb/vite-plugin-svg-icons
*/
import path from 'node:path'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import type { PluginOption } from 'vite'
export function configSvgIconsPlugin(isBuild: boolean) {
const svgIconsPlugin = createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
svgoOptions: isBuild,
// default
symbolId: 'icon-[dir]-[name]',
})
return svgIconsPlugin as PluginOption
}

@ -1,18 +0,0 @@
/**
* Package file volume analysis
*/
import visualizer from 'rollup-plugin-visualizer'
import type { PluginOption } from 'vite'
import { isReportMode } from '../../utils'
export function configVisualizerConfig() {
if (isReportMode()) {
return visualizer({
filename: './node_modules/.cache/visualizer/stats.html',
open: true,
gzipSize: true,
brotliSize: true,
}) as PluginOption
}
return []
}

@ -1,34 +0,0 @@
/**
* Used to parse the .env.development proxy configuration
*/
import type { ProxyOptions } from 'vite'
type ProxyItem = [string, string]
type ProxyList = ProxyItem[]
type ProxyTargetList = Record<string, ProxyOptions>
const httpsRE = /^https:\/\//
/**
* Generate proxy
* @param list
*/
export function createProxy(list: ProxyList = []) {
const ret: ProxyTargetList = {}
for (const [prefix, target] of list) {
const isHttps = httpsRE.test(target)
// https://github.com/http-party/node-http-proxy#options
ret[prefix] = {
target,
changeOrigin: true,
ws: true,
rewrite: path => path.replace(new RegExp(`^${prefix}`), ''),
// https is require secure=false
...(isHttps ? { secure: false } : {}),
}
}
return ret
}

@ -1,87 +0,0 @@
import type { TentantNameVO } from './model/loginModel'
import { defHttp } from '@/utils/http/axios'
import { getRefreshToken } from '@/utils/auth'
enum Api {
Login = '/system/auth/login',
RefreshToken = '/system/auth/refresh-token?refreshToken=',
GetTenantIdByName = '/system/tenant/get-id-by-name?name=',
LoginOut = '/system/auth/logout',
GetUserInfo = '/system/auth/get-permission-info',
GetCaptcha = '/system/captcha/get',
CheckCaptcha = '/system/captcha/check',
}
// 刷新访问令牌
export function refreshToken() {
const refreshToken: string = getRefreshToken()
return defHttp.post({ url: Api.RefreshToken + refreshToken })
}
// 使用租户名,获得租户编号
export function getTenantIdByName(name: string) {
return defHttp.get<TentantNameVO>({ url: Api.GetTenantIdByName + name })
}
// 登出
export function loginOut() {
return defHttp.delete({ url: Api.LoginOut })
}
// 获取用户权限信息
export function getUserInfo() {
return defHttp.get({ url: Api.GetUserInfo })
}
// 获取登录验证码
export function sendSmsCode(mobile, scene) {
return defHttp.post({
url: '/system/auth/send-sms-code',
data: {
mobile,
scene,
},
})
}
// 获取验证图片 以及token
export function getCaptcha(data) {
return defHttp.post({ url: Api.GetCaptcha, data }, { isReturnNativeResponse: true })
}
// 滑动或者点选验证
export function checkCaptcha(data) {
return defHttp.post({ url: Api.CheckCaptcha, data }, { isReturnNativeResponse: true })
}
// ========== OAUTH 2.0 相关 ==========
export function getAuthorize(clientId) {
return defHttp.get({ url: `/system/oauth2/authorize?clientId=${clientId}` })
}
export function authorize(responseType, clientId, redirectUri, state, autoApprove, checkedScopes, uncheckedScopes) {
// 构建 scopes
const scopes = {}
for (const scope of checkedScopes)
scopes[scope] = true
for (const scope of uncheckedScopes)
scopes[scope] = false
// 发起请求
return defHttp.post({
url: '/system/oauth2/authorize',
headers: {
'Content-type': 'application/x-www-form-urlencoded',
},
params: {
response_type: responseType,
client_id: clientId,
redirect_uri: redirectUri,
state,
auto_approve: autoApprove,
scope: JSON.stringify(scopes),
},
})
}

@ -1,31 +0,0 @@
import { defHttp } from '@/utils/http/axios'
// 查询业务线/仓库列表
export function getBusinessWarehousePage(params) {
return defHttp.get({ url: '/system/business-warehouse/page', params })
}
// 查询业务线/仓库详情
export function getBusinessWarehouse(id: number) {
return defHttp.get({ url: '/system/business-warehouse/get?id=' + id })
}
// 新增业务线/仓库
export function createBusinessWarehouse(data) {
return defHttp.post({ url: '/system/business-warehouse/create', data })
}
// 修改业务线/仓库
export function updateBusinessWarehouse(data) {
return defHttp.put({ url: '/system/business-warehouse/update', data })
}
// 删除业务线/仓库
export function deleteBusinessWarehouse(id: number) {
return defHttp.delete({ url: '/system/business-warehouse/delete?id=' + id })
}
// 导出业务线/仓库 Excel
export function exportBusinessWarehouse(params) {
return defHttp.download({ url: '/xxjj/business-warehouse/export-excel', params }, '业务线/仓库.xls')
}

@ -1,31 +0,0 @@
import { defHttp } from '@/utils/http/axios'
// 查询企业信息列表
export function getEnterprisePage(params) {
return defHttp.get({ url: '/xxjj/enterprise/page', params })
}
// 查询企业信息详情
export function getEnterprise(id: number) {
return defHttp.get({ url: '/xxjj/enterprise/get?id=' + id })
}
// 新增企业信息
export function createEnterprise(data) {
return defHttp.post({ url: '/xxjj/enterprise/create', data })
}
// 修改企业信息
export function updateEnterprise(data) {
return defHttp.put({ url: '/xxjj/enterprise/update', data })
}
// 删除企业信息
export function deleteEnterprise(id: number) {
return defHttp.delete({ url: '/xxjj/enterprise/delete?id=' + id })
}
// 导出企业信息 Excel
export function exportEnterprise(params) {
return defHttp.download({ url: '/xxjj/enterprise/export-excel', params }, '企业信息.xls')
}

@ -1,215 +0,0 @@
import { h } from 'vue'
import { defineStore } from 'pinia'
import type { RouteRecordRaw } from 'vue-router'
import type { ErrorMessageMode } from '@/types/axios'
import { store } from '@/store'
import { router } from '@/router'
import type { RoleEnum } from '@/enums/roleEnum'
import { PageEnum } from '@/enums/pageEnum'
import { ACCESS_TOKEN_KEY, REFRESH_TOKEN_KEY, ROLES_KEY, USER_INFO_KEY } from '@/enums/cacheEnum'
import { PAGE_NOT_FOUND_ROUTE } from '@/router/routes/basic'
import { usePermissionStore } from '@/store/modules/permission'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { getAuthCache, setAuthCache } from '@/utils/auth'
import { doLogout, getUserInfo, loginApi, smsLogin } from '@/api/base/user'
import type { GetUserInfoModel, LoginParams, SmsLoginParams } from '@/api/base/model/userModel'
import { isArray } from '@/utils/is'
interface UserState {
userInfo: Nullable<GetUserInfoModel>
accessToken?: string
refreshToken?: string
roleList: RoleEnum[]
sessionTimeout?: boolean
lastUpdateTime: number
}
export const useUserStore = defineStore('app-user', {
state: (): UserState => ({
// user info
userInfo: null,
// token
accessToken: undefined,
refreshToken: undefined,
// roleList
roleList: [],
// Whether the login expired
sessionTimeout: false,
// Last fetch time
lastUpdateTime: 0,
}),
getters: {
getUserInfo(state): GetUserInfoModel {
return state.userInfo || getAuthCache<GetUserInfoModel>(USER_INFO_KEY) || {}
},
getAccessToken(state): string {
return state.accessToken || getAuthCache<string>(ACCESS_TOKEN_KEY)
},
getRefreshToken(state): string {
return state.refreshToken || getAuthCache<string>(REFRESH_TOKEN_KEY)
},
getRoleList(state): RoleEnum[] {
return state.roleList.length > 0 ? state.roleList : getAuthCache<RoleEnum[]>(ROLES_KEY)
},
getSessionTimeout(state): boolean {
return !!state.sessionTimeout
},
getLastUpdateTime(state): number {
return state.lastUpdateTime
},
},
actions: {
setAccessToken(info: string | undefined) {
this.accessToken = info || '' // for null or undefined value
setAuthCache(ACCESS_TOKEN_KEY, info)
},
setRefreshToken(info: string | undefined) {
this.refreshToken = info || '' // for null or undefined value
setAuthCache(REFRESH_TOKEN_KEY, info)
},
setRoleList(roleList: RoleEnum[]) {
this.roleList = roleList
setAuthCache(ROLES_KEY, roleList)
},
setUserInfo(info: GetUserInfoModel | null) {
this.userInfo = info
this.lastUpdateTime = new Date().getTime()
setAuthCache(USER_INFO_KEY, info)
},
setSessionTimeout(flag: boolean) {
this.sessionTimeout = flag
},
resetState() {
this.userInfo = null
this.accessToken = ''
this.roleList = []
this.sessionTimeout = false
},
/**
* @description: login
*/
async login(
params: LoginParams & {
goHome?: boolean
mode?: ErrorMessageMode
},
): Promise<GetUserInfoModel | null> {
try {
const { goHome = true, mode, ...loginParams } = params
const data = await loginApi(loginParams, mode)
const { accessToken, refreshToken } = data
// save token
this.setAccessToken(accessToken)
this.setRefreshToken(refreshToken)
return this.afterLoginAction(goHome)
}
catch (error) {
return Promise.reject(error)
}
},
async smsLogin(
params: SmsLoginParams & {
goHome?: boolean
mode?: ErrorMessageMode
},
): Promise<GetUserInfoModel | null> {
try {
const { goHome = true, mode, ...smsLoginParams } = params
const data = await smsLogin(smsLoginParams, mode)
const { accessToken, refreshToken } = data
// save token
this.setAccessToken(accessToken)
this.setRefreshToken(refreshToken)
return this.afterLoginAction(goHome)
}
catch (error) {
return Promise.reject(error)
}
},
async afterLoginAction(goHome?: boolean): Promise<GetUserInfoModel | null> {
if (!this.getAccessToken)
return null
// get user info
const userInfo = await this.getUserInfoAction()
const sessionTimeout = this.sessionTimeout
if (sessionTimeout) {
this.setSessionTimeout(false)
}
else {
const permissionStore = usePermissionStore()
if (!permissionStore.isDynamicAddedRoute) {
const routes = await permissionStore.buildRoutesAction()
routes.forEach((route) => {
try {
router.addRoute(route as unknown as RouteRecordRaw)
}
catch (e) {}
})
router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw)
permissionStore.setDynamicAddedRoute(true)
}
goHome && (await router.replace(PageEnum.BASE_HOME))
}
return userInfo
},
async getUserInfoAction(): Promise<GetUserInfoModel | null> {
if (!this.getAccessToken)
return null
const userInfo = await getUserInfo()
const { roles = [] } = userInfo
if (isArray(roles)) {
const roleList = roles.map(item => item) as RoleEnum[]
this.setRoleList(roleList)
}
else {
userInfo.roles = []
this.setRoleList([])
}
this.setUserInfo(userInfo)
return userInfo
},
/**
* @description: logout
*/
async logout(goLogin = false) {
if (this.getAccessToken) {
try {
await doLogout()
}
catch {
console.log('注销Token失败')
}
}
this.setAccessToken(undefined)
this.setSessionTimeout(false)
this.setUserInfo(null)
goLogin && router.push(PageEnum.BASE_LOGIN)
},
/**
* @description: Confirm before logging out
*/
confirmLoginOut() {
const { createConfirm } = useMessage()
const { t } = useI18n()
createConfirm({
iconType: 'warning',
title: () => h('span', t('sys.app.logoutTip')),
content: () => h('span', t('sys.app.logoutMessage')),
onOk: async () => {
await this.logout(true)
},
})
},
},
})
// Need to be used outside the setup
export function useUserStoreWithOut() {
return useUserStore(store)
}

@ -1,164 +0,0 @@
/**
*
*/
import { useDictStoreWithOut } from '@/store/modules/dict'
const dictStore = useDictStoreWithOut()
/**
* dictType
*
* @param dictType
* @returns {*|Array}
*/
export interface DictDataType {
dictType: string
label: string
value: string | number | boolean
key?: any
colorType: string
cssClass: string
}
export function getDictDatas(dictType: string) {
return dictStore.getDictMap[dictType] || []
}
export function getDictOpts(dictType: string) {
/**
* Tag
* getDictOptions
*
* bugfix:
* dictOption.push({
...dict,
value: parseInt(dict.value + '')
})
*/
return getDictDatas(dictType)
}
export function getDictOptions(dictType: string, valueType?: 'string' | 'number' | 'boolean') {
const dictOption: DictDataType[] = []
const dictOptions: DictDataType[] = getDictDatas(dictType)
if (dictOptions && dictOptions.length > 0) {
dictOptions.forEach((dict: DictDataType) => {
dictOption.push({
...dict,
key: dict.value,
value:
valueType === 'string'
? `${dict.value}`
: valueType === 'boolean'
? `${dict.value}` === 'true'
: Number.parseInt(`${dict.value}`),
})
})
}
return dictOption
}
export function getDictObj(dictType: string, value: any) {
const dictOptions: DictDataType[] = getDictDatas(dictType)
if (dictOptions) {
dictOptions.forEach((dict: DictDataType) => {
if (dict.value === value.toString())
return dict
})
}
else {
return null
}
}
export enum DICT_TYPE {
USER_TYPE = 'user_type',
COMMON_STATUS = 'common_status',
SYSTEM_TENANT_PACKAGE_ID = 'system_tenant_package_id',
// ========== SYSTEM 模块 ==========
SYSTEM_USER_SEX = 'system_user_sex',
SYSTEM_MENU_TYPE = 'system_menu_type',
SYSTEM_ROLE_TYPE = 'system_role_type',
SYSTEM_DATA_SCOPE = 'system_data_scope',
SYSTEM_NOTICE_TYPE = 'system_notice_type',
SYSTEM_OPERATE_TYPE = 'system_operate_type',
SYSTEM_LOGIN_TYPE = 'system_login_type',
SYSTEM_LOGIN_RESULT = 'system_login_result',
SYSTEM_SMS_CHANNEL_CODE = 'system_sms_channel_code',
SYSTEM_SMS_TEMPLATE_TYPE = 'system_sms_template_type',
SYSTEM_SMS_SEND_STATUS = 'system_sms_send_status',
SYSTEM_SMS_RECEIVE_STATUS = 'system_sms_receive_status',
SYSTEM_ERROR_CODE_TYPE = 'system_error_code_type',
SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type',
SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status',
SYSTEM_NOTIFY_TEMPLATE_TYPE = 'system_notify_template_type',
// ========== INFRA 模块 ==========
INFRA_BOOLEAN_STRING = 'infra_boolean_string',
INFRA_REDIS_TIMEOUT_TYPE = 'infra_redis_timeout_type',
INFRA_JOB_STATUS = 'infra_job_status',
INFRA_JOB_LOG_STATUS = 'infra_job_log_status',
INFRA_API_ERROR_LOG_PROCESS_STATUS = 'infra_api_error_log_process_status',
INFRA_CONFIG_TYPE = 'infra_config_type',
INFRA_CODEGEN_TEMPLATE_TYPE = 'infra_codegen_template_type',
INFRA_CODEGEN_FRONT_TYPE = 'infra_codegen_front_type',
INFRA_CODEGEN_SCENE = 'infra_codegen_scene',
INFRA_FILE_STORAGE = 'infra_file_storage',
// ========== BPM 模块 ==========
BPM_MODEL_CATEGORY = 'bpm_model_category',
BPM_MODEL_FORM_TYPE = 'bpm_model_form_type',
BPM_TASK_ASSIGN_RULE_TYPE = 'bpm_task_assign_rule_type',
BPM_PROCESS_INSTANCE_STATUS = 'bpm_process_instance_status',
BPM_PROCESS_INSTANCE_RESULT = 'bpm_process_instance_result',
BPM_TASK_ASSIGN_SCRIPT = 'bpm_task_assign_script',
BPM_OA_LEAVE_TYPE = 'bpm_oa_leave_type',
// ========== PAY 模块 ==========
PAY_CHANNEL_CODE = 'pay_channel_code', // 支付渠道编码类型
PAY_ORDER_STATUS = 'pay_order_status', // 商户支付订单状态
PAY_REFUND_STATUS = 'pay_refund_status', // 退款订单状态
PAY_NOTIFY_STATUS = 'pay_notify_status', // 商户支付回调状态
PAY_NOTIFY_TYPE = 'pay_notify_type', // 商户支付回调状态
// ========== MP 模块 ==========
MP_AUTO_REPLY_REQUEST_MATCH = 'mp_auto_reply_request_match', // 自动回复请求匹配类型
MP_MESSAGE_TYPE = 'mp_message_type', // 消息类型
// ========== MALL - 会员模块 ==========
MEMBER_POINT_BIZ_TYPE = 'member_point_biz_type', // 积分的业务类型
// ========== MALL - 商品模块 ==========
PRODUCT_UNIT = 'product_unit', // 商品单位
PRODUCT_SPU_STATUS = 'product_spu_status', // 商品状态
// ========== MALL - 交易模块 ==========
EXPRESS_CHARGE_MODE = 'trade_delivery_express_charge_mode', // 快递的计费方式
TRADE_AFTER_SALE_STATUS = 'trade_after_sale_status', // 售后 - 状态
TRADE_AFTER_SALE_WAY = 'trade_after_sale_way', // 售后 - 方式
TRADE_AFTER_SALE_TYPE = 'trade_after_sale_type', // 售后 - 类型
TRADE_ORDER_TYPE = 'trade_order_type', // 订单 - 类型
TRADE_ORDER_STATUS = 'trade_order_status', // 订单 - 状态
TRADE_ORDER_ITEM_AFTER_SALE_STATUS = 'trade_order_item_after_sale_status', // 订单项 - 售后状态
TERMINAL = 'terminal', // 终端
// ========== MALL - 营销模块 ==========
PROMOTION_DISCOUNT_TYPE = 'promotion_discount_type', // 优惠类型
PROMOTION_PRODUCT_SCOPE = 'promotion_product_scope', // 营销的商品范围
PROMOTION_COUPON_TEMPLATE_VALIDITY_TYPE = 'promotion_coupon_template_validity_type', // 优惠劵模板的有限期类型
PROMOTION_COUPON_STATUS = 'promotion_coupon_status', // 优惠劵的状态
PROMOTION_COUPON_TAKE_TYPE = 'promotion_coupon_take_type', // 优惠劵的领取方式
PROMOTION_ACTIVITY_STATUS = 'promotion_activity_status', // 优惠活动的状态
PROMOTION_CONDITION_TYPE = 'promotion_condition_type', // 营销的条件类型枚举
// ============= BUSINESSLINE 模块=================
BUSINESS_TYPE = 'business_type', //业务线类型
DIFF_FLAG = 'diff_flag',
// ============= ENTERPRISEBRANCHING 模块=================
ENTERPRISE_TYPE = 'enterprise_type', //业务线类型
CLASS_STATUS = 'class_status',
}

@ -1,215 +0,0 @@
<script lang="ts" setup>
import { computed, reactive, ref, unref } from 'vue'
import { Button, Checkbox, Col, Divider, Form, Input, Row } from 'ant-design-vue'
import { AlipayCircleFilled, GithubFilled, WechatFilled } from '@ant-design/icons-vue'
import LoginFormTitle from './LoginFormTitle.vue'
import { LoginStateEnum, useFormRules, useFormValid, useLoginState } from './useLogin'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { useUserStore } from '@/store/modules/user'
import { usePermissionStore } from '@/store/modules/permission'
import { useGlobSetting } from '@/hooks/setting'
import { useDesign } from '@/hooks/web/useDesign'
import * as authUtil from '@/utils/auth'
import { Verify } from '@/components/Verifition'
import { getTenantIdByName } from '@/api/base/login'
const FormItem = Form.Item
const InputPassword = Input.Password
const { t } = useI18n()
const { notification, createErrorModal } = useMessage()
const { prefixCls } = useDesign('login')
const userStore = useUserStore()
const permissionStore = usePermissionStore()
const { tenantEnable, captchaEnable } = useGlobSetting()
const { setLoginState, getLoginState } = useLoginState()
const { getFormRules } = useFormRules()
const formRef = ref()
const loading = ref(false)
const rememberMe = ref(false)
const verify = ref()
const captchaType = ref('blockPuzzle') // blockPuzzle clickWord
const formData = reactive({
tenantName: '芋道源码',
username: 'admin',
password: 'admin123',
captchaVerification: '',
})
const { validForm } = useFormValid(formRef)
// onKeyStroke('Enter', handleLogin);
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN)
//
async function getCode() {
//
if (captchaEnable === 'false') {
await handleLogin({})
}
else {
//
//
verify.value.show()
}
}
// ID
async function getTenantId() {
if (tenantEnable === 'true') {
const res = await getTenantIdByName(formData.tenantName)
authUtil.setTenantId(res)
}
}
async function handleLogin(params) {
await getTenantId()
const data = await validForm()
if (!data)
return
try {
loading.value = true
const userInfo = await userStore.login({
password: data.password,
username: data.username,
captchaVerification: params.captchaVerification,
mode: 'none', //
})
if (userInfo) {
await permissionStore.changePermissionCode(userInfo.permissions)
notification.success({
message: t('sys.login.loginSuccessTitle'),
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.user.nickname}`,
duration: 3,
})
}
}
catch (error) {
createErrorModal({
title: t('sys.api.errorTip'),
content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'),
getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body,
})
}
finally {
loading.value = false
}
}
</script>
<template>
<LoginFormTitle v-show="getShow" class="enter-x" />
<Form v-show="getShow" ref="formRef" class="enter-x p-4" :model="formData" :rules="getFormRules" @keypress.enter="handleLogin">
<FormItem name="tenantName" class="enter-x">
<Input
v-if="tenantEnable === 'true'"
v-model:value="formData.tenantName"
size="large"
:placeholder="t('sys.login.tenantName')"
class="fix-auto-fill"
/>
</FormItem>
<FormItem name="username" class="enter-x">
<Input v-model:value="formData.username" size="large" :placeholder="t('sys.login.userName')" class="fix-auto-fill" />
</FormItem>
<FormItem name="password" class="enter-x">
<InputPassword
v-model:value="formData.password"
size="large"
visibility-toggle
:placeholder="t('sys.login.password')"
class="fix-auto-fill"
/>
</FormItem>
<Row class="enter-x">
<Col :span="12">
<FormItem>
<!-- No logic, you need to deal with it yourself -->
<Checkbox v-model:checked="rememberMe" size="small">
{{ t('sys.login.rememberMe') }}
</Checkbox>
</FormItem>
</Col>
<Col :span="12">
<FormItem :style="{ 'text-align': 'right' }">
<!-- No logic, you need to deal with it yourself -->
<Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)">
{{ t('sys.login.forgetPassword') }}
</Button>
</FormItem>
</Col>
</Row>
<FormItem class="enter-x">
<Button type="primary" size="large" block :loading="loading" @click="getCode">
{{ t('sys.login.loginButton') }}
</Button>
<!-- <Button size="large" class="mt-4 enter-x" block @click="handleRegister">
{{ t('sys.login.registerButton') }}
</Button> -->
</FormItem>
<Row class="enter-x" :gutter="[16, 16]">
<Col :md="8" :xs="24">
<Button block @click="setLoginState(LoginStateEnum.MOBILE)">
{{ t('sys.login.mobileSignInFormTitle') }}
</Button>
</Col>
<Col :md="8" :xs="24">
<Button block @click="setLoginState(LoginStateEnum.QR_CODE)">
{{ t('sys.login.qrSignInFormTitle') }}
</Button>
</Col>
<Col :md="8" :xs="24">
<a-button block @click="setLoginState(LoginStateEnum.REGISTER)">
{{ t('sys.login.registerButton') }}
</a-button>
</Col>
</Row>
<Divider class="enter-x">
{{ t('sys.login.otherSignIn') }}
</Divider>
<div class="enter-x flex justify-evenly" :class="`${prefixCls}-sign-in-way`">
<GithubFilled />
<WechatFilled />
<AlipayCircleFilled />
<!-- <GoogleCircleFilled /> -->
<!-- <TwitterCircleFilled /> -->
</div>
<!-- 萌新必读 -->
<Divider class="enter-x">
萌新必读
</Divider>
<div class="enter-x flex justify-evenly" :class="`${prefixCls}-sign-in-way`">
<Button href="https://doc.iocoder.cn/" target="_blank">
📚开发指南
</Button>
<Button href="https://doc.iocoder.cn/video/" target="_blank" style="padding-left: 10px">
🔥视频教程
</Button>
<Button href="https://www.iocoder.cn/Interview/good-collection/" target="_blank" style="padding-left: 10px">
面试手册
</Button>
<Button href="http://static.yudao.iocoder.cn/mp/xinyu370.jpeg" target="_blank" style="padding-left: 10px">
🤝外包咨询
</Button>
</div>
</Form>
<Verify ref="verify" mode="pop" :captcha-type="captchaType" :img-size="{ width: '400px', height: '200px' }" @success="handleLogin" />
</template>

@ -1,125 +0,0 @@
<script lang="ts" setup>
import { nextTick, onMounted, ref } from 'vue'
import DeptModal from './DeptModal.vue'
import { columns, searchFormSchema } from './dept.data'
import { handleTree } from '@/utils/tree'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { useModal } from '@/components/Modal'
import { IconEnum } from '@/enums/appEnum'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { getListSimpleUsers } from '@/api/system/user'
import { deleteDept, getDeptPage } from '@/api/system/dept'
defineOptions({ name: 'SystemDept' })
const { t } = useI18n()
const { createMessage } = useMessage()
const [registerModal, { openModal }] = useModal()
const [register, { expandAll, collapseAll, getForm, reload }] = useTable({
title: '部门列表',
api: getList,
columns,
rowKey: 'id',
formConfig: { labelWidth: 120, schemas: searchFormSchema },
isTreeTable: true,
pagination: false,
useSearchForm: true,
showTableSetting: true,
showIndexColumn: false,
actionColumn: {
width: 140,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right',
},
})
async function getList() {
const res = await getDeptPage(getForm().getFieldsValue() as any)
return handleTree(res, 'id')
}
const users = ref<any[]>([])
async function getUserList() {
const res = await getListSimpleUsers()
users.value = res
}
function handleCreate() {
openModal(true, { isUpdate: false })
}
function handleEdit(record: Recordable) {
openModal(true, { record, isUpdate: true })
}
async function handleDelete(record: Recordable) {
await deleteDept(record.id)
createMessage.success(t('common.delSuccessText'))
reload()
}
function onFetchSuccess() {
nextTick(expandAll)
}
function userNicknameFormat(row) {
if (!row.leaderUserId)
return '未设置'
for (const user of users.value) {
if (row.leaderUserId === user.id)
return user.nickname
}
return `未知【${row.leaderUserId}`
}
onMounted(async () => {
await getUserList()
})
</script>
<template>
<div>
<BasicTable @register="register" @fetch-success="onFetchSuccess">
<template #toolbar>
<a-button v-auth="['system:dept:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate">
{{ t('action.create') }}
</a-button>
<a-button type="info" @click="expandAll">
{{ t('component.tree.expandAll') }}
</a-button>
<a-button type="info" @click="collapseAll">
{{ t('component.tree.unExpandAll') }}
</a-button>
</template>
<template #leader="{ text }">
<span> {{ userNicknameFormat(text) }} </span>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:dept:update', onClick: handleEdit.bind(null, record) },
{
icon: IconEnum.DELETE,
danger: true,
label: t('action.delete'),
auth: 'system:dept:delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
<DeptModal @register="registerModal" @success="reload()" />
</div>
</template>

@ -1,142 +0,0 @@
<script lang="ts" setup>
import { reactive } from 'vue'
import UserModal from './UserModal.vue'
import UserRoleModal from './UserRoleModal.vue'
import ResetPwdModal from './ResetPwdModal.vue'
import DeptTree from './DeptTree.vue'
import { columns, searchFormSchema } from './user.data'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { useModal } from '@/components/Modal'
import { IconEnum } from '@/enums/appEnum'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import type { UserExportReqVO } from '@/api/system/user'
import { deleteUser, exportUser, getUserPage } from '@/api/system/user'
defineOptions({ name: 'SystemUser' })
const { t } = useI18n()
const { createConfirm, createMessage } = useMessage()
const [registerModal, { openModal }] = useModal()
const [registerRoleModal, { openModal: openRoleModal }] = useModal()
const [registerPwdModal, { openModal: openPwdModal }] = useModal()
const searchInfo = reactive<Recordable>({})
const [registerTable, { getForm, reload }] = useTable({
title: '账号列表',
api: getUserPage,
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
},
useSearchForm: true,
showTableSetting: true,
showIndexColumn: false,
actionColumn: {
width: 140,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right',
},
})
/** 新增按钮操作 */
function handleCreate() {
openModal(true, { isUpdate: false })
}
/** 导出按钮操作 */
async function handleExport() {
createConfirm({
title: t('common.exportTitle'),
iconType: 'warning',
content: t('common.exportMessage'),
async onOk() {
await exportUser(getForm().getFieldsValue() as UserExportReqVO)
createMessage.success(t('common.exportSuccessText'))
},
})
}
/** 修改按钮操作 */
function handleEdit(record: Recordable) {
openModal(true, { record, isUpdate: true })
}
/** 分配用户角色操作 */
function handleRole(record: Recordable) {
openRoleModal(true, { record })
}
/** 重置密码按钮操作 */
function handleResetPwd(record: Recordable) {
openPwdModal(true, { record })
}
/** 删除按钮操作 */
async function handleDelete(record: Recordable) {
await deleteUser(record.id)
createMessage.success(t('common.delSuccessText'))
reload()
}
/** 点击部门操作 */
function handleSelect(deptId = '') {
searchInfo.deptId = deptId
reload()
}
</script>
<template>
<div class="flex">
<DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect" />
<BasicTable class="w-3/4 xl:w-4/5" :search-info="searchInfo" @register="registerTable">
<template #toolbar>
<a-button v-auth="['system:user:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate">
{{ t('action.create') }}
</a-button>
<a-button v-auth="['system:user:export']" :pre-icon="IconEnum.EXPORT" @click="handleExport">
{{ t('action.export') }}
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:user:update', onClick: handleEdit.bind(null, record) },
]"
:drop-down-actions="[
{
icon: IconEnum.EDIT,
label: '分配角色',
auth: 'system:permission:assign-user-role',
onClick: handleRole.bind(null, record),
},
{
icon: IconEnum.EDIT,
label: '重置密码',
auth: 'system:user:update-password',
onClick: handleResetPwd.bind(null, record),
},
{
icon: IconEnum.DELETE,
danger: true,
label: t('action.delete'),
auth: 'system:user:delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
<UserModal @register="registerModal" @success="reload()" />
<UserRoleModal @register="registerRoleModal" @success="reload()" />
<ResetPwdModal @register="registerPwdModal" @success="reload()" />
</div>
</template>

@ -1,284 +0,0 @@
import { h } from 'vue'
import { Switch } from 'ant-design-vue'
import { useMessage } from '@/hooks/web/useMessage'
import { listSimpleDept } from '@/api/system/dept'
import { listSimplePosts } from '@/api/system/post'
import type { BasicColumn, FormSchema } from '@/components/Table'
import { useRender } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
import { updateUserStatus } from '@/api/system/user'
import { listSimpleRoles } from '@/api/system/role'
export const columns: BasicColumn[] = [
{
title: '用户编号',
dataIndex: 'id',
width: 100,
},
{
title: '用户名称',
dataIndex: 'username',
width: 180,
},
{
title: '用户昵称',
dataIndex: 'nickname',
width: 100,
},
{
title: '部门',
dataIndex: 'deptId',
width: 120,
customRender: ({ record }) => {
return useRender.renderTag(record.dept && record.dept.name)
},
},
{
title: '手机号码',
dataIndex: 'mobile',
width: 120,
},
{
title: '状态',
dataIndex: 'status',
width: 180,
// customRender: ({ text }) => {
// return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS)
// }
customRender: ({ record }) => {
if (!Reflect.has(record, 'pendingStatus'))
record.pendingStatus = false
return h(Switch, {
checked: record.status === 0,
checkedChildren: '已启用',
unCheckedChildren: '已禁用',
loading: record.pendingStatus,
onChange(checked: boolean) {
record.pendingStatus = true
const newStatus = checked ? 0 : 1
const { createMessage } = useMessage()
updateUserStatus(record.id, newStatus)
.then(() => {
record.status = newStatus
createMessage.success('已成功修改用户状态')
})
.catch(() => {
createMessage.error('修改用户状态失败')
})
.finally(() => {
record.pendingStatus = false
})
},
})
},
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 180,
customRender: ({ text }) => {
return useRender.renderDate(text)
},
},
]
export const searchFormSchema: FormSchema[] = [
{
label: '用户名称',
field: 'username',
component: 'Input',
colProps: { span: 8 },
},
{
label: '手机号码',
field: 'mobile',
component: 'Input',
colProps: { span: 8 },
},
{
label: '状态',
field: 'status',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.COMMON_STATUS),
},
colProps: { span: 8 },
},
{
label: '创建时间',
field: 'createTime',
component: 'RangePicker',
componentProps: {
format: 'YYYY-MM-DD HH:mm:ss',
},
colProps: { span: 8 },
},
]
export const formSchema: FormSchema[] = [
{
label: '编号',
field: 'id',
show: false,
component: 'Input',
},
{
label: '用户昵称',
field: 'nickname',
required: true,
component: 'Input',
},
{
label: '用户头像',
field: 'avatar',
component: 'FileUpload',
componentProps: {
maxCount: 1,
fileType: 'image',
},
},
{
label: '归属部门',
field: 'deptId',
required: true,
component: 'ApiTreeSelect',
componentProps: {
api: () => listSimpleDept(),
fieldNames: {
label: 'name',
key: 'id',
value: 'id',
},
handleTree: 'id',
},
},
{
label: '手机号码',
field: 'mobile',
required: true,
defaultValue: 0,
component: 'InputNumber',
},
{
label: '邮箱',
field: 'email',
required: true,
component: 'Input',
},
{
label: '用户名称',
field: 'username',
component: 'Input',
dynamicDisabled: ({ values }) => !!values.id,
},
{
label: '用户密码',
field: 'password',
component: 'InputPassword',
ifShow: ({ values }) => !values.id,
},
{
label: '用户性别',
field: 'sex',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX),
},
},
{
label: '岗位',
field: 'postIds',
component: 'ApiSelect',
defaultValue: [],
componentProps: {
api: () => listSimplePosts(),
labelField: 'name',
valueField: 'id',
mode: 'tags',
},
},
{
label: '状态',
field: 'status',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.COMMON_STATUS),
},
},
{
label: '备注',
field: 'remark',
component: 'InputTextArea',
},
]
export const userRoleFormSchema: FormSchema[] = [
{
label: '编号',
field: 'id',
show: false,
component: 'Input',
},
{
label: '用户名称',
field: 'username',
component: 'Input',
dynamicDisabled: () => true,
},
{
label: '用户昵称',
field: 'nickname',
component: 'Input',
dynamicDisabled: () => true,
},
{
label: '角色',
field: 'roleIds',
component: 'ApiSelect',
componentProps: {
api: () => listSimpleRoles(),
labelField: 'name',
valueField: 'id',
mode: 'tags',
},
},
]
export const userPwdFormSchema: FormSchema[] = [
{
field: 'newPassword',
label: '新密码',
component: 'StrengthMeter',
componentProps: {
placeholder: '新密码',
},
rules: [
{
required: true,
message: '请输入新密码',
},
],
},
{
field: 'confirmPassword',
label: '确认密码',
component: 'InputPassword',
dynamicRules: ({ values }) => {
return [
{
required: true,
validator: (_, value) => {
if (!value)
return Promise.reject('密码不能为空')
if (value !== values.newPassword)
return Promise.reject('两次输入的密码不一致!')
return Promise.resolve()
},
},
]
},
},
]

@ -1,890 +0,0 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import type { UnwrapRef } from 'vue'
import {
FieldTimeOutlined,
LeftOutlined, ManOutlined,
RightCircleFilled,
UserOutlined, WindowsFilled,
WomanOutlined,
} from '@ant-design/icons-vue'
//
const sex = ref<string>('保密')//
const message = ref<string>('全部信息')//
interface FormState {
name: string
delivery: boolean
type: string[]
resource: string
desc: string
}
const formState: UnwrapRef<FormState> = reactive({
name: '',
delivery: false,
type: [],
resource: '',
desc: '',
})
//
const open = ref<boolean>(false)
const confirmLoading = ref<boolean>(false)
function showModal() {
open.value = true
}
function handleOk() {
confirmLoading.value = true
setTimeout(() => {
open.value = false
confirmLoading.value = false
}, 2000)
}
const state = reactive({
checked1: true,
})
//
const current = ref(6)//
//
const isVisible = ref(true)
const isVisible2 = ref(false)
const toggleBlocks: any = () => {
isVisible.value = !isVisible.value
isVisible2.value = !isVisible2.value
}
//antd^^^
const customButtonStyle = [ {
width:'80px',
textAlign:'center',
borderRadius: '50px',
margin:'0 10px',
}]
const messageStyle = [ {
color:'#6666',
width:'90px',
fontSize:'12px',
textAlign:'center',
borderRadius: '5px',
margin:'0 5px',
}]
const phoneStyle = [{
width:'60%',
}]
const changeStyle = [{
border:'none',
boxShadow: 'none',
color:'#409EFF',
}]
const labelCol = { style: { width: '100px' } }
const wrapperCol = { span: 20 }
const activeKey = ref('1')
//
const tablecolumns = [
{
name: '通知标题',
dataIndex: 'title',
key: 'title',
},
{
title: '状态',
dataIndex: 'state',
key: 'state',
},
{
title: '类型',
key: 'type',
dataIndex: 'type',
},
{
title: '发布时间',
key: 'time',
dataIndex: 'time',
},
]
const tabledata = [
{
key: '1',
title: '供应链管理平台正式上线',
state: '已读',
type:'产品信息',
time:'2023-08-22 22:31',
},
{
key: '2',
title: '供应链管理平台正式上线',
state: '已读',
type: '产品信息',
time:'2023-08-22 22:31',
}, {
key: '3',
title: '供应链管理平台正式上线',
state: '已读',
type: '产品信息',
time:'2023-08-22 22:31',
},
]
</script>
<template>
<a-card
style="width: 80%; padding: 20px;margin: 20px auto;"
default-active-tab-key
>
<a-tabs v-model:activeKey="activeKey" tab-position="left">
<!-- 第一部分 -->
<a-tab-pane key="1" tab="资料设置">
<div class="datum">
<div class="datumtop">
<p>
<span></span>
基本资料
</p>
</div>
<p class="pleft">
基本信息
</p>
<div class="datumbox">
<div class="form">
<a-form :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="登录账号:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item label="姓名:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item label="所属部门:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item label="员工职务:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item label="员工工号:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item label="手机号码:">
<div class="phonecss">
<a-input v-model:value="value" placeholder="输入内容" :style="phoneStyle" />
<div>
<a-button :style="changeStyle" @click="showModal">
修改手机号
</a-button>
<a-modal v-model:open="open" title="修改手机号" centered :confirm-loading="confirmLoading" @ok="handleOk">
<div class="dialog">
<a-form :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="原手机号码:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item label="验证码:">
<div class="phonecss">
<a-input v-model:value="value" placeholder="输入验证码" :style="phoneStyle" />
<a-button :style="changeStyle">
获取验证码
</a-button>
</div>
</a-form-item>
<a-form-item label="新手机号码:">
<a-input v-model:value="value" placeholder="输入新手机号" />
</a-form-item>
</a-form>
</div>
</a-modal>
</div>
</div>
</a-form-item>
<a-form-item label="微信账号:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item label="邮箱地址:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item name="DatePicker" label="出生日期" v-bind="config">
<a-date-picker v-model:value="formState['date-picker']" value-format="YYYY-MM-DD" />
</a-form-item>
<a-form-item label="性别:">
<div>
<div>
<div>
<a-radio-group v-model:value="sex">
<a-radio-button :style="customButtonStyle" value="男性">
男性<ManOutlined />
</a-radio-button>
<a-radio-button :style="customButtonStyle" value="女性">
女性<WomanOutlined />
</a-radio-button>
<a-radio-button :style="customButtonStyle" value="保密">
保密
</a-radio-button>
</a-radio-group>
</div>
</div>
</div>
</a-form-item>
<p class="pleft">
更多信息
</p>
<a-form label-width="100px" :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="籍贯:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item label="学历" name="region">
<a-select v-model:value="formState.region" placeholder="选择学历">
<a-select-option value="初中">
初中
</a-select-option>
<a-select-option value="高中">
高中
</a-select-option>
<a-select-option value="初中">
大专
</a-select-option>
<a-select-option value="高中">
本科
</a-select-option>
<a-select-option value="初中">
研究生
</a-select-option>
<a-select-option value="高中">
博士
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="专业:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item label="毕业院校:">
<a-input v-model:value="value" placeholder="输入内容" />
</a-form-item>
<a-form-item name="DatePicker" label="毕业时间:" v-bind="config">
<a-date-picker v-model:value="formState['date-picker']" value-format="YYYY-MM-DD" />
</a-form-item>
<a-form-item label="个人简介:" placeholder="输入内容" name="desc">
<a-textarea v-model:value="formState.desc" />
</a-form-item>
<a-form-item label="">
<button class="save">
保存
</button>
</a-form-item>
</a-form>
</a-form>
</div>
<div class="usepic">
<div class="idpic">
<a-avatar :size="{ xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }">
<template #icon>
<UserOutlined />
</template>
</a-avatar>
</div>
<div class="change">
<a-upload
v-model:file-list="fileList"
list-type="picture"
:max-count="1"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
>
<a-button>
<upload-outlined />
修改头像
</a-button>
</a-upload>
</div>
</div>
</div>
</div>
</a-tab-pane>
<!-- 第二部分 -->
<a-tab-pane key="2" tab="修改密码">
<div class="datum">
<div class="datumtop">
<p>
<span></span>
修改密码
</p>
</div>
<div class="datumbox">
<div class="form">
<a-form :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="验证码:">
<div class="phonecss">
<a-input v-model:value="value" placeholder="输入内容" :style="phoneStyle" />
<a-button :style="changeStyle">
获取验证码
</a-button>
</div>
</a-form-item>
<a-form-item label="原密码:">
<a-input v-model:value="value" placeholder="输入原密码" />
</a-form-item>
<a-form-item label="新密码:">
<a-input v-model:value="value" placeholder="输入新密码" />
</a-form-item>
<a-form-item label="新密码:">
<a-input v-model:value="value" placeholder="输入确认新密码" />
</a-form-item>
<button class="save">
保存
</button>
</a-form>
</div>
</div>
</div>
</a-tab-pane>
<!-- 第三部分 -->
<a-tab-pane key="3" tab="登录记录">
<div class="datum">
<div class="datumtop">
<p>
<span></span>
登录记录
</p>
</div>
<!-- 日期 -->
<div
v-for="(item, index) in 5" :key="index"
>
<div class="date">
{{ `2023-08-22` }}
</div>
<div
v-for="(item, index) in 5"
:key="index" class="recordbox"
>
<div class="recordleft">
<div class="recordicon">
<WindowsFilled />
</div>
<div class="recordmessage">
<div class="usersId">
{{ `kang-pc` }}
</div>
{{ `上海市长宁区 14.127.100.242` }}
</div>
</div>
<div class="recordright">
<span><FieldTimeOutlined /></span>{{ `2023-08-22 12:00` }}
</div>
</div>
</div>
<div class="sorter">
<a-pagination v-model:current="current" :total="500" />
</div>
</div>
</a-tab-pane>
<!-- 第四部分 -->
<a-tab-pane key="4" tab="系统通知">
<div v-if="isVisible" class="datum">
<div class="datumtop">
<p>
<span></span>
系统通知
</p>
</div>
<div class="messagetitle">
<div class="messagetitleleft">
<a-radio-group v-model:value="message">
<a-radio-button :style="messageStyle" value="全部信息">
全部信息
</a-radio-button>
<a-radio-button :style="messageStyle" value="服务信息">
服务信息
</a-radio-button>
<a-radio-button :style="messageStyle" value="活动信息">
活动信息
</a-radio-button>
<a-radio-button :style="messageStyle" value="产品信息">
产品信息
</a-radio-button>
<a-radio-button :style="messageStyle" value="安全信息">
安全信息
</a-radio-button>
<a-radio-button :style="messageStyle" value="故障信息">
故障信息
</a-radio-button>
</a-radio-group>
</div>
<div class="messagetitleright">
全部标记为已读
</div>
</div>
<div class="table">
<a-table :columns="tablecolumns" :data-source="tabledata" :total="500">
<template #headerCell="{ column }">
<template v-if="column.key === 'title'">
<span>
通知标题
</span>
</template>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'name'">
<a href=""> {{ record.name }}</a>
</template>
<template v-else-if="column.key === 'title'">
<div style="cursor: pointer;" @click="toggleBlocks">
{{ record.title }}
</div>
</template>
</template>
</a-table>
</div>
</div>
<div v-else-if="isVisible2" class="details">
<div class="detailstop">
<p>
关于供应链管理平台正式上线的通知
</p>
<div @click="toggleBlocks">
<a-button><LeftOutlined />返回</a-button>
</div>
</div>
<div class="nav">
<p>消息类型<span>{{ `产品信息` }}</span>发布时间<span>{{ `2023-08-22 22:31` }}</span></p>
</div>
<div class="main">
<p>
8月22日由长江云息打造的供应链管理平台正式上线运行该项目基于云息云建设涵盖采购需求采购价格采购配额采购订单到货签收质量协同对账开票付款计划 / 付款申请等全业务流程助力客户实现对标准采购VMI 采购委外加工等业务的全面管理实现供应商全周期管理实现从需求寻源合同到采购执行的全过程管理打造具有云息特色的端到端的数智化供应链管理体系
</p>
</div>
</div>
</a-tab-pane>
<!-- 第五部分 -->
<a-tab-pane key="5" tab="信息设置">
<div class="datum">
<div class="datumtop">
<p>
<span></span>
信息设置
</p>
</div>
<div class="inform">
<div
v-for="(item, index) in 5"
:key="index" class="informbox"
>
<div class="informleft">
<div class="informicon">
<WindowsFilled />
</div>
<div class="informmessage">
<div class="informId">
{{ `未读日报` }}
</div>
{{ `未读日报将以站内信的形式通知` }}
</div>
</div>
<div class="informright">
<a-space direction="vertical">
<a-switch v-model:checked="state.checked1" checked-children="" un-checked-children="" />
</a-space>
</div>
</div>
</div>
</div>
</a-tab-pane>
<!-- 第六部分 -->
<a-tab-pane key="6" tab="公司列表">
<div class="datum">
<div class="datumtop">
<p>
<span></span>
公司列表
</p>
</div>
<div class="listmainbox">
<div class="listmain">
<div v-for="(item, index) in 4" :key="index" class="list">
<div class="firm">
<div class="firmtop">
<div class="firmtopleft">
<img src="https://files.axshare.com/gsc/F4557Q/03/bb/8b/03bb8b5afc694032b44452387757f019/images/%E5%85%AC%E5%8F%B8%E5%88%97%E8%A1%A8/u30.png?pageId=125c1eb4-7fa5-4390-86d9-40ffd2c7d87c" alt="">
</div>
<div class="firmtopright">
<p>{{ `济钢城市矿产科技有限公司` }}</p>
<p class="fontcss">
职务{{ `产品经理` }}
</p>
</div>
</div>
<div class="firmtopbot">
<p class="fontcss">
部门{{ `再生资源事业部<采购部` }}
</p>
<p class="fontcss">
业务线{{ `废铁、废铝` }}
</p>
</div>
</div>
<div class="default">
<p class="fontcss">
默认登录:
<span style="margin-left: 15px;">
<a-switch v-model:checked="state.checked1" checked-children="" un-checked-children="" /></span>
</p>
<a href="http://www.hao123.com/" class="fontcss">
<span><RightCircleFilled /></span>
进入
</a>
</div>
</div>
</div>
<div class="sorter">
<a-pagination v-model:current="current" :total="50" show-less-items />
</div>
</div>
</div>
</a-tab-pane>
</a-tabs>
</a-card>
</template>
<style scoped lang="less">
.details{
height: 1200px;
padding: 20px;
.detailstop{
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
p{
font-size: 20px;
font-weight: 800;
color: #666;
}
}
.nav{
height: 30px;
padding: 0 0 0 10px;
line-height: 30px;
background-color: rgb(249 249 249);
border: 1px solid #999;
border-color: rgb(228 228 228 / 100%);
p{
font-size: 12px;
color: #999;
span{
margin: 0 10px;
color: #666;
}
}
}
}
.main{
padding: 20px 0;
p{
font-size: 16px;
font-weight: 700;
line-height: 28px;
color: #666;
text-align: left;
}
}
.listmainbox{
display: flex;
flex-direction: column;
width:100%;
padding: 20px ;
margin-top: 30px;
border-radius: 10px;
box-shadow: 0 0 0 0.2px #8f8c8c;
}
.listmain{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.list{
width: 30%;
height: 215px;
margin-bottom: 20px;
overflow: hidden;
border-radius: 10px;
box-shadow: 0 0 0 0.2px #8f8c8c;
.fontcss{
font-size:14px;
color:#999;
}
.firm{
display:flex;
flex-direction:column;
justify-content:space-between;
height: 165px;
padding: 10px;
background-color: rgb(227 240 252 );
.firmtop{
display: flex;
.firmtopleft{
width: 70px;
height: 70px;
margin-right:15px;
img{
width: 100%;
}
}
}
}
.default{
display:flex;
align-items: flex-end;
justify-content: space-between;
height:50px;
padding: 0 10px;
a{
line-height: 50px;
}
a:hover{
color:#333;
}
}
}
}
.ant-tabs-nav-list{
width: 300px !important;
}
.ant-tabs-tab .ant-tabs-tab-active{
padding: 8px 24px;
text-align: center;
}
.datum{
//
width: 100%;
margin-left: 20px;
color: #666;
.datumtop{
p{
margin-bottom: 15px;
font-size:18px;
font-weight:700;
span{
font-size:14px;
color:#409EFF;
}
}
}
.datumbox{
display: flex;
.form{
width: 40%;
.save{
width: 160px;
height: 40px;
margin-left: 100px;
color: aliceblue;
background-color: #409EFF;
border: none;
border-radius: 5px;
}
}
.phonecss{
display: flex;
justify-content: space-between;
}
.usepic{
display: flex;
flex-direction: column;
align-items: center;
margin-left: 150px;
.change{
margin-top: 20px;
}
}
}
.pleft{
margin: 20px ;
}
}
.messagetitle{
display: flex;
justify-content: space-between;
width: 100%;
margin: 20px 0;
font-size: 12px;
.messagetitleright{
width: 100px;
margin-right: 15px;
}
}
.dialog{
height: 400px;
margin-top: 30px;
}
.table{
width: 100%;
text-align: center;
}
.date{
padding: 20px;
font-weight: 700;
}
.sorter{
display: flex;
flex-direction: row-reverse;
}
.informbox{
display: flex;
align-items: center;
justify-content: space-between;
height: 90px;
padding:0 20px 0 0;
margin-bottom: 15px;
box-shadow:0 0.3px 0 0 ;
.informleft{
display: flex;
.informId{
font-weight: 600;
}
.informicon{
width: 50px ;
height: 50px;
margin-right: 20px;
font-size: 30px;
line-height: 50px;
color: #6666;
text-align: center;
border: 1px solid #6666;
border-radius: 50%;
}}}
.recordbox{
display: flex;
align-items: center;
justify-content: space-between;
height: 90px;
padding: 0 20px;
margin-bottom: 15px;
border: 1px solid #6666;
.recordleft{
display: flex;
.recordicon{
width: 50px ;
height: 50px;
font-size: 30px;
line-height: 50px;
color: #6666;
text-align: center;
border: 1px solid #6666;
border-radius: 50%;
}
.recordmessage{
display: flex;
flex-direction: column;
width: 300px;
margin-left: 20px;
.usersId{
font-size:20px ;
font-weight: 700;
}
}
}
}
:where(.css-dev-only-do-not-override-176pxz6).ant-picker{
width: 100%;
height: 40px;
}
:where(.css-dev-only-do-not-override-176pxz6).ant-input {
height: 40px;
}
:where(.css-dev-only-do-not-override-176pxz6).ant-input .phone{
width: 50%;
}
:where(.css-dev-only-do-not-override-176pxz6).ant-radio-button-wrapper:not(:first-child)::before {
display: none;
}
:where(.css-dev-only-do-not-override-176pxz6).ant-radio-button-wrapper:first-child{
border-inline-start: 1px solid #d9d9d9;
}
</style>

@ -1,57 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="isUpdate ? t('action.edit') : t('action.create')" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, unref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { BasicForm, useForm } from '@/components/Form'
import { BasicModal, useModalInner } from '@/components/Modal'
import { createFormSchema, updateFormSchema } from './businessWarehouse.data'
import { createBusinessWarehouse, getBusinessWarehouse, updateBusinessWarehouse } from '@/api/xxjj/businessWarehouse'
defineOptions({ name: 'BusinessWarehouseModal' })
const { t } = useI18n()
const { createMessage } = useMessage()
const emit = defineEmits(['success', 'register'])
const isUpdate = ref(true)
const [registerForm, { setFieldsValue, resetFields, resetSchema, validate }] = useForm({
labelWidth: 120,
baseColProps: { span: 24 },
schemas: createFormSchema,
showActionButtonGroup: false,
actionColOptions: { span: 23 }
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields()
setModalProps({ confirmLoading: false })
isUpdate.value = !!data?.isUpdate
if (unref(isUpdate)) {
resetSchema(updateFormSchema)
const res = await getBusinessWarehouse(data.record.id)
setFieldsValue({ ...res })
}
})
async function handleSubmit() {
try {
const values = await validate()
setModalProps({ confirmLoading: true })
if (unref(isUpdate)) {
await updateBusinessWarehouse(values)
} else {
await createBusinessWarehouse(values)
}
closeModal()
emit('success')
createMessage.success(t('common.saveSuccessText'))
} finally {
setModalProps({ confirmLoading: false })
}
}
</script>

@ -1,314 +0,0 @@
import { BasicColumn, FormSchema, useRender } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
export const columns: BasicColumn[] = [
{
title: '业务线名称',
dataIndex: 'name',
width: 160
},
{
title: '类型',
dataIndex: 'type',
width: 180,
customRender: ({ text }) => {
return useRender.renderDict(text, DICT_TYPE.BUSINESS_TYPE)
}
},
{
title: '状态',
dataIndex: 'type',
width: 180,
customRender: ({ text }) => {
return useRender.renderDict(text, DICT_TYPE.CLASS_STATUS)
}
},
{
title: '关联机构',
dataIndex: 'institutionNum',
width: 160
},
{
title: '成员数量',
dataIndex: 'employeeNum',
width: 160
},
{
title: '主管人员',
dataIndex: 'belongUserId',
width: 160
},
{
title: '介绍',
dataIndex: 'description',
width: 160
},
{
title: '更新时间',
dataIndex: 'updateTime',
width: 180,
customRender: ({ text }) => {
return useRender.renderDate(text)
}
},
]
export const searchFormSchema: FormSchema[] = [
{
label: '业务线名称',
field: 'name',
component: 'Input',
colProps: { span: 8 }
},
// {
// label: '类型',
// field: 'type',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.BUSINESS_TYPE)
// },
// colProps: { span: 8 }
// },
// {
// label: '所属行业',
// field: 'industry',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.DUTY_TYPE)
// },
// colProps: { span: 8 }
// },
// {
// label: '成立时间',
// field: 'establishDate',
// component: 'RangePicker',
// colProps: { span: 8 }
// },
// {
// label: '归属人员',
// field: 'belongUserId',
// component: 'Input',
// colProps: { span: 8 }
// },
// {
// label: '品牌/业务线/事业群名称',
// field: 'brandName',
// component: 'Input',
// colProps: { span: 8 }
// },
// {
// label: '业务线仓库区分(0业务线,1仓库)',
// field: 'diffFlag',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.DIFF_FLAG)
// },
// colProps: { span: 8 }
// },
]
export const createFormSchema: FormSchema[] = [
{
label: '编号',
field: 'id',
show: false,
component: 'Input'
},
{
label: '业务线编号',
field: 'businessCode',
required: true,
component: 'Input'
},
{
label: '业务线简称',
field: 'businessSimple',
component: 'Input'
},
{
label: '传真',
field: 'fax',
component: 'Input'
},
{
label: '网址',
field: 'url',
component: 'Input'
},
{
label: '介绍',
field: 'description',
component: 'InputTextArea'
},
{
label: '业务线名称',
field: 'name',
required: true,
component: 'Input'
},
{
label: '业务线LOGO',
field: 'businessLogo',
component: 'FileUpload',
componentProps: {
fileType: 'file',
maxCount: 1
}
},
{
label: '父id',
field: 'parentId',
component: 'Input'
},
{
label: '类型',
field: 'type',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.BUSINESS_TYPE, 'number')
}
},
{
label: '所属行业',
field: 'industry',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.DUTY_TYPE, 'number')
}
},
{
label: '所在城市',
field: 'city',
component: 'Input'
},
{
label: '成立时间',
field: 'establishDate',
component: 'DatePicker'
},
{
label: '归属人员',
field: 'belongUserId',
component: 'Input'
},
{
label: '品牌/业务线/事业群名称',
field: 'brandName',
component: 'Input'
},
{
label: '电话',
field: 'phone',
component: 'Input'
},
{
label: '业务线仓库区分(0业务线,1仓库)',
field: 'diffFlag',
required: true,
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.DIFF_FLAG, 'number')
}
},
]
export const updateFormSchema: FormSchema[] = [
{
label: '编号',
field: 'id',
show: false,
component: 'Input'
},
{
label: '业务线编号',
field: 'businessCode',
required: true,
component: 'Input'
},
{
label: '业务线简称',
field: 'businessSimple',
component: 'Input'
},
{
label: '业务线名称',
field: 'name',
required: true,
component: 'Input'
},
{
label: '业务线LOGO',
field: 'businessLogo',
component: 'Upload'
},
{
label: '父id',
field: 'parentId',
component: 'Input'
},
{
label: '类型',
field: 'type',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.BUSINESS_TYPE, 'number')
}
},
{
label: '所属行业',
field: 'industry',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.DUTY_TYPE, 'number')
}
},
{
label: '所在城市',
field: 'city',
component: 'Input'
},
{
label: '成立时间',
field: 'establishDate',
component: 'DatePicker'
},
{
label: '归属人员',
field: 'belongUserId',
component: 'Input'
},
{
label: '品牌/业务线/事业群名称',
field: 'brandName',
component: 'Input'
},
{
label: '电话',
field: 'phone',
component: 'Input'
},
{
label: '传真',
field: 'fax',
component: 'Input'
},
{
label: '网址',
field: 'url',
component: 'Input'
},
{
label: '介绍',
field: 'description',
component: 'InputTextArea'
},
{
label: '业务线仓库区分(0业务线,1仓库)',
field: 'diffFlag',
required: true,
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.DIFF_FLAG, 'number')
}
},
]

@ -1,92 +0,0 @@
<template>
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" v-auth="['xxjj:business-warehouse:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
{{ t('action.create') }}
</a-button>
<a-button type="warning" v-auth="['xxjj:business-warehouse:export']" :preIcon="IconEnum.EXPORT" @click="handleExport">
{{ t('action.export') }}
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'xxjj:business-warehouse:update', onClick: handleEdit.bind(null, record) },
{
icon: IconEnum.DELETE,
color: 'error',
label: t('action.delete'),
auth: 'xxjj:business-warehouse:delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',
confirm: handleDelete.bind(null, record)
}
}
]"
/>
</template>
</template>
</BasicTable>
<BusinessWarehouseModal @register="registerModal" @success="reload()" />
</div>
</template>
<script lang="ts" setup>
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { useModal } from '@/components/Modal'
import BusinessWarehouseModal from './BusinessWarehouseModal.vue'
import { IconEnum } from '@/enums/appEnum'
import { BasicTable, useTable, TableAction } from '@/components/Table'
import { deleteBusinessWarehouse, exportBusinessWarehouse, getBusinessWarehousePage } from '@/api/xxjj/businessWarehouse'
import { columns, searchFormSchema } from './businessWarehouse.data'
defineOptions({ name: 'BusinessWarehouse' })
const { t } = useI18n()
const { createConfirm, createMessage } = useMessage()
const [registerModal, { openModal }] = useModal()
const [registerTable, { getForm, reload }] = useTable({
title: '业务线/仓库列表',
api: getBusinessWarehousePage,
columns,
formConfig: { labelWidth: 120, schemas: searchFormSchema },
useSearchForm: true,
showTableSetting: true,
actionColumn: {
width: 140,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right'
}
})
function handleCreate() {
openModal(true, { isUpdate: false })
}
function handleEdit(record: Recordable) {
openModal(true, { record, isUpdate: true })
}
async function handleExport() {
createConfirm({
title: t('common.exportTitle'),
iconType: 'warning',
content: t('common.exportMessage'),
async onOk() {
await exportBusinessWarehouse(getForm().getFieldsValue())
createMessage.success(t('common.exportSuccessText'))
}
})
}
async function handleDelete(record: Recordable) {
await deleteBusinessWarehouse(record.id)
createMessage.success(t('common.delSuccessText'))
reload()
}
</script>

@ -1,57 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="isUpdate ? t('action.edit') : t('action.create')" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, unref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { BasicForm, useForm } from '@/components/Form'
import { BasicModal, useModalInner } from '@/components/Modal'
import { createFormSchema, updateFormSchema } from './enterprise.data'
import { createEnterprise, getEnterprise, updateEnterprise } from '@/api/system/enterprise'
defineOptions({ name: 'EnterpriseModal' })
const { t } = useI18n()
const { createMessage } = useMessage()
const emit = defineEmits(['success', 'register'])
const isUpdate = ref(true)
const [registerForm, { setFieldsValue, resetFields, resetSchema, validate }] = useForm({
labelWidth: 120,
baseColProps: { span: 24 },
schemas: createFormSchema,
showActionButtonGroup: false,
actionColOptions: { span: 23 }
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields()
setModalProps({ confirmLoading: false })
isUpdate.value = !!data?.isUpdate
if (unref(isUpdate)) {
resetSchema(updateFormSchema)
const res = await getEnterprise(data.record.id)
setFieldsValue({ ...res })
}
})
async function handleSubmit() {
try {
const values = await validate()
setModalProps({ confirmLoading: true })
if (unref(isUpdate)) {
await updateEnterprise(values)
} else {
await createEnterprise(values)
}
closeModal()
emit('success')
createMessage.success(t('common.saveSuccessText'))
} finally {
setModalProps({ confirmLoading: false })
}
}
</script>

@ -1,814 +0,0 @@
import { BasicColumn, FormSchema, useRender } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
export const columns: BasicColumn[] = [
// {
// title: '编号',
// dataIndex: 'id',
// width: 160
// },
{
title: '企业名称',
dataIndex: 'name',
width: 160
},
{
title: '机构类型',
dataIndex: 'enterpriseType',
width: 180,
customRender: ({ text }) => {
return useRender.renderDict(text, DICT_TYPE.ENTERPRISE_TYPE)
}
},
{
title: '关联子公司(没弄)',
dataIndex: '',
width: 160
},
{
title: '包含业务线(没弄)',
dataIndex: '',
width: 160
},
{
title: '关联员工(没弄)',
dataIndex: '',
width: 160
},
{
title: '首联系人',
dataIndex: 'firstConcat',
width: 160
},
{
title: '联系电话',
dataIndex: 'phone',
width: 160
},
{
title: '更新时间',
dataIndex: 'updateTime',
width: 180,
customRender: ({ text }) => {
return useRender.renderDate(text)
}
},
// {
// title: '企业简称',
// dataIndex: 'shortName',
// width: 160
// },
// {
// title: '主体类型',
// dataIndex: 'mainType',
// width: 180,
// customRender: ({ text }) => {
// return useRender.renderDict(text, DICT_TYPE.MAIN_TYPE)
// }
// },
// {
// title: '企业代码',
// dataIndex: 'code',
// width: 160
// },
// {
// title: '社会统一信息代码',
// dataIndex: 'societyCode',
// width: 160
// },
// {
// title: '办理人(0法人 1代办人)',
// dataIndex: 'transactors',
// width: 160
// },
// {
// title: '实际操作人(0法人 1代办人)',
// dataIndex: 'operator',
// width: 160
// },
// {
// title: '法人证件有效期类型(0长期 1非长期)',
// dataIndex: 'legalOperator',
// width: 160
// },
// {
// title: '代办人证件类型(0身份证 1护照)',
// dataIndex: 'commissionCertificateType',
// width: 160
// },
// {
// title: '代办人证件有效期类型(0长期 1非长期)',
// dataIndex: 'commissionOperator',
// width: 160
// },
// {
// title: '创建时间',
// dataIndex: 'createTime',
// width: 180,
// customRender: ({ text }) => {
// return useRender.renderDate(text)
// }
// },
// {
// title: '企业id',
// dataIndex: 'parentId',
// width: 160
// },
]
export const searchFormSchema: FormSchema[] = [
{
label: '企业名称',
field: 'name',
component: 'Input',
colProps: { span: 8 }
},
// {
// label: '主体类型',
// field: 'mainType',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.MAIN_TYPE)
// },
// colProps: { span: 8 }
// },
// {
// label: '企业代码',
// field: 'code',
// component: 'Input',
// colProps: { span: 8 }
// },
// {
// label: '社会统一信息代码',
// field: 'societyCode',
// component: 'Input',
// colProps: { span: 8 }
// },
// {
// label: '办理人(0法人 1代办人)',
// field: 'transactors',
// component: 'Input',
// colProps: { span: 8 }
// },
// {
// label: '实际操作人(0法人 1代办人)',
// field: 'operator',
// component: 'Input',
// colProps: { span: 8 }
// },
// {
// label: '法人证件有效期类型(0长期 1非长期)',
// field: 'legalOperator',
// component: 'Input',
// colProps: { span: 8 }
// },
// {
// label: '代办人证件类型(0身份证 1护照)',
// field: 'commissionCertificateType',
// component: 'Select',
// componentProps: {
// options: []
// },
// colProps: { span: 8 }
// },
// {
// label: '代办人证件有效期类型(0长期 1非长期)',
// field: 'commissionOperator',
// component: 'Input',
// colProps: { span: 8 }
// },
// {
// label: '创建时间',
// field: 'createTime',
// component: 'RangePicker',
// colProps: { span: 8 }
// },
// {
// label: '企业id',
// field: 'parentId',
// component: 'Input',
// colProps: { span: 8 }
// },
// {
// label: '总公司,子公司机构类型',
// field: 'enterpriseType',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.ENTERPRISE_TYPE)
// },
// colProps: { span: 8 }
// },
]
export const createFormSchema: FormSchema[] = [
{
label: '编号',
field: 'id',
show: false,
component: 'Input'
},
{
label: '企业名称',
field: 'name',
required: true,
component: 'Input'
},
// {
// label: '企业简称',
// field: 'shortName',
// component: 'Input'
// },
// {
// label: '主体类型',
// field: 'mainType',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.MAIN_TYPE, 'number')
// }
// },
// {
// label: '所在城市',
// field: 'city',
// component: 'Input'
// },
// {
// label: '行业类型',
// field: 'dutyType',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.DUTY_TYPE, 'number')
// }
// },
{
label: '首联系人',
field: 'firstConcat',
component: 'Input'
},
// {
// label: '职位',
// field: 'position',
// component: 'Input'
// },
{
label: '手机号码',
field: 'phone',
component: 'Input'
},
// {
// label: 'logo图片',
// field: 'logo',
// component: 'FileUpload',
// componentProps: {
// fileType: 'file',
// maxCount: 1
// }
// },
// {
// label: '地址',
// field: 'address',
// component: 'Input'
// },
// {
// label: '企业电话',
// field: 'enterprisePhone',
// component: 'Input'
// },
// {
// label: '企业传真',
// field: 'enterpriseFax',
// component: 'Input'
// },
// {
// label: '企业网址',
// field: 'enterpriseWebsite',
// component: 'Input'
// },
// {
// label: '企业简介',
// field: 'enterpriseRemark',
// component: 'InputTextArea'
// },
// {
// label: '税号',
// field: 'dutyParagraph',
// component: 'Input'
// },
// {
// label: '发票抬头',
// field: 'invoiceHeader',
// component: 'Input'
// },
// {
// label: '开户银行',
// field: 'openBank',
// component: 'Input'
// },
// {
// label: '银行卡号',
// field: 'bankAccount',
// component: 'Input'
// },
// {
// label: '银行电话',
// field: 'bankPhone',
// component: 'Input'
// },
// {
// label: '注册地址',
// field: 'registerAddress',
// component: 'Input'
// },
// {
// label: '经营开始时间',
// field: 'startDate',
// component: 'DatePicker'
// },
// {
// label: '经营结束时间',
// field: 'endDate',
// component: 'DatePicker'
// },
// {
// label: '证件照',
// field: 'photo',
// component: 'FileUpload',
// componentProps: {
// fileType: 'file',
// maxCount: 1
// }
// },
// {
// label: '经营范围',
// field: 'businessScope',
// component: 'InputTextArea'
// },
// {
// label: '邮箱',
// field: 'email',
// component: 'Input'
// },
// {
// label: '法人证件照1',
// field: 'legalPersonPhoto1',
// component: 'FileUpload',
// componentProps: {
// fileType: 'file',
// maxCount: 1
// }
// },
// {
// label: '法人证件照2',
// field: 'legalPersonPhoto2',
// component: 'FileUpload',
// componentProps: {
// fileType: 'file',
// maxCount: 1
// }
// },
// {
// label: '法人证件照3',
// field: 'legalPersonPhoto3',
// component: 'FileUpload',
// componentProps: {
// fileType: 'file',
// maxCount: 1
// }
// },
// {
// label: '法人证件类型(0身份证 1护照)',
// field: 'legalCertificateType',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.CERTIFICATE_TYPE, 'number')
// }
// },
// {
// label: '法人姓名',
// field: 'legalPersonName',
// component: 'Input'
// },
// {
// label: '法人证件号',
// field: 'legalCardNo',
// component: 'Input'
// },
// {
// label: '法人生日',
// field: 'legalBirthday',
// component: 'Input'
// },
// {
// label: '法人证件有效开始时间',
// field: 'legalCardStart',
// component: 'DatePicker'
// },
// {
// label: '法人证件有效结束时间',
// field: 'legalCardEnd',
// component: 'DatePicker'
// },
// {
// label: '代办人证件照1',
// field: 'commissionPersonPhoto1',
// component: 'FileUpload',
// componentProps: {
// fileType: 'file',
// maxCount: 1
// }
// },
// {
// label: '代办人证件照2',
// field: 'commissionPersonPhoto2',
// component: 'FileUpload',
// componentProps: {
// fileType: 'file',
// maxCount: 1
// }
// },
// {
// label: '代办人证件照3',
// field: 'commissionPersonPhoto3',
// component: 'FileUpload',
// componentProps: {
// fileType: 'file',
// maxCount: 1
// }
// },
// {
// label: '代办人证件照4',
// field: 'commissionPersonPhoto4',
// component: 'FileUpload',
// componentProps: {
// fileType: 'file',
// maxCount: 1
// }
// },
// {
// label: '代办人姓名',
// field: 'commissionPersonName',
// component: 'Input'
// },
// {
// label: '代办人证件号',
// field: 'commissionCardNo',
// component: 'Input'
// },
// {
// label: '代办人生日',
// field: 'commissionBirthday',
// component: 'Input'
// },
// {
// label: '代办人证件有效开始时间',
// field: 'commissionCardStart',
// component: 'DatePicker'
// },
// {
// label: '代办人证件有效结束时间',
// field: 'commissionCardEnd',
// component: 'DatePicker'
// },
{
label: '描述',
field: 'description',
component: 'InputTextArea'
},
// {
// label: '企业代码',
// field: 'code',
// component: 'Input'
// },
// {
// label: '社会统一信息代码',
// field: 'societyCode',
// component: 'Input'
// },
// {
// label: '办理人(0法人 1代办人)',
// field: 'transactors',
// component: 'Input'
// },
// {
// label: '实际操作人(0法人 1代办人)',
// field: 'operator',
// component: 'Input'
// },
// {
// label: '法人证件有效期类型(0长期 1非长期)',
// field: 'legalOperator',
// component: 'Input'
// },
// {
// label: '代办人证件类型(0身份证 1护照)',
// field: 'commissionCertificateType',
// component: 'Select',
// componentProps: {
// options:[]
// }
// },
// {
// label: '代办人证件有效期类型(0长期 1非长期)',
// field: 'commissionOperator',
// component: 'Input'
// },
{
label: '企业id',
field: 'parentId',
component: 'Input'
},
{
label: '上级机构',
field: 'enterpriseType',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.ENTERPRISE_TYPE, 'number')
}
},
]
export const updateFormSchema: FormSchema[] = [
// {
// label: '编号',
// field: 'id',
// show: false,
// component: 'Input'
// },
{
label: '企业名称',
field: 'name',
required: true,
component: 'Input'
},
{
label: '企业id',
field: 'parentId',
component: 'Input'
},
{
label: '首联系人',
field: 'firstConcat',
component: 'Input'
},
{
label: '手机号码',
field: 'phone',
component: 'Input'
},
{
label: '机构描述',
field: 'description',
component: 'InputTextArea'
},
// {
// label: '企业简称',
// field: 'shortName',
// component: 'Input'
// },
// {
// label: '主体类型',
// field: 'mainType',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.MAIN_TYPE, 'number')
// }
// },
// {
// label: '所在城市',
// field: 'city',
// component: 'Input'
// },
// {
// label: '行业类型',
// field: 'dutyType',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.DUTY_TYPE, 'number')
// }
// },
// {
// label: 'logo图片',
// field: 'logo',
// component: 'Upload'
// },
// {
// label: '地址',
// field: 'address',
// component: 'Input'
// },
// {
// label: '企业电话',
// field: 'enterprisePhone',
// component: 'Input'
// },
// {
// label: '企业传真',
// field: 'enterpriseFax',
// component: 'Input'
// },
// {
// label: '企业网址',
// field: 'enterpriseWebsite',
// component: 'Input'
// },
// {
// label: '企业简介',
// field: 'enterpriseRemark',
// component: 'InputTextArea'
// },
// {
// label: '税号',
// field: 'dutyParagraph',
// component: 'Input'
// },
// {
// label: '发票抬头',
// field: 'invoiceHeader',
// component: 'Input'
// },
// {
// label: '开户银行',
// field: 'openBank',
// component: 'Input'
// },
// {
// label: '银行卡号',
// field: 'bankAccount',
// component: 'Input'
// },
// {
// label: '银行电话',
// field: 'bankPhone',
// component: 'Input'
// },
// {
// label: '注册地址',
// field: 'registerAddress',
// component: 'Input'
// },
// {
// label: '经营开始时间',
// field: 'startDate',
// component: 'DatePicker'
// },
// {
// label: '经营结束时间',
// field: 'endDate',
// component: 'DatePicker'
// },
// {
// label: '证件照',
// field: 'photo',
// component: 'Upload'
// },
// {
// label: '经营范围',
// field: 'businessScope',
// component: 'InputTextArea'
// },
// {
// label: '邮箱',
// field: 'email',
// component: 'Input'
// },
// {
// label: '法人证件照1',
// field: 'legalPersonPhoto1',
// component: 'Upload'
// },
// {
// label: '法人证件照2',
// field: 'legalPersonPhoto2',
// component: 'Upload'
// },
// {
// label: '法人证件照3',
// field: 'legalPersonPhoto3',
// component: 'Upload'
// },
// {
// label: '法人证件类型(0身份证 1护照)',
// field: 'legalCertificateType',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.CERTIFICATE_TYPE, 'number')
// }
// },
// {
// label: '法人姓名',
// field: 'legalPersonName',
// component: 'Input'
// },
// {
// label: '法人证件号',
// field: 'legalCardNo',
// component: 'Input'
// },
// {
// label: '法人生日',
// field: 'legalBirthday',
// component: 'Input'
// },
// {
// label: '法人证件有效开始时间',
// field: 'legalCardStart',
// component: 'DatePicker'
// },
// {
// label: '法人证件有效结束时间',
// field: 'legalCardEnd',
// component: 'DatePicker'
// },
// {
// label: '代办人证件照1',
// field: 'commissionPersonPhoto1',
// component: 'Upload'
// },
// {
// label: '代办人证件照2',
// field: 'commissionPersonPhoto2',
// component: 'Upload'
// },
// {
// label: '代办人证件照3',
// field: 'commissionPersonPhoto3',
// component: 'Upload'
// },
// {
// label: '代办人证件照4',
// field: 'commissionPersonPhoto4',
// component: 'Upload'
// },
// {
// label: '代办人姓名',
// field: 'commissionPersonName',
// component: 'Input'
// },
// {
// label: '代办人证件号',
// field: 'commissionCardNo',
// component: 'Input'
// },
// {
// label: '代办人生日',
// field: 'commissionBirthday',
// component: 'Input'
// },
// {
// label: '代办人证件有效开始时间',
// field: 'commissionCardStart',
// component: 'DatePicker'
// },
// {
// label: '代办人证件有效结束时间',
// field: 'commissionCardEnd',
// component: 'DatePicker'
// },
// {
// label: '企业代码',
// field: 'code',
// component: 'Input'
// },
// {
// label: '社会统一信息代码',
// field: 'societyCode',
// component: 'Input'
// },
// {
// label: '办理人(0法人 1代办人)',
// field: 'transactors',
// component: 'Input'
// },
// {
// label: '实际操作人(0法人 1代办人)',
// field: 'operator',
// component: 'Input'
// },
// {
// label: '法人证件有效期类型(0长期 1非长期)',
// field: 'legalOperator',
// component: 'Input'
// },
// {
// label: '代办人证件类型(0身份证 1护照)',
// field: 'commissionCertificateType',
// component: 'Select',
// componentProps: {
// options:[]
// }
// },
// {
// label: '代办人证件有效期类型(0长期 1非长期)',
// field: 'commissionOperator',
// component: 'Input'
// },
// {
// label: '总公司,子公司机构类型',
// field: 'enterpriseType',
// component: 'Select',
// componentProps: {
// options: getDictOptions(DICT_TYPE.ENTERPRISE_TYPE, 'number')
// }
// },
]

@ -1,92 +0,0 @@
<template>
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" v-auth="['system:enterprise:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
{{ t('action.create') }}
</a-button>
<a-button type="warning" v-auth="['system:enterprise:export']" :preIcon="IconEnum.EXPORT" @click="handleExport">
{{ t('action.export') }}
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:enterprise:update', onClick: handleEdit.bind(null, record) },
{
icon: IconEnum.DELETE,
color: 'error',
label: t('action.delete'),
auth: 'system:enterprise:delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',
confirm: handleDelete.bind(null, record)
}
}
]"
/>
</template>
</template>
</BasicTable>
<EnterpriseModal @register="registerModal" @success="reload()" />
</div>
</template>
<script lang="ts" setup>
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { useModal } from '@/components/Modal'
import EnterpriseModal from './EnterpriseModal.vue'
import { IconEnum } from '@/enums/appEnum'
import { BasicTable, useTable, TableAction } from '@/components/Table'
import { deleteEnterprise, exportEnterprise, getEnterprisePage } from '@/api/system/enterprise'
import { columns, searchFormSchema } from './enterprise.data'
defineOptions({ name: 'Enterprise' })
const { t } = useI18n()
const { createConfirm, createMessage } = useMessage()
const [registerModal, { openModal }] = useModal()
const [registerTable, { getForm, reload }] = useTable({
title: '分支机构',
api: getEnterprisePage,
columns,
formConfig: { labelWidth: 120, schemas: searchFormSchema },
useSearchForm: true,
showTableSetting: true,
actionColumn: {
width: 140,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right'
}
})
function handleCreate() {
openModal(true, { isUpdate: false })
}
function handleEdit(record: Recordable) {
openModal(true, { record, isUpdate: true })
}
async function handleExport() {
createConfirm({
title: t('common.exportTitle'),
iconType: 'warning',
content: t('common.exportMessage'),
async onOk() {
await exportEnterprise(getForm().getFieldsValue())
createMessage.success(t('common.exportSuccessText'))
}
})
}
async function handleDelete(record: Recordable) {
await deleteEnterprise(record.id)
createMessage.success(t('common.delSuccessText'))
reload()
}
</script>

@ -1,5 +1,6 @@
package com.yunxi.scm.framework.mybatis.core.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.yunxi.scm.framework.common.pojo.PageParam;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.framework.mybatis.core.util.MyBatisUtils;
@ -18,7 +19,7 @@ import java.util.List;
/**
* MyBatis Plus BaseMapper
*/
public interface BaseMapperX<T> extends BaseMapper<T> {
public interface BaseMapperX<T> extends MPJBaseMapper<T> {
default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
// MyBatis Plus 查询

@ -169,6 +169,9 @@ public interface ErrorCodeConstants {
// ========== 业务线表 TODO 补充编号 ==========
ErrorCode BUSINESS_WAREHOUSE_NOT_EXISTS = new ErrorCode(1002025019, "业务线表不存在");
// ========== 业务线和用户关联 TODO 补充编号 ==========
ErrorCode BUSINESS_USER_RELATIONAL_NOT_EXISTS = new ErrorCode(1002025020, "业务线和用户关联不存在");
// ========== 业务线和机构关联 TODO 补充编号 ==========
ErrorCode BUSINESS_ENTERPRISE_RELATIONAL_NOT_EXISTS = new ErrorCode(1002025021, "业务线和机构关联不存在");
}

@ -0,0 +1,18 @@
package com.yunxi.scm.module.system.enums.business;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum BusinessEnum {
ENABLE("0"), // 启用
DISABLE("1"); // 禁用
/**
*
*/
private final String status;
}

@ -22,4 +22,10 @@ public enum MenuTypeEnum {
*/
private final Integer type;
// 判断是否不为目录类型
public static boolean isNoDIR(Integer type) {
return !DIR.getType().equals(type);
}
}

@ -27,4 +27,7 @@ public class AuthLoginRespVO {
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime expiresTime;
@Schema(description = "租户id", requiredMode = Schema.RequiredMode.REQUIRED)
private Long tenantId;
}

@ -1,5 +1,9 @@
package com.yunxi.scm.module.system.controller.admin.auth.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.yunxi.scm.module.system.dal.dataobject.businesswarehouse.BusinessWarehouseDO;
import com.yunxi.scm.module.system.dal.dataobject.enterprise.EnterpriseDO;
import com.yunxi.scm.module.system.dal.dataobject.tenant.TenantDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -44,6 +48,15 @@ public class AuthPermissionInfoRespVO {
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.jpg")
private String avatar;
private List<EnterpriseDO> enterpriseList;
private List<BusinessWarehouseDO> businessWarehouseList;
private EnterpriseDO enterprise;
private List<TenantDO> tenantDOList;
private TenantDO tenantDO;
}
@Schema(description = "管理后台 - 登录用户的菜单信息 Response VO")

@ -0,0 +1,102 @@
package com.yunxi.scm.module.system.controller.admin.businessenterpriserelational;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.framework.common.pojo.CommonResult;
import static com.yunxi.scm.framework.common.pojo.CommonResult.success;
import com.yunxi.scm.framework.excel.core.util.ExcelUtils;
import com.yunxi.scm.framework.operatelog.core.annotations.OperateLog;
import static com.yunxi.scm.framework.operatelog.core.enums.OperateTypeEnum.*;
import com.yunxi.scm.module.system.controller.admin.businessenterpriserelational.vo.*;
import com.yunxi.scm.module.system.dal.dataobject.businessenterpriserelational.BusinessEnterpriseRelationalDO;
import com.yunxi.scm.module.system.convert.businessenterpriserelational.BusinessEnterpriseRelationalConvert;
import com.yunxi.scm.module.system.service.businessenterpriserelational.BusinessEnterpriseRelationalService;
@Tag(name = "管理后台 - 业务线和机构关联")
@RestController
@RequestMapping("/system/business-enterprise-relational")
@Validated
public class BusinessEnterpriseRelationalController {
@Resource
private BusinessEnterpriseRelationalService businessEnterpriseRelationalService;
@PostMapping("/create")
@Operation(summary = "创建业务线和机构关联")
@PreAuthorize("@ss.hasPermission('system:business-enterprise-relational:create')")
public CommonResult<Long> createBusinessEnterpriseRelational(@Valid @RequestBody BusinessEnterpriseRelationalCreateReqVO createReqVO) {
return success(businessEnterpriseRelationalService.createBusinessEnterpriseRelational(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新业务线和机构关联")
@PreAuthorize("@ss.hasPermission('system:business-enterprise-relational:update')")
public CommonResult<Boolean> updateBusinessEnterpriseRelational(@Valid @RequestBody BusinessEnterpriseRelationalUpdateReqVO updateReqVO) {
businessEnterpriseRelationalService.updateBusinessEnterpriseRelational(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除业务线和机构关联")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('system:business-enterprise-relational:delete')")
public CommonResult<Boolean> deleteBusinessEnterpriseRelational(@RequestParam("id") Long id) {
businessEnterpriseRelationalService.deleteBusinessEnterpriseRelational(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得业务线和机构关联")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('system:business-enterprise-relational:query')")
public CommonResult<BusinessEnterpriseRelationalRespVO> getBusinessEnterpriseRelational(@RequestParam("id") Long id) {
BusinessEnterpriseRelationalDO businessEnterpriseRelational = businessEnterpriseRelationalService.getBusinessEnterpriseRelational(id);
return success(BusinessEnterpriseRelationalConvert.INSTANCE.convert(businessEnterpriseRelational));
}
@GetMapping("/list")
@Operation(summary = "获得业务线和机构关联列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('system:business-enterprise-relational:query')")
public CommonResult<List<BusinessEnterpriseRelationalRespVO>> getBusinessEnterpriseRelationalList(@RequestParam("ids") Collection<Long> ids) {
List<BusinessEnterpriseRelationalDO> list = businessEnterpriseRelationalService.getBusinessEnterpriseRelationalList(ids);
return success(BusinessEnterpriseRelationalConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得业务线和机构关联分页")
@PreAuthorize("@ss.hasPermission('system:business-enterprise-relational:query')")
public CommonResult<PageResult<BusinessEnterpriseRelationalRespVO>> getBusinessEnterpriseRelationalPage(@Valid BusinessEnterpriseRelationalPageReqVO pageVO) {
PageResult<BusinessEnterpriseRelationalDO> pageResult = businessEnterpriseRelationalService.getBusinessEnterpriseRelationalPage(pageVO);
return success(BusinessEnterpriseRelationalConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出业务线和机构关联 Excel")
@PreAuthorize("@ss.hasPermission('system:business-enterprise-relational:export')")
@OperateLog(type = EXPORT)
public void exportBusinessEnterpriseRelationalExcel(@Valid BusinessEnterpriseRelationalExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<BusinessEnterpriseRelationalDO> list = businessEnterpriseRelationalService.getBusinessEnterpriseRelationalList(exportReqVO);
// 导出 Excel
List<BusinessEnterpriseRelationalExcelVO> datas = BusinessEnterpriseRelationalConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "业务线和机构关联.xls", "数据", BusinessEnterpriseRelationalExcelVO.class, datas);
}
}

@ -0,0 +1,25 @@
package com.yunxi.scm.module.system.controller.admin.businessenterpriserelational.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import javax.validation.constraints.*;
/**
* 线 Base VO VO 使
* VO Swagger
*/
@Data
public class BusinessEnterpriseRelationalBaseVO {
@Schema(description = "业务线id", requiredMode = Schema.RequiredMode.REQUIRED, example = "3256")
@NotNull(message = "业务线id不能为空")
private Long businessId;
@Schema(description = "企业id", requiredMode = Schema.RequiredMode.REQUIRED, example = "15640")
@NotNull(message = "企业id不能为空")
private Long enterpriseId;
}

@ -0,0 +1,14 @@
package com.yunxi.scm.module.system.controller.admin.businessenterpriserelational.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 业务线和机构关联创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BusinessEnterpriseRelationalCreateReqVO extends BusinessEnterpriseRelationalBaseVO {
}

@ -0,0 +1,31 @@
package com.yunxi.scm.module.system.controller.admin.businessenterpriserelational.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 线 Excel VO
*
* @author
*/
@Data
public class BusinessEnterpriseRelationalExcelVO {
@ExcelProperty("主键id")
private Long id;
@ExcelProperty("业务线id")
private Long businessId;
@ExcelProperty("企业id")
private Long enterpriseId;
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,26 @@
package com.yunxi.scm.module.system.controller.admin.businessenterpriserelational.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.yunxi.scm.framework.common.pojo.PageParam;
import java.time.LocalDateTime;
import org.springframework.format.annotation.DateTimeFormat;
import static com.yunxi.scm.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 业务线和机构关联 Excel 导出 Request VO参数和 BusinessEnterpriseRelationalPageReqVO 是一致的")
@Data
public class BusinessEnterpriseRelationalExportReqVO {
@Schema(description = "业务线id", example = "3256")
private Long businessId;
@Schema(description = "企业id", example = "15640")
private Long enterpriseId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,28 @@
package com.yunxi.scm.module.system.controller.admin.businessenterpriserelational.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.yunxi.scm.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.yunxi.scm.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 业务线和机构关联分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BusinessEnterpriseRelationalPageReqVO extends PageParam {
@Schema(description = "业务线id", example = "3256")
private Long businessId;
@Schema(description = "企业id", example = "15640")
private Long enterpriseId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,19 @@
package com.yunxi.scm.module.system.controller.admin.businessenterpriserelational.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 业务线和机构关联 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BusinessEnterpriseRelationalRespVO extends BusinessEnterpriseRelationalBaseVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "21519")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

@ -0,0 +1,18 @@
package com.yunxi.scm.module.system.controller.admin.businessenterpriserelational.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 业务线和机构关联更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BusinessEnterpriseRelationalUpdateReqVO extends BusinessEnterpriseRelationalBaseVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "21519")
@NotNull(message = "主键id不能为空")
private Long id;
}

@ -0,0 +1,102 @@
package com.yunxi.scm.module.system.controller.admin.businessuserrelational;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.framework.common.pojo.CommonResult;
import static com.yunxi.scm.framework.common.pojo.CommonResult.success;
import com.yunxi.scm.framework.excel.core.util.ExcelUtils;
import com.yunxi.scm.framework.operatelog.core.annotations.OperateLog;
import static com.yunxi.scm.framework.operatelog.core.enums.OperateTypeEnum.*;
import com.yunxi.scm.module.system.controller.admin.businessuserrelational.vo.*;
import com.yunxi.scm.module.system.dal.dataobject.businessuserrelational.BusinessUserRelationalDO;
import com.yunxi.scm.module.system.convert.businessuserrelational.BusinessUserRelationalConvert;
import com.yunxi.scm.module.system.service.businessuserrelational.BusinessUserRelationalService;
@Tag(name = "管理后台 - 业务线和用户关联")
@RestController
@RequestMapping("/system/business-user-relational")
@Validated
public class BusinessUserRelationalController {
@Resource
private BusinessUserRelationalService businessUserRelationalService;
@PostMapping("/create")
@Operation(summary = "创建业务线和用户关联")
@PreAuthorize("@ss.hasPermission('system:business-user-relational:create')")
public CommonResult<Long> createBusinessUserRelational(@Valid @RequestBody BusinessUserRelationalCreateReqVO createReqVO) {
return success(businessUserRelationalService.createBusinessUserRelational(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新业务线和用户关联")
@PreAuthorize("@ss.hasPermission('system:business-user-relational:update')")
public CommonResult<Boolean> updateBusinessUserRelational(@Valid @RequestBody BusinessUserRelationalUpdateReqVO updateReqVO) {
businessUserRelationalService.updateBusinessUserRelational(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除业务线和用户关联")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('system:business-user-relational:delete')")
public CommonResult<Boolean> deleteBusinessUserRelational(@RequestParam("id") Long id) {
businessUserRelationalService.deleteBusinessUserRelational(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得业务线和用户关联")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('system:business-user-relational:query')")
public CommonResult<BusinessUserRelationalRespVO> getBusinessUserRelational(@RequestParam("id") Long id) {
BusinessUserRelationalDO businessUserRelational = businessUserRelationalService.getBusinessUserRelational(id);
return success(BusinessUserRelationalConvert.INSTANCE.convert(businessUserRelational));
}
@GetMapping("/list")
@Operation(summary = "获得业务线和用户关联列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('system:business-user-relational:query')")
public CommonResult<List<BusinessUserRelationalRespVO>> getBusinessUserRelationalList(@RequestParam("ids") Collection<Long> ids) {
List<BusinessUserRelationalDO> list = businessUserRelationalService.getBusinessUserRelationalList(ids);
return success(BusinessUserRelationalConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得业务线和用户关联分页")
@PreAuthorize("@ss.hasPermission('system:business-user-relational:query')")
public CommonResult<PageResult<BusinessUserRelationalRespVO>> getBusinessUserRelationalPage(@Valid BusinessUserRelationalPageReqVO pageVO) {
PageResult<BusinessUserRelationalDO> pageResult = businessUserRelationalService.getBusinessUserRelationalPage(pageVO);
return success(BusinessUserRelationalConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出业务线和用户关联 Excel")
@PreAuthorize("@ss.hasPermission('system:business-user-relational:export')")
@OperateLog(type = EXPORT)
public void exportBusinessUserRelationalExcel(@Valid BusinessUserRelationalExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<BusinessUserRelationalDO> list = businessUserRelationalService.getBusinessUserRelationalList(exportReqVO);
// 导出 Excel
List<BusinessUserRelationalExcelVO> datas = BusinessUserRelationalConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "业务线和用户关联.xls", "数据", BusinessUserRelationalExcelVO.class, datas);
}
}

@ -0,0 +1,25 @@
package com.yunxi.scm.module.system.controller.admin.businessuserrelational.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import javax.validation.constraints.*;
/**
* 线 Base VO VO 使
* VO Swagger
*/
@Data
public class BusinessUserRelationalBaseVO {
@Schema(description = "业务线/仓库id", requiredMode = Schema.RequiredMode.REQUIRED, example = "29863")
@NotNull(message = "业务线/仓库id不能为空")
private Long businessId;
@Schema(description = "用户id", requiredMode = Schema.RequiredMode.REQUIRED, example = "2593")
@NotNull(message = "用户id不能为空")
private Long userId;
}

@ -0,0 +1,14 @@
package com.yunxi.scm.module.system.controller.admin.businessuserrelational.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 业务线和用户关联创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BusinessUserRelationalCreateReqVO extends BusinessUserRelationalBaseVO {
}

@ -0,0 +1,31 @@
package com.yunxi.scm.module.system.controller.admin.businessuserrelational.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 线 Excel VO
*
* @author
*/
@Data
public class BusinessUserRelationalExcelVO {
@ExcelProperty("主键id")
private Long id;
@ExcelProperty("业务线/仓库id")
private Long businessId;
@ExcelProperty("用户id")
private Long userId;
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,26 @@
package com.yunxi.scm.module.system.controller.admin.businessuserrelational.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.yunxi.scm.framework.common.pojo.PageParam;
import java.time.LocalDateTime;
import org.springframework.format.annotation.DateTimeFormat;
import static com.yunxi.scm.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 业务线和用户关联 Excel 导出 Request VO参数和 BusinessUserRelationalPageReqVO 是一致的")
@Data
public class BusinessUserRelationalExportReqVO {
@Schema(description = "业务线/仓库id", example = "29863")
private Long businessId;
@Schema(description = "用户id", example = "2593")
private Long userId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,28 @@
package com.yunxi.scm.module.system.controller.admin.businessuserrelational.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.yunxi.scm.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.yunxi.scm.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 业务线和用户关联分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BusinessUserRelationalPageReqVO extends PageParam {
@Schema(description = "业务线/仓库id", example = "29863")
private Long businessId;
@Schema(description = "用户id", example = "2593")
private Long userId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,19 @@
package com.yunxi.scm.module.system.controller.admin.businessuserrelational.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 业务线和用户关联 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BusinessUserRelationalRespVO extends BusinessUserRelationalBaseVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "17732")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

@ -0,0 +1,18 @@
package com.yunxi.scm.module.system.controller.admin.businessuserrelational.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 业务线和用户关联更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BusinessUserRelationalUpdateReqVO extends BusinessUserRelationalBaseVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "17732")
@NotNull(message = "主键id不能为空")
private Long id;
}

@ -1,5 +1,11 @@
package com.yunxi.scm.module.system.controller.admin.businesswarehouse;
import com.yunxi.scm.framework.common.enums.CommonStatusEnum;
import com.yunxi.scm.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
import com.yunxi.scm.module.system.controller.admin.dept.vo.dept.DeptSimpleRespVO;
import com.yunxi.scm.module.system.convert.dept.DeptConvert;
import com.yunxi.scm.module.system.dal.dataobject.dept.DeptDO;
import com.yunxi.scm.module.system.enums.business.BusinessEnum;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -87,6 +93,14 @@ public class BusinessWarehouseController {
return success(BusinessWarehouseConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/business")
@Operation(summary = "获得业务线分页")
@PreAuthorize("@ss.hasPermission('system:business-warehouse:business')")
public CommonResult<PageResult<BusinessWarehouseRespVO>> getBusinessPage(@Valid BusinessWarehousePageReqVO pageVO) {
PageResult<BusinessWarehouseDO> pageResult = businessWarehouseService.getBusinessPage(pageVO);
return success(BusinessWarehouseConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出业务线表 Excel")
@PreAuthorize("@ss.hasPermission('system:business-warehouse:export')")
@ -99,4 +113,25 @@ public class BusinessWarehouseController {
ExcelUtils.write(response, "业务线表.xls", "数据", BusinessWarehouseExcelVO.class, datas);
}
@GetMapping("/list-all-simple")
@Operation(summary = "获取业务线精简信息列表", description = "只包含被开启的业务线,主要用于前端的下拉选项")
@PreAuthorize("@ss.hasPermission('system:business-warehouse:list-all-simple')")
public CommonResult<List<BusinessSimpleRespVo>> getSimpleBusinessList() {
// 获得业务线列表,只要开启状态的
BusinessWarehousePageReqVO pageReqVO = new BusinessWarehousePageReqVO();
// pageReqVO.setStatus(BusinessEnum.ENABLE.getStatus());
// pageReqVO.setDiffFlag("0");
List<BusinessWarehouseDO> list = businessWarehouseService.getBusinessSimpleList(pageReqVO);
return success(BusinessWarehouseConvert.INSTANCE.convertList03(list));
}
@GetMapping("/business-user")
@Operation(summary = "获得业务线分页")
@PreAuthorize("@ss.hasPermission('system:business-warehouse:business-user')")
public CommonResult<PageResult<BusinessUserVO>> getBusinessUserPage(BusinessUserVO reqVO) {
PageResult<BusinessUserVO> pageResult = businessWarehouseService.getBusinessUserList(reqVO);
return success(pageResult);
}
}

@ -0,0 +1,21 @@
package com.yunxi.scm.module.system.controller.admin.businesswarehouse.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@Schema(description = "管理后台 - 业务线表精简信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BusinessSimpleRespVo {
@Schema(description = "业务线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "业务线名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
@Schema(description = "父部门 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long parentId;
}

@ -0,0 +1,44 @@
package com.yunxi.scm.module.system.controller.admin.businesswarehouse.vo;
import com.yunxi.scm.framework.common.pojo.PageParam;
import com.yunxi.scm.module.system.dal.dataobject.businesswarehouse.BusinessWarehouseDO;
import com.yunxi.scm.module.system.dal.dataobject.user.AdminUserDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.yunxi.scm.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 业务线员工信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BusinessUserVO extends AdminUserDO {
@Schema(description = "帐号状态")
private Integer accountStatus;
@Schema(description = "业务编号")
private Integer businessId;
@Schema(description = "业务名称")
private String businessName;
@Schema(description = "员工编号")
private Integer userId;
@Schema(description = "分页")
private Integer pageNo;
@Schema(description = "分页")
private Integer pageSize;
@Schema(description = "部门名称")
private String deptName;
@Schema(description = "职务名称")
private String postName;
@Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] loginTime;
}

@ -16,4 +16,7 @@ public class BusinessWarehouseRespVO extends BusinessWarehouseBaseVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime updateTime;
}

@ -3,6 +3,7 @@ package com.yunxi.scm.module.system.controller.admin.dept;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yunxi.scm.framework.common.enums.CommonStatusEnum;
import com.yunxi.scm.framework.common.pojo.CommonResult;
import com.yunxi.scm.framework.security.core.util.SecurityFrameworkUtils;
import com.yunxi.scm.module.system.controller.admin.dept.vo.dept.*;
import com.yunxi.scm.module.system.convert.dept.DeptConvert;
import com.yunxi.scm.module.system.dal.dataobject.dept.DeptDO;
@ -13,12 +14,15 @@ import com.yunxi.scm.module.system.service.user.AdminUserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -33,12 +37,14 @@ public class DeptController {
@Resource
private DeptService deptService;
@Resource
private AdminUserMapper adminUserMapper;
private AdminUserService userService;
@PostMapping("create")
@Operation(summary = "创建部门")
@PreAuthorize("@ss.hasPermission('system:dept:create')")
public CommonResult<Long> createDept(@Valid @RequestBody DeptCreateReqVO reqVO) {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
Long deptId = deptService.createDept(reqVO);
return success(deptId);
}
@ -47,6 +53,8 @@ public class DeptController {
@Operation(summary = "更新部门")
@PreAuthorize("@ss.hasPermission('system:dept:update')")
public CommonResult<Boolean> updateDept(@Valid @RequestBody DeptUpdateReqVO reqVO) {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
deptService.updateDept(reqVO);
return success(true);
}
@ -64,6 +72,11 @@ public class DeptController {
@Operation(summary = "获取部门列表")
@PreAuthorize("@ss.hasPermission('system:dept:query')")
public CommonResult<List<DeptRespVO>> getDeptList(DeptListReqVO reqVO) {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
//是子机构,根据机构过滤
if(adminUserDO.getEnterprise() != null && StringUtils.equals(adminUserDO.getEnterprise().getEnterpriseType(), "1")){
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
}
List<DeptDO> list = deptService.getDeptList(reqVO);
list.sort(Comparator.comparing(DeptDO::getSort));
return success(DeptConvert.INSTANCE.convertList(list));
@ -75,6 +88,11 @@ public class DeptController {
// 获得部门列表,只要开启状态的
DeptListReqVO reqVO = new DeptListReqVO();
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
//是子机构,根据机构过滤
if(adminUserDO.getEnterprise() != null && StringUtils.equals(adminUserDO.getEnterprise().getEnterpriseType(), "1")){
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
}
List<DeptDO> list = deptService.getDeptList(reqVO);
// 排序后,返回给前端
list.sort(Comparator.comparing(DeptDO::getSort));
@ -90,4 +108,41 @@ public class DeptController {
return success(DeptConvert.INSTANCE.convert(deptService.getDept(id)));
}
@GetMapping("/list-user-simple")
@Operation(summary = "获取部门用户精简信息列表", description = "只包含被开启的部门,主要用于前端的下拉选项")
public CommonResult<List<DeptSimpleRespVO>> getSimpleDeptUserList() {
// 获得部门列表,只要开启状态的
DeptListReqVO reqVO = new DeptListReqVO();
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
List<DeptDO> list = deptService.getDeptList(reqVO);
// 排序后,返回给前端
list.sort(Comparator.comparing(DeptDO::getSort));
return success(DeptConvert.INSTANCE.convertList02(list));
}
@GetMapping("/list-dept-user")
@Operation(summary = "获取部门和人员列表")
@PreAuthorize("@ss.hasPermission('system:dept:user')")
public CommonResult<List<DeptSimpleRespVO>> getDeptUserList() {
// 获得部门列表,只要开启状态的
DeptListReqVO deptListReqVO = new DeptListReqVO();
deptListReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
List<DeptDO> deptDOList = deptService.getDeptList(deptListReqVO);
//将Dept转化为简单的Dept
List<DeptSimpleRespVO> simpleDeptList = new ArrayList<>(DeptConvert.INSTANCE.convertList02(deptDOList));
deptDOList.forEach(deptDO -> {
List<AdminUserDO> adminUserList = userService.getUserListByDeptIds(Collections.singleton(deptDO.getId()));
for (AdminUserDO adminUserDO : adminUserList){
DeptSimpleRespVO deptSimpleRespVO = new DeptSimpleRespVO();
deptSimpleRespVO.setId(adminUserDO.getId());
deptSimpleRespVO.setParentId(adminUserDO.getDeptId());
deptSimpleRespVO.setName(adminUserDO.getNickname());
simpleDeptList.add(deptSimpleRespVO);
}
});
//将list转为树状
List<DeptSimpleRespVO> list = deptService.buildTree(simpleDeptList,0);
return success(list);
}
}

@ -5,13 +5,18 @@ import com.yunxi.scm.framework.common.pojo.CommonResult;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.framework.excel.core.util.ExcelUtils;
import com.yunxi.scm.framework.operatelog.core.annotations.OperateLog;
import com.yunxi.scm.framework.security.core.util.SecurityFrameworkUtils;
import com.yunxi.scm.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
import com.yunxi.scm.module.system.controller.admin.dept.vo.post.*;
import com.yunxi.scm.module.system.convert.dept.PostConvert;
import com.yunxi.scm.module.system.dal.dataobject.dept.PostDO;
import com.yunxi.scm.module.system.dal.dataobject.user.AdminUserDO;
import com.yunxi.scm.module.system.service.dept.PostService;
import com.yunxi.scm.module.system.service.user.AdminUserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -35,11 +40,15 @@ public class PostController {
@Resource
private PostService postService;
@Resource
private AdminUserService userService;
@PostMapping("/create")
@Operation(summary = "创建岗位")
@PreAuthorize("@ss.hasPermission('system:post:create')")
public CommonResult<Long> createPost(@Valid @RequestBody PostCreateReqVO reqVO) {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
Long postId = postService.createPost(reqVO);
return success(postId);
}
@ -48,6 +57,8 @@ public class PostController {
@Operation(summary = "修改岗位")
@PreAuthorize("@ss.hasPermission('system:post:update')")
public CommonResult<Boolean> updatePost(@Valid @RequestBody PostUpdateReqVO reqVO) {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
postService.updatePost(reqVO);
return success(true);
}
@ -71,8 +82,15 @@ public class PostController {
@GetMapping("/list-all-simple")
@Operation(summary = "获取岗位精简信息列表", description = "只包含被开启的岗位,主要用于前端的下拉选项")
public CommonResult<List<PostSimpleRespVO>> getSimplePostList() {
PostExportReqVO reqVO = new PostExportReqVO();
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
//是子机构,根据机构过滤
if(adminUserDO.getEnterprise() != null && StringUtils.equals(adminUserDO.getEnterprise().getEnterpriseType(), "1")){
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
}
// 获得岗位列表,只要开启状态的
List<PostDO> list = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
List<PostDO> list = postService.getPostList(reqVO);
// 排序后,返回给前端
list.sort(Comparator.comparing(PostDO::getSort));
return success(PostConvert.INSTANCE.convertList02(list));
@ -82,6 +100,11 @@ public class PostController {
@Operation(summary = "获得岗位分页列表")
@PreAuthorize("@ss.hasPermission('system:post:query')")
public CommonResult<PageResult<PostRespVO>> getPostPage(@Validated PostPageReqVO reqVO) {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
//是子机构,根据机构过滤
if(adminUserDO.getEnterprise() != null && StringUtils.equals(adminUserDO.getEnterprise().getEnterpriseType(), "1")){
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
}
return success(PostConvert.INSTANCE.convertPage(postService.getPostPage(reqVO)));
}
@ -90,6 +113,11 @@ public class PostController {
@PreAuthorize("@ss.hasPermission('system:post:export')")
@OperateLog(type = EXPORT)
public void export(HttpServletResponse response, @Validated PostExportReqVO reqVO) throws IOException {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
//是子机构,根据机构过滤
if(adminUserDO.getEnterprise() != null && StringUtils.equals(adminUserDO.getEnterprise().getEnterpriseType(), "1")){
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
}
List<PostDO> posts = postService.getPostList(reqVO);
List<PostExcelVO> data = PostConvert.INSTANCE.convertList03(posts);
// 输出

@ -44,4 +44,6 @@ public class DeptBaseVO {
// @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
@Schema(description = "企业ID", example = "1024")
private Long enterpriseId;
}

@ -13,4 +13,6 @@ public class DeptListReqVO {
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
@Schema(description = "企业id", example = "1")
private Long enterpriseId;
}

@ -23,4 +23,8 @@ public class DeptSimpleRespVO {
@Schema(description = "父部门 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long parentId;
@Schema(description = "子集" )
private List<DeptSimpleRespVO> children;
}

@ -33,4 +33,6 @@ public class PostBaseVO {
@Schema(description = "备注", example = "快乐的备注")
private String remark;
@Schema(description = "企业ID", example = "1024")
private Long enterpriseId;
}

@ -4,6 +4,7 @@ import com.yunxi.scm.framework.excel.core.annotations.DictFormat;
import com.yunxi.scm.framework.excel.core.convert.DictConvert;
import com.yunxi.scm.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
@ -28,4 +29,6 @@ public class PostExcelVO {
@DictFormat(DictTypeConstants.COMMON_STATUS)
private String status;
@Schema(description = "企业id", example = "1")
private Long enterpriseId;
}

@ -16,4 +16,6 @@ public class PostExportReqVO {
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
@Schema(description = "企业id", example = "1")
private Long enterpriseId;
}

@ -15,4 +15,6 @@ public class PostListReqVO extends PostBaseVO {
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
@Schema(description = "企业id", example = "1")
private Long enterpriseId;
}

@ -19,4 +19,6 @@ public class PostPageReqVO extends PageParam {
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
@Schema(description = "企业id", example = "1")
private Long enterpriseId;
}

@ -1,5 +1,6 @@
package com.yunxi.scm.module.system.controller.admin.enterprise;
import com.yunxi.scm.module.system.controller.admin.user.vo.user.UserUpdateStatusReqVO;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -52,6 +53,16 @@ public class EnterpriseController {
return success(true);
}
@PutMapping("/updateStatus")
@Operation(summary = "更新企业状态")
@PreAuthorize("@ss.hasPermission('system:enterprise:updateStatus')")
public CommonResult<Boolean> updateEnterpriseStatus(@Valid @RequestBody EnterpriseUpdateReqVO updateReqVO) {
updateReqVO.setEnterpriseStatus("1");
enterpriseService.updateEnterprise(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除企业信息")
@Parameter(name = "id", description = "编号", required = true)

@ -76,4 +76,7 @@ public class EnterpriseBaseVO {
@Schema(description = "描述")
private String description;
@Schema(description = "企业状态")
private String enterpriseStatus;
}

@ -145,4 +145,6 @@ public class EnterpriseCreateReqVO extends EnterpriseBaseVO {
@Schema(description = "描述", example = "你猜")
private String description;
@Schema(description = "企业状态")
private String enterpriseStatus;
}

@ -62,4 +62,7 @@ public class EnterpriseExportReqVO {
@Schema(description = "描述")
private String description;
@Schema(description = "企业状态")
private String enterpriseStatus;
}

@ -64,4 +64,7 @@ public class EnterprisePageReqVO extends PageParam {
@Schema(description = "描述")
private String description;
@Schema(description = "企业状态")
private String enterpriseStatus;
}

@ -149,4 +149,6 @@ public class EnterpriseUpdateReqVO extends EnterpriseBaseVO {
@Schema(description = "描述", example = "你猜")
private String description;
@Schema(description = "企业状态")
private String enterpriseStatus;
}

@ -5,13 +5,18 @@ import com.yunxi.scm.framework.common.pojo.CommonResult;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.framework.excel.core.util.ExcelUtils;
import com.yunxi.scm.framework.operatelog.core.annotations.OperateLog;
import com.yunxi.scm.framework.security.core.util.SecurityFrameworkUtils;
import com.yunxi.scm.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
import com.yunxi.scm.module.system.controller.admin.permission.vo.role.*;
import com.yunxi.scm.module.system.convert.permission.RoleConvert;
import com.yunxi.scm.module.system.dal.dataobject.permission.RoleDO;
import com.yunxi.scm.module.system.dal.dataobject.user.AdminUserDO;
import com.yunxi.scm.module.system.service.permission.RoleService;
import com.yunxi.scm.module.system.service.user.AdminUserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -35,11 +40,15 @@ public class RoleController {
@Resource
private RoleService roleService;
@Resource
private AdminUserService userService;
@PostMapping("/create")
@Operation(summary = "创建角色")
@PreAuthorize("@ss.hasPermission('system:role:create')")
public CommonResult<Long> createRole(@Valid @RequestBody RoleCreateReqVO reqVO) {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
return success(roleService.createRole(reqVO, null));
}
@ -47,6 +56,8 @@ public class RoleController {
@Operation(summary = "修改角色")
@PreAuthorize("@ss.hasPermission('system:role:update')")
public CommonResult<Boolean> updateRole(@Valid @RequestBody RoleUpdateReqVO reqVO) {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
roleService.updateRole(reqVO);
return success(true);
}
@ -80,14 +91,26 @@ public class RoleController {
@Operation(summary = "获得角色分页")
@PreAuthorize("@ss.hasPermission('system:role:query')")
public CommonResult<PageResult<RoleDO>> getRolePage(RolePageReqVO reqVO) {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
//是子机构,根据机构过滤
if(adminUserDO.getEnterprise() != null && StringUtils.equals(adminUserDO.getEnterprise().getEnterpriseType(), "1")){
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
}
return success(roleService.getRolePage(reqVO));
}
@GetMapping("/list-all-simple")
@Operation(summary = "获取角色精简信息列表", description = "只包含被开启的角色,主要用于前端的下拉选项")
public CommonResult<List<RoleSimpleRespVO>> getSimpleRoleList() {
RoleExportReqVO reqVO = new RoleExportReqVO();
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
//是子机构,根据机构过滤
if(adminUserDO.getEnterprise() != null && StringUtils.equals(adminUserDO.getEnterprise().getEnterpriseType(), "1")){
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
}
// 获得角色列表,只要开启状态的
List<RoleDO> list = roleService.getRoleListByStatus(singleton(CommonStatusEnum.ENABLE.getStatus()));
List<RoleDO> list = roleService.getRoleList(reqVO);
// 排序后,返回给前端
list.sort(Comparator.comparing(RoleDO::getSort));
return success(RoleConvert.INSTANCE.convertList02(list));
@ -97,6 +120,11 @@ public class RoleController {
@OperateLog(type = EXPORT)
@PreAuthorize("@ss.hasPermission('system:role:export')")
public void export(HttpServletResponse response, @Validated RoleExportReqVO reqVO) throws IOException {
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
//是子机构,根据机构过滤
if(adminUserDO.getEnterprise() != null && StringUtils.equals(adminUserDO.getEnterprise().getEnterpriseType(), "1")){
reqVO.setEnterpriseId(adminUserDO.getEnterpriseId());
}
List<RoleDO> list = roleService.getRoleList(reqVO);
List<RoleExcelVO> data = RoleConvert.INSTANCE.convertList03(list);
// 输出

@ -31,4 +31,7 @@ public class RoleBaseVO {
@Schema(description = "备注", example = "我是一个角色")
private String remark;
@Schema(description = "企业ID", example = "1024")
private Long enterpriseId;
}

@ -4,6 +4,7 @@ import com.yunxi.scm.framework.excel.core.annotations.DictFormat;
import com.yunxi.scm.framework.excel.core.convert.DictConvert;
import com.yunxi.scm.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
@ -31,4 +32,5 @@ public class RoleExcelVO {
@DictFormat(DictTypeConstants.COMMON_STATUS)
private String status;
private Long enterpriseId;
}

@ -25,4 +25,5 @@ public class RoleExportReqVO {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
private Long enterpriseId;
}

@ -28,4 +28,5 @@ public class RolePageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
private Long enterpriseId;
}

@ -34,4 +34,6 @@ public class RoleRespVO extends RoleBaseVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
private LocalDateTime createTime;
@Schema(description = "企业ID", example = "1024")
private Long enterpriseId;
}

@ -7,7 +7,9 @@ import com.yunxi.scm.framework.operatelog.core.annotations.OperateLog;
import com.yunxi.scm.module.system.controller.admin.tenant.vo.tenant.*;
import com.yunxi.scm.module.system.convert.tenant.TenantConvert;
import com.yunxi.scm.module.system.dal.dataobject.tenant.TenantDO;
import com.yunxi.scm.module.system.dal.dataobject.user.AdminUserDO;
import com.yunxi.scm.module.system.service.tenant.TenantService;
import com.yunxi.scm.module.system.service.user.AdminUserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
@ -23,6 +25,7 @@ import java.util.List;
import static com.yunxi.scm.framework.common.pojo.CommonResult.success;
import static com.yunxi.scm.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static com.yunxi.scm.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - 租户")
@RestController
@ -31,6 +34,8 @@ public class TenantController {
@Resource
private TenantService tenantService;
@Resource
private AdminUserService userService;
@GetMapping("/get-id-by-name")
@PermitAll
@ -41,6 +46,16 @@ public class TenantController {
return success(tenantDO != null ? tenantDO.getId() : null);
}
@GetMapping("/get-tenantId-by-userName")
@PermitAll
@Operation(summary = "使用租户名,获得租户编号", description = "登录界面,根据用户的租户名,获得租户编号")
@Parameter(name = "name", description = "租户名", required = true, example = "1024")
public CommonResult<Long> getTenantIdByUserName(@RequestParam("name") String name) {
AdminUserDO user = userService.getUserByUsername(name);
TenantDO tenantDO = tenantService.getTenant(user.getTenantId());
return success(tenantDO != null ? tenantDO.getId() : null);
}
@PostMapping("/create")
@Operation(summary = "创建租户")
@PreAuthorize("@ss.hasPermission('system:tenant:create')")

@ -1,6 +1,7 @@
package com.yunxi.scm.module.system.controller.admin.user;
import cn.hutool.core.collection.CollUtil;
import com.yunxi.scm.framework.security.core.util.SecurityFrameworkUtils;
import com.yunxi.scm.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
import com.yunxi.scm.module.system.controller.admin.dept.vo.dept.DeptSimpleRespVO;
import com.yunxi.scm.module.system.controller.admin.user.vo.user.*;
@ -21,6 +22,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -94,6 +96,7 @@ public class UserController {
@PreAuthorize("@ss.hasPermission('system:user:list')")
public CommonResult<PageResult<UserPageItemRespVO>> getUserPage(@Valid UserPageReqVO reqVO) {
// 获得用户分页列表
AdminUserDO adminUserDO = userService.getUser(SecurityFrameworkUtils.getLoginUserId());
PageResult<AdminUserDO> pageResult = userService.getUserPage(reqVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return success(new PageResult<>(pageResult.getTotal())); // 返回空
@ -202,5 +205,4 @@ public class UserController {
list.sort(Comparator.comparing(AdminUserDO::getId));
return success(UserConvert.INSTANCE.convertList04(list));
}
}

@ -65,16 +65,30 @@ public class UserProfileController {
// 获得用户角色
List<RoleDO> userRoles = roleService.getRoleListFromCache(permissionService.getUserRoleIdListByUserId(user.getId()));
resp.setRoles(UserConvert.INSTANCE.convertList(userRoles));
String deptNames = "";
// 获得部门信息
if (user.getDeptId() != null) {
DeptDO dept = deptService.getDept(user.getDeptId());
resp.setDept(UserConvert.INSTANCE.convert02(dept));
deptNames = deptNames + dept.getName() + ",";
}
if(deptNames.length() > 0){
deptNames = deptNames.substring(0, deptNames.length() - 1);
}
resp.setDeptNames(deptNames);
String postNames = "";
// 获得岗位信息
if (CollUtil.isNotEmpty(user.getPostIds())) {
List<PostDO> posts = postService.getPostList(user.getPostIds());
resp.setPosts(UserConvert.INSTANCE.convertList02(posts));
for (PostDO postDO : posts) {
postNames = postNames + postDO.getName() + ",";
}
}
if(postNames.length() > 0){
postNames = postNames.substring(0, postNames.length() - 1);
}
resp.setPostNames(postNames);
// 获得社交用户信息
List<SocialUserDO> socialUsers = socialService.getSocialUserList(user.getId(), UserTypeEnum.ADMIN.getValue());
resp.setSocialUsers(UserConvert.INSTANCE.convertList03(socialUsers));

@ -33,6 +33,41 @@ public class UserProfileRespVO extends UserBaseVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
private LocalDateTime createTime;
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "事业部,传感部")
private String deptNames;
@Schema(description = "职务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "董事长,周经理")
private String postNames;
/**
*
*/
private String nativePlace;
/**
*
*/
private String education;
/**
*
*/
private String speciality;
/**
*
*/
private String graduationInstitution;
/**
*
*/
private LocalDateTime institutionDatatime;
/**
*
*/
private LocalDateTime birthDatetime;
/**
*
*/
private String personalProfile;
/**
*
*/

@ -10,7 +10,7 @@ import javax.validation.constraints.Size;
@Schema(description = "管理后台 - 用户个人信息更新 Request VO")
@Data
public class UserProfileUpdateReqVO {
public class UserProfileUpdateReqVO extends UserProfileRespVO{
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@Size(max = 30, message = "用户昵称长度不能超过 30 个字符")

@ -8,6 +8,7 @@ import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.Set;
/**
@ -51,4 +52,31 @@ public class UserBaseVO {
@Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png")
private String avatar;
@Schema(description = "员工工号", example = "123")
private String jobNumber;
@Schema(description = "微信账号", example = "123")
private String wechatAccount;
@Schema(description = "出生日期", example = "123")
private LocalDateTime birthDatetime;
@Schema(description = "籍贯", example = "123")
private String nativePlace;
@Schema(description = "学历", example = "123")
private String education;
@Schema(description = "专业", example = "123")
private String speciality;
@Schema(description = "毕业院校", example = "123")
private String graduationInstitution;
@Schema(description = "毕业时间", example = "123")
private LocalDateTime institutionDatatime;
@Schema(description = "个人简介", example = "123")
private String personalProfile;
}

@ -28,7 +28,7 @@ public interface AuthConvert {
default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) {
return AuthPermissionInfoRespVO.builder()
.user(AuthPermissionInfoRespVO.UserVO.builder().id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).build())
.user(AuthPermissionInfoRespVO.UserVO.builder().id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).enterprise(user.getEnterprise()).businessWarehouseList(user.getBusinessWarehouseList()).tenantDO(user.getTenantDO()).tenantDOList(user.getTenantDOList()).enterpriseList(user.getEnterpriseList()).build())
.roles(convertSet(roleList, RoleDO::getCode))
// 权限标识信息
.permissions(convertSet(menuList, MenuDO::getPermission))

@ -0,0 +1,34 @@
package com.yunxi.scm.module.system.convert.businessenterpriserelational;
import java.util.*;
import com.yunxi.scm.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import com.yunxi.scm.module.system.controller.admin.businessenterpriserelational.vo.*;
import com.yunxi.scm.module.system.dal.dataobject.businessenterpriserelational.BusinessEnterpriseRelationalDO;
/**
* 线 Convert
*
* @author
*/
@Mapper
public interface BusinessEnterpriseRelationalConvert {
BusinessEnterpriseRelationalConvert INSTANCE = Mappers.getMapper(BusinessEnterpriseRelationalConvert.class);
BusinessEnterpriseRelationalDO convert(BusinessEnterpriseRelationalCreateReqVO bean);
BusinessEnterpriseRelationalDO convert(BusinessEnterpriseRelationalUpdateReqVO bean);
BusinessEnterpriseRelationalRespVO convert(BusinessEnterpriseRelationalDO bean);
List<BusinessEnterpriseRelationalRespVO> convertList(List<BusinessEnterpriseRelationalDO> list);
PageResult<BusinessEnterpriseRelationalRespVO> convertPage(PageResult<BusinessEnterpriseRelationalDO> page);
List<BusinessEnterpriseRelationalExcelVO> convertList02(List<BusinessEnterpriseRelationalDO> list);
}

@ -0,0 +1,34 @@
package com.yunxi.scm.module.system.convert.businessuserrelational;
import java.util.*;
import com.yunxi.scm.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import com.yunxi.scm.module.system.controller.admin.businessuserrelational.vo.*;
import com.yunxi.scm.module.system.dal.dataobject.businessuserrelational.BusinessUserRelationalDO;
/**
* 线 Convert
*
* @author
*/
@Mapper
public interface BusinessUserRelationalConvert {
BusinessUserRelationalConvert INSTANCE = Mappers.getMapper(BusinessUserRelationalConvert.class);
BusinessUserRelationalDO convert(BusinessUserRelationalCreateReqVO bean);
BusinessUserRelationalDO convert(BusinessUserRelationalUpdateReqVO bean);
BusinessUserRelationalRespVO convert(BusinessUserRelationalDO bean);
List<BusinessUserRelationalRespVO> convertList(List<BusinessUserRelationalDO> list);
PageResult<BusinessUserRelationalRespVO> convertPage(PageResult<BusinessUserRelationalDO> page);
List<BusinessUserRelationalExcelVO> convertList02(List<BusinessUserRelationalDO> list);
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save