feat(superManagement): 新增行政区划树组件并集成到表单中
- 新增 AdministrativeDivisionTree组件用于显示行政区划树 - 在 FormProMax 组件中集成行政区划树组件 - 修改 PoliceUnit 页面,将行政区划选择改为使用新的行政区划树组件 - 优化测试页面,添加行政区划树组件的测试
This commit is contained in:
parent
5fe3af2758
commit
b70ab10f95
|
@ -46,6 +46,11 @@ public class TreeNodeVo<T> implements Serializable {
|
||||||
*/
|
*/
|
||||||
@Schema(description = "节点名称")
|
@Schema(description = "节点名称")
|
||||||
private String label;
|
private String label;
|
||||||
|
/**
|
||||||
|
* 是否是叶子节点
|
||||||
|
*/
|
||||||
|
@Schema(description = "是否是叶子节点")
|
||||||
|
private Boolean isLeaf;
|
||||||
/**
|
/**
|
||||||
* 排序
|
* 排序
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -58,10 +58,4 @@ public class RsaUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
RSA rs = new RSA();
|
|
||||||
System.out.println(rs.getPublicKeyBase64());
|
|
||||||
System.out.println(rs.getPrivateKeyBase64());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,16 +63,16 @@ public class WebConfig implements WebMvcConfigurer {
|
||||||
.addPathPatterns("/open/**");
|
.addPathPatterns("/open/**");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void addCorsMappings(CorsRegistry registry) {
|
// public void addCorsMappings(CorsRegistry registry) {
|
||||||
registry.addMapping("/**")
|
// registry.addMapping("/**")
|
||||||
.allowedOriginPatterns("*")
|
// .allowedOriginPatterns("*")
|
||||||
.allowedMethods("GET", "POST", "OPTION", "PUT", "DELETE")
|
// .allowedMethods("GET", "POST", "OPTION", "PUT", "DELETE")
|
||||||
.allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
|
// .allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
|
||||||
"Access-Control-Request-Headers", "Authorization","Token","*")
|
// "Access-Control-Request-Headers", "Authorization","Token","*")
|
||||||
.allowCredentials(true)
|
// .allowCredentials(true)
|
||||||
.maxAge(3600);
|
// .maxAge(3600);
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.changhu.controller;
|
package com.changhu.controller;
|
||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
|
||||||
import com.changhu.common.annotation.CheckOpenApi;
|
import com.changhu.common.annotation.CheckOpenApi;
|
||||||
import com.changhu.common.annotation.JsonBody;
|
import com.changhu.common.annotation.JsonBody;
|
||||||
import com.changhu.common.enums.OpenApiType;
|
import com.changhu.common.enums.OpenApiType;
|
||||||
|
|
|
@ -23,4 +23,12 @@ public interface AdministrativeDivisionMapper extends BaseMapper<AdministrativeD
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
List<TreeNodeVo<String>> treeList(@Param("level") Integer level);
|
List<TreeNodeVo<String>> treeList(@Param("level") Integer level);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据父编码查询子级行政区划
|
||||||
|
*
|
||||||
|
* @param parentCode 父编码
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
List<TreeNodeVo<String>> administrativeDivisionByParentCode(@Param("parentCode") String parentCode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,15 +25,6 @@ public class AdministrativeDivisionServiceImpl extends ServiceImpl<Administrativ
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TreeNodeVo<String>> administrativeDivisionByParentCode(String parentCode) {
|
public List<TreeNodeVo<String>> administrativeDivisionByParentCode(String parentCode) {
|
||||||
return this.lambdaQuery()
|
return baseMapper.administrativeDivisionByParentCode(parentCode);
|
||||||
.eq(AdministrativeDivision::getParentCode, parentCode)
|
|
||||||
.list()
|
|
||||||
.stream()
|
|
||||||
.map(item -> TreeNodeVo.<String>builder()
|
|
||||||
.value(item.getCode())
|
|
||||||
.label(item.getName())
|
|
||||||
.parentValue(item.getParentCode())
|
|
||||||
.build())
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,24 @@ package com.changhu.support.minio;
|
||||||
|
|
||||||
import io.minio.MinioClient;
|
import io.minio.MinioClient;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fileName: MinioProperties
|
* fileName: MinioProperties
|
||||||
* author: LuoZhun
|
* author: LuoZhun
|
||||||
* createTime: 2023/11/10 17:26
|
* createTime: 2023/11/10 17:26
|
||||||
* description: some...
|
* description: some...
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Data
|
@Data
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConfigurationProperties(prefix = "minio")
|
@ConfigurationProperties(prefix = "minio")
|
||||||
|
@ -39,9 +47,43 @@ public class MinioProperties {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MinioClient minioClient() {
|
public MinioClient minioClient() {
|
||||||
|
// Create a trust manager that does not validate certificate chains
|
||||||
|
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||||
|
new X509TrustManager() {
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new X509Certificate[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkClientTrusted(X509Certificate[] certs, String authType) {
|
||||||
|
// Do nothing (trust any client certificate)
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkServerTrusted(X509Certificate[] certs, String authType) {
|
||||||
|
// Do nothing (trust any server certificate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Install the all-trusting trust manager
|
||||||
|
SSLContext sslContext = null;
|
||||||
|
try {
|
||||||
|
sslContext = SSLContext.getInstance("SSL");
|
||||||
|
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Install the all-trusting trust manager error:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a custom OkHttpClient that trusts all certificates
|
||||||
|
OkHttpClient customHttpClient = new OkHttpClient.Builder()
|
||||||
|
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0])
|
||||||
|
.hostnameVerifier((hostname, session) -> true)
|
||||||
|
.build();
|
||||||
|
|
||||||
return MinioClient.builder()
|
return MinioClient.builder()
|
||||||
.endpoint(url)
|
.endpoint(url)
|
||||||
.credentials(accessKey, secretKey)
|
.credentials(accessKey, secretKey)
|
||||||
|
.httpClient(customHttpClient)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ spring:
|
||||||
datasource:
|
datasource:
|
||||||
type: com.alibaba.druid.pool.DruidDataSource
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://118.253.177.137:3306/police_security_dev?serverTimezone=Asia/Shanghai&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
|
url: jdbc:mysql://118.253.177.137:3306/police_security?serverTimezone=Asia/Shanghai&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
|
||||||
username: police_security_dev
|
username: police_security
|
||||||
password: GejDeCNj3ZBSNxSP
|
password: xRxNWErNMKa6Th64
|
||||||
# druid 连接池管理
|
# druid 连接池管理
|
||||||
druid:
|
druid:
|
||||||
# 初始化时建立物理连接的个数
|
# 初始化时建立物理连接的个数
|
||||||
|
@ -119,7 +119,7 @@ minio:
|
||||||
url: https://www.hnjinglian.cn:9000
|
url: https://www.hnjinglian.cn:9000
|
||||||
accessKey: admin
|
accessKey: admin
|
||||||
secretKey: lonsung301
|
secretKey: lonsung301
|
||||||
bucketName: police-security-dev
|
bucketName: police-security
|
||||||
|
|
||||||
sa-token:
|
sa-token:
|
||||||
# token 名称(同时也是 cookie 名称)
|
# token 名称(同时也是 cookie 名称)
|
||||||
|
|
|
@ -12,4 +12,22 @@
|
||||||
<if test="level!=null">and level <= #{level}</if>
|
<if test="level!=null">and level <= #{level}</if>
|
||||||
order by code
|
order by code
|
||||||
</select>
|
</select>
|
||||||
|
<resultMap id="administrativeDivisionByParentCodeVoResultMap" type="com.changhu.common.pojo.vo.TreeNodeVo">
|
||||||
|
<result
|
||||||
|
column="extData"
|
||||||
|
typeHandler="com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler"
|
||||||
|
property="extData"/>
|
||||||
|
</resultMap>
|
||||||
|
<select id="administrativeDivisionByParentCode" resultMap="administrativeDivisionByParentCodeVoResultMap">
|
||||||
|
select ad1.code as 'value',
|
||||||
|
ad1.name as 'label',
|
||||||
|
ad1.parent_code as 'parentValue',
|
||||||
|
any_value(if(count(ad2.snow_flake_id) > 0, false, true)) as 'isLeaf'
|
||||||
|
from administrative_division ad1
|
||||||
|
left join administrative_division ad2 on ad1.code = ad2.parent_code
|
||||||
|
and ad2.delete_flag = 0
|
||||||
|
where ad1.delete_flag = 0
|
||||||
|
and ad1.parent_code = #{parentCode}
|
||||||
|
group by ad1.code
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.changhu;
|
||||||
|
|
||||||
|
import com.changhu.module.management.pojo.params.ManagementSuperUserSaveOrUpdateParams;
|
||||||
|
import com.changhu.module.management.service.SuperService;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/10/30 上午11:23
|
||||||
|
* @desc SuperUserInitTest...
|
||||||
|
*/
|
||||||
|
@SpringBootTest
|
||||||
|
public class SuperUserInitTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SuperService superService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void initAdmin() {
|
||||||
|
ManagementSuperUserSaveOrUpdateParams params = new ManagementSuperUserSaveOrUpdateParams();
|
||||||
|
params.setName("超级管理员");
|
||||||
|
params.setTelephone("15576404472");
|
||||||
|
superService.saveOrUpdateUser(params);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,10 +2,10 @@ VITE_APP_NAME=超级后台
|
||||||
VITE_APP_ENV=development
|
VITE_APP_ENV=development
|
||||||
VITE_APP_PORT=1000
|
VITE_APP_PORT=1000
|
||||||
VITE_DROP_CONSOLE=false
|
VITE_DROP_CONSOLE=false
|
||||||
|
VITE_APP_MODULE_NAME=superManagement
|
||||||
|
|
||||||
# axios
|
# axios
|
||||||
VITE_APP_BASE_API=/api
|
VITE_APP_BASE_API=/api
|
||||||
# VITE_APP_PROXY_URL=http://localhost:8765
|
|
||||||
VITE_APP_PROXY_URL=http://172.10.10.93:8765
|
VITE_APP_PROXY_URL=http://172.10.10.93:8765
|
||||||
|
|
||||||
# rsa 公钥
|
# rsa 公钥
|
||||||
|
|
|
@ -2,11 +2,15 @@ VITE_APP_NAME=超级后台
|
||||||
VITE_APP_ENV=production
|
VITE_APP_ENV=production
|
||||||
VITE_APP_PORT=1001
|
VITE_APP_PORT=1001
|
||||||
VITE_DROP_CONSOLE=true
|
VITE_DROP_CONSOLE=true
|
||||||
|
VITE_APP_MODULE_NAME=superManagement
|
||||||
|
|
||||||
# axios
|
# axios
|
||||||
VITE_APP_BASE_API=/api
|
VITE_APP_BASE_API=/api
|
||||||
VITE_APP_PROXY_URL=https://172.10.10.238:8765
|
VITE_APP_PROXY_URL=http://118.253.177.137:8765
|
||||||
|
|
||||||
|
# rsa 公钥
|
||||||
|
VITE_APP_RSA_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpu1C3JHZ+Ng/eVVCZtwKsOZv9RktpAL13pKy4FoRHyNv2t8TPV2AMzLzfEzlWx001nBxyVxEMR2N9jAcqFLHv7r16ciOzbtzB9dky2G+bc9jIs4/EdVK5bAZcPRh5Jrb78sC9PHyR4AeceDyCIKHLUbWBJB4NTZE0s1Wh5kMynQIDAQAB
|
||||||
|
|
||||||
# minio
|
# minio
|
||||||
VITE_APP_MINIO_URL=http://118.253.177.137:9000
|
VITE_APP_MINIO_URL=https://www.hnjinglian.cn:9000
|
||||||
VITE_APP_MINIO_BUCKET=police-security-dev
|
VITE_APP_MINIO_BUCKET=police-security
|
||||||
|
|
|
@ -9,6 +9,7 @@ lerna-debug.log*
|
||||||
|
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
|
superManagement
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vue-tsc -b && vite build",
|
"build": "vue-tsc -b && vite build --mode production",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
"@types/node": "^22.5.1",
|
"@types/node": "^22.5.1",
|
||||||
"@vitejs/plugin-vue": "^5.1.2",
|
"@vitejs/plugin-vue": "^5.1.2",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||||
|
"terser": "^5.36.0",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"unplugin-vue-components": "^0.27.4",
|
"unplugin-vue-components": "^0.27.4",
|
||||||
"vite": "^5.4.1",
|
"vite": "^5.4.1",
|
||||||
|
|
|
@ -97,6 +97,12 @@
|
||||||
:allowClear="item.componentsProps?.allowClear ?? true"
|
:allowClear="item.componentsProps?.allowClear ?? true"
|
||||||
:options="item.options"
|
:options="item.options"
|
||||||
/>
|
/>
|
||||||
|
<administrative-division-tree-comp
|
||||||
|
v-else-if="item.type==='administrativeDivisionTree'"
|
||||||
|
style="width: 100%"
|
||||||
|
v-model:value="modelValue[field]"
|
||||||
|
v-bind="item.componentsProps"
|
||||||
|
/>
|
||||||
<a-range-picker
|
<a-range-picker
|
||||||
v-else-if="item.type ==='rangePicker'"
|
v-else-if="item.type ==='rangePicker'"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@ -141,11 +147,14 @@
|
||||||
|
|
||||||
<script setup lang="ts" generic="T extends Record<string,any>">
|
<script setup lang="ts" generic="T extends Record<string,any>">
|
||||||
import {FormInstance} from "ant-design-vue";
|
import {FormInstance} from "ant-design-vue";
|
||||||
import {ref} from "vue";
|
import {defineAsyncComponent, ref} from "vue";
|
||||||
import {FormExpose} from "ant-design-vue/es/form/Form";
|
import {FormExpose} from "ant-design-vue/es/form/Form";
|
||||||
import {QuestionCircleOutlined} from '@ant-design/icons-vue'
|
import {QuestionCircleOutlined} from '@ant-design/icons-vue'
|
||||||
import {FormProMaxItemOptions, FormProMaxItemProps, FormProMaxProps} from "@/types/components/form/index.ts";
|
import {FormProMaxItemOptions, FormProMaxItemProps, FormProMaxProps} from "@/types/components/form/index.ts";
|
||||||
|
import {ComponentProps} from "vue-component-type-helpers";
|
||||||
|
import AdministrativeDivisionTree from "@/components/tree/AdministrativeDivisionTree.vue";
|
||||||
|
|
||||||
|
const AdministrativeDivisionTreeComp: ComponentProps<typeof AdministrativeDivisionTree> = defineAsyncComponent(() => import("@/components/tree/AdministrativeDivisionTree.vue"));
|
||||||
|
|
||||||
const modelValue = defineModel<T>('value', {
|
const modelValue = defineModel<T>('value', {
|
||||||
default: {}
|
default: {}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
import {IconFontProps} from "@/types/components/iconfont/IconFont";
|
import {IconFontProps} from "@/types/components/iconfont/IconFont";
|
||||||
|
|
||||||
const props = withDefaults(defineProps<IconFontProps>(), {
|
withDefaults(defineProps<IconFontProps>(), {
|
||||||
size: 25,
|
size: 25,
|
||||||
type: "svg"
|
type: "svg"
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
@click="router.push(item.path)"
|
@click="router.push(item.path)"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-font :font-class="item.icon" :size="item.size"/>
|
<icon-font :font-class="item.icon"/>
|
||||||
<!-- <icon-font font-class="icon-guanlianbaoan" type="class" size="10"/>-->
|
<!-- <icon-font font-class="icon-guanlianbaoan" type="class" size="10"/>-->
|
||||||
</template>
|
</template>
|
||||||
<span class="margin-left-xs">{{ item.title }}</span>
|
<span class="margin-left-xs">{{ item.title }}</span>
|
||||||
|
|
|
@ -14,7 +14,6 @@ import {computed} from "vue";
|
||||||
import {useRoute} from "vue-router";
|
import {useRoute} from "vue-router";
|
||||||
import {SYSTEM_MENUS} from "@/config";
|
import {SYSTEM_MENUS} from "@/config";
|
||||||
import MenuItem from "@/components/layout/MenuItem.vue";
|
import MenuItem from "@/components/layout/MenuItem.vue";
|
||||||
import IconFont from "@/components/iconfont/IconFont.vue";
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref} from 'vue'
|
import {ref} from 'vue'
|
||||||
import {FormInstance, message, notification} from "ant-design-vue";
|
import {FormInstance, notification} from "ant-design-vue";
|
||||||
import {Rule} from "ant-design-vue/es/form";
|
import {Rule} from "ant-design-vue/es/form";
|
||||||
import {LoginParams} from "@/types/views/login.ts";
|
import {LoginParams} from "@/types/views/login.ts";
|
||||||
import api from "@/axios";
|
import api from "@/axios";
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
<template>
|
||||||
|
<a-cascader
|
||||||
|
v-model:value="modelValue"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:change-on-select="changeOnSelect"
|
||||||
|
:options="administrativeDivisionTree"
|
||||||
|
:load-data="loadData"
|
||||||
|
style="width: 500px"
|
||||||
|
:allow-clear="allowClear"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import api from "@/axios";
|
||||||
|
import {onMounted, ref} from "vue";
|
||||||
|
import {CascaderProps} from "ant-design-vue";
|
||||||
|
import {isEmpty} from "lodash-es";
|
||||||
|
|
||||||
|
withDefaults(defineProps<{
|
||||||
|
placeholder?: string,
|
||||||
|
changeOnSelect?: boolean
|
||||||
|
allowClear?: boolean
|
||||||
|
}>(), {
|
||||||
|
placeholder: '请选择行政区划',
|
||||||
|
changeOnSelect: true,
|
||||||
|
allowClear: true
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const modelValue = defineModel('value', {
|
||||||
|
default: []
|
||||||
|
})
|
||||||
|
|
||||||
|
const administrativeDivisionTree = ref<TreeNodeVo<string>[]>([])
|
||||||
|
|
||||||
|
const loadData: CascaderProps['loadData'] = selectedOptions => {
|
||||||
|
const targetOption = selectedOptions[selectedOptions.length - 1];
|
||||||
|
targetOption.loading = true;
|
||||||
|
administrativeDivisionByParentCode(targetOption.value as string).then(data => {
|
||||||
|
targetOption.loading = false
|
||||||
|
targetOption.children = data
|
||||||
|
administrativeDivisionTree.value = [...administrativeDivisionTree.value]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据父级编码查询行政区划
|
||||||
|
* @param code
|
||||||
|
*/
|
||||||
|
const administrativeDivisionByParentCode = async (code: string = '0'): Promise<TreeNodeVo<string>[]> => {
|
||||||
|
const resp = await api.get<TreeNodeVo<string>[]>('/common/administrativeDivisionByParentCode', {
|
||||||
|
parentCode: code
|
||||||
|
})
|
||||||
|
return resp.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
administrativeDivisionTree.value = await administrativeDivisionByParentCode()
|
||||||
|
if (!isEmpty(modelValue.value)) {
|
||||||
|
const ps = modelValue.value.map(code => administrativeDivisionByParentCode(code))
|
||||||
|
Promise.all(ps).then(data => {
|
||||||
|
let i = 0;
|
||||||
|
const deepChildren = (treeData: TreeNodeVo<string>[]) => {
|
||||||
|
treeData.forEach(item => {
|
||||||
|
if (item.value === modelValue.value[i]) {
|
||||||
|
item.children = data[i]
|
||||||
|
i++;
|
||||||
|
deepChildren(item.children)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
deepChildren(administrativeDivisionTree.value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
|
@ -10,10 +10,10 @@ import {ROUTER_WHITE_LIST} from "@/config";
|
||||||
* createWebHashHistory: 路径带#号 这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理,影响SEO
|
* createWebHashHistory: 路径带#号 这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理,影响SEO
|
||||||
*/
|
*/
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(),
|
history: createWebHistory(__APP_ENV.VITE_APP_MODULE_NAME),
|
||||||
routes: [...staticRouter],
|
routes: [...staticRouter],
|
||||||
strict: false,
|
strict: false,
|
||||||
scrollBehavior: () => ({left: 0, top: 0})
|
scrollBehavior: () => ({left: 0, top: 0}),
|
||||||
});
|
});
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
} from "ant-design-vue";
|
} from "ant-design-vue";
|
||||||
import {Ref, UnwrapRef, VNode} from "vue";
|
import {Ref, UnwrapRef, VNode} from "vue";
|
||||||
import {ComponentProps} from "vue-component-type-helpers";
|
import {ComponentProps} from "vue-component-type-helpers";
|
||||||
|
import AdministrativeDivisionTree from "@/components/tree/AdministrativeDivisionTree.vue";
|
||||||
|
|
||||||
type FormProMaxItemType =
|
type FormProMaxItemType =
|
||||||
| 'custom'
|
| 'custom'
|
||||||
|
@ -32,7 +33,8 @@ type FormProMaxItemType =
|
||||||
| 'datePicker'
|
| 'datePicker'
|
||||||
| 'rangePicker'
|
| 'rangePicker'
|
||||||
| 'timeRangePicker'
|
| 'timeRangePicker'
|
||||||
| 'timePicker';
|
| 'timePicker'
|
||||||
|
| 'administrativeDivisionTree'
|
||||||
|
|
||||||
interface FormProMaxItemCommonProps extends ComponentProps<typeof FormItem> {
|
interface FormProMaxItemCommonProps extends ComponentProps<typeof FormItem> {
|
||||||
label?: string,
|
label?: string,
|
||||||
|
@ -64,6 +66,7 @@ export type FormProMaxItemOptions<T> = {
|
||||||
| FormProMaxItemProps<'rangePicker', ComponentProps<typeof RangePicker>>
|
| FormProMaxItemProps<'rangePicker', ComponentProps<typeof RangePicker>>
|
||||||
| FormProMaxItemProps<'timeRangePicker', ComponentProps<typeof TimeRangePicker>>
|
| FormProMaxItemProps<'timeRangePicker', ComponentProps<typeof TimeRangePicker>>
|
||||||
| FormProMaxItemProps<'timePicker', ComponentProps<typeof TimePicker>>
|
| FormProMaxItemProps<'timePicker', ComponentProps<typeof TimePicker>>
|
||||||
|
| FormProMaxItemProps<'administrativeDivisionTree', ComponentProps<typeof AdministrativeDivisionTree>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormProMaxProps<T = {}> extends FormProps {
|
export interface FormProMaxProps<T = {}> extends FormProps {
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
{{ url}}
|
<administrative-division-tree/>
|
||||||
<SingleImageFileUpload
|
123123
|
||||||
v-model:value="url"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import SingleImageFileUpload from "@/components/upload/SingleImageFileUpload.vue";
|
import AdministrativeDivisionTree from "@/components/tree/AdministrativeDivisionTree.vue";
|
||||||
import {ref} from "vue";
|
|
||||||
|
|
||||||
const url = ref<string>('')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
|
@ -25,12 +25,9 @@ import {message, Modal} from "ant-design-vue";
|
||||||
import {UNIT_TYPE} from "@/config";
|
import {UNIT_TYPE} from "@/config";
|
||||||
import {PageParams} from "@/types/hooks/useTableProMax.ts";
|
import {PageParams} from "@/types/hooks/useTableProMax.ts";
|
||||||
import {submitSimpleFormModal, deleteDataModal} from "@/components/tsx/ModalPro.tsx";
|
import {submitSimpleFormModal, deleteDataModal} from "@/components/tsx/ModalPro.tsx";
|
||||||
import useSelectAndTreeNodeVos from "@/hooks/useSelectAndTreeNodeVos.ts";
|
|
||||||
|
|
||||||
type TableProps = TableProMaxProps<PoliceUnitPagerVo, PoliceUnitPagerQueryParams>
|
type TableProps = TableProMaxProps<PoliceUnitPagerVo, PoliceUnitPagerQueryParams>
|
||||||
|
|
||||||
const {administrativeDivisionTree} = useSelectAndTreeNodeVos('administrativeDivisionTree')
|
|
||||||
|
|
||||||
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
|
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
|
||||||
const reqApi: TableProps['requestApi'] = (params) => api.post('/management/super/policeUnit/pager', params)
|
const reqApi: TableProps['requestApi'] = (params) => api.post('/management/super/policeUnit/pager', params)
|
||||||
const columns: TableProps['columns'] = [
|
const columns: TableProps['columns'] = [
|
||||||
|
@ -111,9 +108,8 @@ const searchFormOptions = ref<TableProps["searchFormOptions"]>({
|
||||||
type: 'input',
|
type: 'input',
|
||||||
label: '代码'
|
label: '代码'
|
||||||
}, administrativeDivisionCodes: {
|
}, administrativeDivisionCodes: {
|
||||||
type: 'cascader',
|
type: 'administrativeDivisionTree',
|
||||||
label: '行政区划',
|
label: '行政区划',
|
||||||
options: administrativeDivisionTree
|
|
||||||
}, isEnable: {
|
}, isEnable: {
|
||||||
type: 'select',
|
type: 'select',
|
||||||
label: '是否启用',
|
label: '是否启用',
|
||||||
|
@ -152,13 +148,9 @@ const showEnterprisesUnit = (policeUnitPagerVo: PoliceUnitPagerVo) => {
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
administrativeDivisionCodes: {
|
administrativeDivisionCodes: {
|
||||||
type: 'cascader',
|
type: 'administrativeDivisionTree',
|
||||||
label: '行政区划',
|
label: '行政区划',
|
||||||
required: true,
|
required: true,
|
||||||
options: administrativeDivisionTree.value,
|
|
||||||
componentsProps: {
|
|
||||||
showSearch: true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
address: {
|
address: {
|
||||||
type: 'inputTextArea',
|
type: 'inputTextArea',
|
||||||
|
|
|
@ -6,6 +6,8 @@ interface ImportMetaEnv {
|
||||||
readonly VITE_APP_ENV: 'development' | 'production';
|
readonly VITE_APP_ENV: 'development' | 'production';
|
||||||
// 启动端口
|
// 启动端口
|
||||||
readonly VITE_APP_PORT: number;
|
readonly VITE_APP_PORT: number;
|
||||||
|
// 模块名称
|
||||||
|
readonly VITE_APP_MODULE_NAME: string;
|
||||||
|
|
||||||
// axios
|
// axios
|
||||||
readonly VITE_APP_BASE_API: string;
|
readonly VITE_APP_BASE_API: string;
|
||||||
|
|
|
@ -14,7 +14,7 @@ export default defineConfig(({mode}) => {
|
||||||
define: {
|
define: {
|
||||||
__APP_ENV: JSON.stringify(env)
|
__APP_ENV: JSON.stringify(env)
|
||||||
},
|
},
|
||||||
base: '/',
|
base: `/${env['VITE_APP_MODULE_NAME']}/`,
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
vueJsx(),
|
vueJsx(),
|
||||||
|
@ -43,7 +43,7 @@ export default defineConfig(({mode}) => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
outDir: 'dist',
|
outDir: env['VITE_APP_MODULE_NAME'],
|
||||||
target: 'modules',
|
target: 'modules',
|
||||||
chunkSizeWarningLimit: 1500,
|
chunkSizeWarningLimit: 1500,
|
||||||
minify: 'terser',
|
minify: 'terser',
|
||||||
|
|
Loading…
Reference in New Issue