This commit is contained in:
2023-05-24 11:07:48 +08:00
parent cc981fc956
commit ac6ec65bcc
10 changed files with 466 additions and 122 deletions

31
src/api/config.js Normal file
View File

@ -0,0 +1,31 @@
// 省列表
import request from "@/utils/request";
export function provinceList() {
return request({
url: "/system/region/allProvince",
method: "get",
});
}
// 市列表
export function cityList(provinceCode) {
return request({
url: "/system/region/allCity",
method: "get",
params: {
provinceCode,
},
});
}
// 县区列表
export function districtList(cityCode) {
return request({
url: "/system/region/allArea",
method: "get",
params: {
cityCode,
},
});
}

View File

@ -0,0 +1,202 @@
<template>
<el-form
ref="formRef"
:label-width="`${labelWidth}px`"
:model="modelValue"
:rules="rules"
>
<el-row>
<el-col :span="24">
<el-form-item label="所在地:" required>
<el-row justify="space-between" type="flex">
<el-col :span="7">
<el-form-item prop="provinceCode">
<el-select
v-model="modelValue.provinceCode"
:disabled="provinceSelectList.length === 0"
clearable
filterable
placeholder="请选择"
@change="provinceChanged"
>
<el-option
v-for="item in provinceSelectList"
:key="item.provinceCode"
:label="item.provinceName"
:value="item.provinceCode"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item prop="cityCode">
<el-select
v-model="modelValue.cityCode"
:disabled="citySelectList.length === 0"
clearable
filterable
placeholder="请选择"
@change="cityChanged"
>
<el-option
v-for="item in citySelectList"
:key="item.cityCode"
:label="item.cityName"
:value="item.cityCode"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item prop="areaCode">
<el-select
v-model="modelValue.areaCode"
:disabled="districtSelectList.length === 0"
clearable
filterable
placeholder="请选择"
@change="areaChanged"
>
<el-option
v-for="item in districtSelectList"
:key="item.areaCode"
:label="item.areaName"
:value="item.areaCode"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script name="CityOptions" setup>
import { cityList, districtList, provinceList } from "@/api/config";
import { reactive, ref, toRefs, watch } from "vue";
const props = defineProps({
modelValue: Object,
labelWidth: {
type: Number,
default: 120
}
});
const { modelValue, labelWidth } = toRefs(props);
const formRef = ref(null);
const provinceSelectList = ref([]); // 省
const citySelectList = ref([]); // 市
const districtSelectList = ref([]); // 区\
const data = reactive({
rules: {
provinceCode: [
{ required: true, message: "请选择", trigger: ["change", "blue"] }
],
cityCode: [{ required: true, message: "请选择", trigger: ["change", "blue"] }],
areaCode: [
{ required: true, message: "请选择", trigger: ["change", "blue"] }
]
}
});
const { rules } = toRefs(data);
// 获取 省列表
const getProvinceList = async () => {
const resp = await provinceList();
provinceSelectList.value = resp.data.map((el) => {
return { ...el, provinceCode: el.provinceCode.toString() };
});
};
// 获取市列表
const getCityListByProvinceId = async (provinceId) => {
const { data } = await cityList(provinceId);
citySelectList.value = data.map((el) => {
return {
...el,
cityCode: el.cityCode.toString()
};
});
};
// 根据市id获取县区列表
const getAreaListByCityId = async (cityId) => {
const { data } = await districtList(cityId);
districtSelectList.value = data.map((el) => {
return {
...el,
areaCode: el.areaCode.toString()
};
});
};
// 当省改变时
const provinceChanged = (val) => {
if (val) {
modelValue.value.provinceName = provinceSelectList.value.find(el => el.provinceCode === val)?.provinceName;
} else {
modelValue.value.provinceName = undefined;
}
// 清除市县代码列表
modelValue.value.cityCode = undefined;
modelValue.value.areaCode = undefined;
// 清除市县列表
citySelectList.value = [];
districtSelectList.value = [];
};
// 当市改变时
const cityChanged = (val) => {
if (val) {
modelValue.value.cityName = citySelectList.value.find(el => el.cityCode === val)?.cityName;
} else {
modelValue.value.cityName = undefined;
}
// 清除县区代码列表
modelValue.value.areaCode = undefined;
districtSelectList.value = [];
};
const areaChanged = (val) => {
if (val) {
modelValue.value.areaName = districtSelectList.value.find(el => el.areaCode === val)?.areaName;
} else {
modelValue.value.areaName = undefined;
}
};
const validateForm = async () => {
try {
return await formRef.value.validate();
} catch (error) {
return false;
}
};
watch(
() => modelValue.value.provinceCode,
(val) => {
console.log("changed province");
val && getCityListByProvinceId(val);
},
{
immediate: true
}
);
watch(
() => modelValue.value.cityCode,
(val) => {
console.log("changed city");
val && getAreaListByCityId(val);
},
{
immediate: true
}
);
getProvinceList();
defineExpose({
validateForm
});
</script>

View File

@ -187,7 +187,7 @@ onMounted(async () => {
left: 0;
top: 10px;
padding: 0 10px;
z-index: 202333;
z-index: 120;
}
}
</style>

View File

@ -57,6 +57,10 @@ export const constantRoutes = [
component: () => import("@/views/sign_in_with.vue"),
hidden: true,
},
{
path: "/test",
component: () => import("@/views/test/index.vue"),
},
{
path: "/:pathMatch(.*)*",
component: () => import("@/views/error/404"),

View File

@ -15,6 +15,7 @@
<el-input
v-model="form.serialNumber"
:disabled="!!route.query.id"
maxlength="15"
placeholder="请输入设备编号"
>
<template #append>
@ -35,34 +36,45 @@
</el-form-item>
<el-form-item label="产品" prop="productId">
<!-- <el-input v-model="form.productId" placeholder="请输入产品ID" />-->
<el-select
v-model="form.productId"
:remote-method="getProductOptions"
clearable
filterable
placeholder="请选择产品"
remote
remote-show-suffix
>
<el-option
v-for="item in productOptions"
:key="item.productId"
:label="item.productName"
:value="item.productId"
/>
</el-select>
<el-row>
<el-col :span="12">
<el-select
v-model="form.productId"
:remote-method="getProductOptions"
clearable
disabled
filterable
placeholder="请选择产品"
remote
remote-show-suffix
>
<el-option
v-for="item in productOptions"
:key="item.productId"
:label="item.productName"
:value="item.productId"
/>
</el-select>
</el-col>
<el-col :span="12">
<el-form-item label="产品编号">
<el-input v-model="form.productSn" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="MQTT账号" prop="mqttAccount">
<el-input v-model="form.mqttAccount" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="MQTT密码" prop="mqttPassword">
<el-input v-model="form.mqttPassword" disabled></el-input>
</el-form-item>
</el-col>
<!-- <el-col :span="12">-->
<!-- <el-form-item label="MQTT密码" prop="mqttPassword">-->
<!-- <el-input v-model="form.mqttPassword" disabled></el-input>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
</el-row>
<!-- <el-form-item label="定位方式" prop="locationWay">-->
<!-- <el-select-->
@ -74,21 +86,22 @@
<!-- <el-option :value="3" label="自定义" />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<CityOptions ref="cityRef" v-model="form" :label-width="140" />
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="设备经度" prop="longitude">
<el-input
v-model="form.longitude"
disabled
placeholder="请输入设备经度"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备纬度" prop="latitude">
<el-input
v-model="form.latitude"
placeholder="请输入设备纬度"
<el-input v-model="form.latitude"
disabled
placeholder="请输入设备纬度"
/>
</el-form-item>
</el-col>
@ -128,7 +141,7 @@
round
type="primary"
@click="submitForm"
>编辑
>编辑
</el-button>
</el-row>
</el-col>
@ -156,7 +169,7 @@
</template>
<script setup>
import { onActivated, onMounted, reactive, ref, toRefs } from "vue";
import { onMounted, reactive, ref, toRefs } from "vue";
import { listProduct } from "@/api/product/product";
import OperatingStatus from "@/views/iot/device/detail-panes/OperatingStatus.vue";
import { addDevice, getDevice, updateDevice } from "@/api/iot/device";
@ -167,6 +180,7 @@ import UpgradeLog from "@/views/firmware/log/index.vue";
import MapSelect from "@/components/MapSelect/index.vue";
import { generateRandomString } from "@/utils";
import { listModel } from "@/api/thingsmodel/model";
import CityOptions from "@/components/CityOptions";
const route = useRoute();
@ -176,15 +190,17 @@ const data = reactive({
form: {},
rules: {
deviceName: [
{ required: true, message: "设备名称不能为空", trigger: "blur" },
{ required: true, message: "设备名称不能为空", trigger: "blur" }
],
serialNumber: [
{ required: true, message: "设备编号不能为空", trigger: "blur" },
{ pattern: /^[a-zA-Z0-9]+$/, message: "只能包含字母和数字", trigger: "blur" }
],
productId: [{ required: true, message: "产品ID不能为空", trigger: "blur" }],
},
productId: [{ required: true, message: "产品ID不能为空", trigger: "blur" }]
}
});
const { form, rules } = toRefs(data);
const cityRef = ref();
// 表单重置
function reset() {
@ -210,7 +226,7 @@ function reset() {
imgUrl: null,
createBy: null,
createTime: null,
remark: null,
remark: null
};
if (deviceRef.value) {
deviceRef.value.resetFields();
@ -219,8 +235,9 @@ function reset() {
/** 提交按钮 */
function submitForm() {
deviceRef.value.validate((valid) => {
if (valid) {
deviceRef.value.validate(async (valid) => {
const cityValid = await cityRef.value.validateForm();
if (valid && cityValid) {
if (form.value.deviceId != null) {
updateDevice(form.value).then((response) => {
ElMessage.success("修改成功");
@ -239,7 +256,7 @@ function getProductOptions(keyword) {
listProduct({
productName: keyword,
pageNum: 1,
pageSize: 20,
pageSize: 20
}).then((resp) => {
productOptions.value = resp.rows;
});
@ -261,14 +278,26 @@ const modelList = ref([]);
const getThingsModel = () => {
if (form.value.productId) {
listModel({
productId: form.value.productId,
productId: form.value.productId
}).then((resp) => {
modelList.value = resp.rows ?? [];
});
}
};
// watch(() => form.value.productId, (val) => {
// if (val) {
// form.value.productSn = productOptions.value.find(el => el.productId === val)?.productSn ?? undefined;
// } else {
// form.value.productSn = undefined;
// }
// }, {
// // immediate: true
// });
onMounted(async () => {
getProductOptions();
await getDeviceDetail();
getThingsModel();
// AMap.value = await loadMap(["AMap.PlaceSearch"]);
@ -285,7 +314,7 @@ onMounted(async () => {
});
reset();
getProductOptions();
</script>
<style lang="scss" scoped>

View File

@ -147,7 +147,7 @@
<!-- </el-form-item>-->
<el-form-item>
<el-button icon="Search" type="primary" @click="handleQuery"
>搜索
>搜索
</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
@ -162,7 +162,7 @@
plain
type="primary"
@click="handleAdd"
>新增
>新增
</el-button>
</el-col>
<el-col :span="1.5">
@ -174,7 +174,7 @@
plain
type="success"
@click="handleUpdate"
>修改
>修改
</el-button>
</el-col>
<el-col :span="1.5">
@ -186,7 +186,7 @@
plain
type="danger"
@click="handleDelete"
>删除
>删除
</el-button>
</el-col>
<!-- <el-col :span="1.5">-->
@ -214,32 +214,25 @@
>
<el-table-column align="center" type="selection" width="55" />
<!-- <el-table-column align="center" label="设备ID" prop="deviceId" />-->
<el-table-column align="center" label="设备名称" prop="deviceName" />
<el-table-column align="center" label="设备名称" prop="deviceName" show-overflow-tooltip/>
<el-table-column align="center" label="设备编号" prop="serialNumber" />
<el-table-column align="center" label="产品" prop="productName" />
<!-- <el-table-column align="center" label="用户" prop="userName" />-->
<!-- <el-table-column align="center" label="租户" prop="tenantName" />-->
<!-- <el-table-column align="center" label="固件版本" prop="firmwareVersion" />-->
<el-table-column align="center" label="设备状态" prop="status">
<template #default="{ row }">
<dict-tag
:options="deviceStatusMap"
:value="[row.status]"
effect="dark"
size="small"
/>
</template>
</el-table-column>
<el-table-column align="center" label="产品编码" prop="productSn" />
<!-- <el-table-column align="center" label="信号强度" prop="rssi" />-->
<el-table-column align="center" label="是否启用设备影子" prop="isShadow">
<template #default="{ row }">
<dict-tag
:options="isShadowDict"
:value="[row.isShadow]"
size="small"
/>
</template>
</el-table-column>
<!-- <el-table-column align="center" label="是否启用设备影子" prop="isShadow">-->
<!-- <template #default="{ row }">-->
<!-- <dict-tag-->
<!-- :options="isShadowDict"-->
<!-- :value="[row.isShadow]"-->
<!-- size="small"-->
<!-- />-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column align="center" label="定位方式" prop="locationWay">-->
<!-- <template #default="{ row }">-->
<!-- {{ locationWayMap.find((el) => el.value === row.locationWay)?.label }}-->
@ -250,11 +243,11 @@
label="MQTT账号"
prop="mqttAccount"
></el-table-column>
<el-table-column
align="center"
label="MQTT密码"
prop="mqttPassword"
></el-table-column>
<!-- <el-table-column-->
<!-- align="center"-->
<!-- label="MQTT密码"-->
<!-- prop="mqttPassword"-->
<!-- ></el-table-column>-->
<!-- <el-table-column align="center" label="物模型值" prop="thingsModelValue" />-->
<!-- <el-table-column align="center" label="设备所在地址" prop="networkAddress" />-->
<!-- <el-table-column align="center" label="设备入网IP" prop="networkIp" />-->
@ -279,7 +272,16 @@
</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="设备状态" prop="status">
<template #default="{ row }">
<dict-tag
:options="deviceStatusMap"
:value="[row.status]"
effect="dark"
size="small"
/>
</template>
</el-table-column>
<el-table-column
align="center"
class-name="small-padding fixed-width"
@ -310,7 +312,7 @@
link
type="primary"
@click="handleDelete(scope.row)"
>删除
>删除
</el-button>
</template>
</el-table-column>
@ -334,7 +336,7 @@
label-width="140px"
>
<el-form-item label="设备编号" prop="serialNumber">
<el-input v-model="form.serialNumber" placeholder="请输入设备编号">
<el-input v-model="form.serialNumber" maxlength="15" placeholder="请输入设备编号">
<template #append>
<el-button @click="geneDeivceSn">自动生成</el-button>
</template>
@ -400,18 +402,19 @@
<!-- </el-col>-->
<el-col :span="12"></el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="设备经度" prop="longitude">
<el-input v-model="form.longitude" placeholder="请输入设备经度" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备纬度" prop="latitude">
<el-input v-model="form.latitude" placeholder="请输入设备纬度" />
</el-form-item>
</el-col>
</el-row>
<CityOptions ref="cityRef" v-model="form" :label-width="140" />
<!-- <el-row :gutter="20">-->
<!-- <el-col :span="12">-->
<!-- <el-form-item label="设备经度" prop="longitude">-->
<!-- <el-input v-model="form.longitude" placeholder="请输入设备经度" />-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- <el-col :span="12">-->
<!-- <el-form-item label="设备纬度" prop="latitude">-->
<!-- <el-input v-model="form.latitude" placeholder="请输入设备纬度" />-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- </el-row>-->
<el-form-item label="设备所在地址" prop="networkAddress">
<el-input
v-model="form.networkAddress"
@ -480,29 +483,17 @@
</template>
<script name="Device" setup>
import {
addDevice,
delDevice,
getDevice,
listDevice,
updateDevice,
} from "@/api/iot/device";
import { addDevice, delDevice, getDevice, listDevice, updateDevice } from "@/api/iot/device";
import { listProduct } from "@/api/product/product";
import { deviceStatusMap, isShadowDict } from "@/constant/dict";
import { deviceStatusMap } from "@/constant/dict";
import UserTreeSelect from "@/components/UserTreeSelect/index.vue";
import {
getCurrentInstance,
reactive,
ref,
shallowRef,
toRefs,
watchEffect,
} from "vue";
import { getCurrentInstance, reactive, ref, shallowRef, toRefs, watch, watchEffect } from "vue";
import DictTag from "@/components/DictTag/index.vue";
import { useRouter } from "vue-router";
import { loadMap } from "@/utils/amap";
import MapSelect from "@/components/MapSelect/index.vue";
import { generateRandomString } from "@/utils";
import CityOptions from "@/components/CityOptions";
const router = useRouter();
const { proxy } = getCurrentInstance();
@ -510,10 +501,10 @@ const { proxy } = getCurrentInstance();
const props = defineProps({
productId: {
type: Number,
default: null,
},
default: null
}
});
const cityRef = ref();
const deviceList = ref([]);
const open = ref(false);
const loading = ref(true);
@ -548,17 +539,18 @@ const data = reactive({
latitude: null,
activeTime: null,
summary: null,
imgUrl: null,
imgUrl: null
},
rules: {
deviceName: [
{ required: true, message: "设备名称不能为空", trigger: "blur" },
{ required: true, message: "设备名称不能为空", trigger: "blur" }
],
serialNumber: [
{ required: true, message: "设备编号不能为空", trigger: "blur" },
{ pattern: /^[a-zA-Z0-9]+$/, message: "只能包含字母和数字", trigger: "blur" }
],
productId: [{ required: true, message: "产品ID不能为空", trigger: "blur" }],
},
productId: [{ required: true, message: "产品ID不能为空", trigger: "blur" }]
}
});
const { queryParams, form, rules } = toRefs(data);
@ -608,7 +600,7 @@ function reset() {
imgUrl: null,
createBy: null,
createTime: null,
remark: null,
remark: null
};
proxy.resetForm("deviceRef");
}
@ -619,6 +611,16 @@ function handleQuery() {
getList();
}
watch(() => form.value.productId, (val) => {
if (val) {
form.value.productSn = productOptions.value.find(el => el.productId === val)?.productSn ?? undefined;
} else {
form.value.productSn = undefined;
}
}, {
immediate: true
});
const geneDeivceSn = () => {
form.value.serialNumber = generateRandomString(11);
};
@ -645,7 +647,7 @@ async function handleAdd() {
if (!AMap.value) AMap.value = await loadMap([]);
if (!map.value)
map.value = new AMap.value.Map("map-container", {
zoom: 11,
zoom: 11
});
map.value.on("click", handleMapClick);
}
@ -667,8 +669,9 @@ function handleDetail(row) {
/** 提交按钮 */
function submitForm() {
proxy.$refs["deviceRef"].validate((valid) => {
if (valid) {
proxy.$refs["deviceRef"].validate(async (valid) => {
const cityValid = await cityRef.value.validateForm();
if (valid && cityValid) {
if (form.value.deviceId != null) {
updateDevice(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
@ -677,7 +680,7 @@ function submitForm() {
});
} else {
form.value.mqttAccount = form.value.serialNumber;
form.value.mqttPassword = generateRandomString(11);
// form.value.mqttPassword = generateRandomString(11);
addDevice(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
@ -692,15 +695,16 @@ function submitForm() {
function handleDelete(row) {
const _deviceIds = row.deviceId || ids.value;
proxy.$modal
.confirm('是否确认删除设备编号为"' + _deviceIds + '"的数据项?')
.then(function () {
.confirm("是否确认删除设备编号为\"" + _deviceIds + "\"的数据项?")
.then(function() {
return delDevice(_deviceIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
.catch(() => {
});
}
/** 导出按钮操作 */
@ -708,7 +712,7 @@ function handleExport() {
proxy.download(
"iot/device/export",
{
...queryParams.value,
...queryParams.value
},
`device_${new Date().getTime()}.xlsx`
);
@ -718,7 +722,7 @@ function getProductOptions(keyword) {
listProduct({
productName: keyword,
pageNum: 1,
pageSize: 20,
pageSize: 20
}).then((resp) => {
productOptions.value = resp.rows;
});
@ -738,7 +742,7 @@ const handleMapClick = (event) => {
form.value.latitude = lnglat.lat;
form.value.longitude = lnglat.lng;
const marker = new AMap.value.Marker({
position: lnglat,
position: lnglat
});
map.value.add(marker);
};

View File

@ -236,7 +236,7 @@ function reset() {
categoryId: null,
tenantId: null,
mqttAccount: null,
mqttPassword: null,
// mqttPassword: null,
mqttSecret: null,
status: null,
thingsModelsJson: null,

View File

@ -282,9 +282,9 @@
<el-form-item label="mqtt账号" prop="mqttAccount">
<el-input v-model="form.mqttAccount" placeholder="请输入mqtt账号" />
</el-form-item>
<el-form-item label="mqtt密码" prop="mqttPassword">
<el-input v-model="form.mqttPassword" placeholder="请输入mqtt密码" />
</el-form-item>
<!-- <el-form-item label="mqtt密码" prop="mqttPassword">-->
<!-- <el-input v-model="form.mqttPassword" placeholder="请输入mqtt密码" />-->
<!-- </el-form-item>-->
<el-form-item label="产品秘钥" prop="mqttSecret">
<el-input v-model="form.mqttSecret" placeholder="请输入产品秘钥" />
</el-form-item>
@ -353,7 +353,7 @@ const data = reactive({
categoryId: null,
tenantId: null,
mqttAccount: null,
mqttPassword: null,
// mqttPassword: null,
mqttSecret: null,
status: null,
thingsModelsJson: null,
@ -414,7 +414,7 @@ function reset() {
categoryId: null,
tenantId: null,
mqttAccount: null,
mqttPassword: null,
// mqttPassword: null,
mqttSecret: null,
status: null,
thingsModelsJson: null,

73
src/views/test/index.vue Normal file
View File

@ -0,0 +1,73 @@
<script lang="ts" setup>
import { ref } from "vue";
const showSelectProvinceDialog = ref(true);
const selectedProvinceList = ref([]);
const provinceList = ref([
{ code: "11", name: "北京市" },
{ code: "12", name: "天津市" },
{ code: "13", name: "河北省" },
{ code: "14", name: "山西省" },
{ code: "15", name: "内蒙古自治区" },
{ code: "21", name: "辽宁省" },
{ code: "22", name: "吉林省" },
{ code: "23", name: "黑龙江省" },
{ code: "31", name: "上海市" },
{ code: "32", name: "江苏省" },
{ code: "33", name: "浙江省" },
{ code: "34", name: "安徽省" },
{ code: "35", name: "福建省" },
{ code: "36", name: "江西省" },
{ code: "37", name: "山东省" },
{ code: "41", name: "河南省" },
{ code: "42", name: "湖北省" },
{ code: "43", name: "湖南省" },
{ code: "44", name: "广东省" },
{ code: "45", name: "广西壮族自治区" },
{ code: "46", name: "海南省" },
{ code: "50", name: "重庆市" },
{ code: "51", name: "四川省" },
{ code: "52", name: "贵州省" },
{ code: "53", name: "云南省" },
{ code: "54", name: "西藏自治区" },
{ code: "61", name: "陕西省" },
{ code: "62", name: "甘肃省" },
{ code: "63", name: "青海省" },
{ code: "64", name: "宁夏回族自治区" },
{ code: "65", name: "新疆维吾尔自治区" },
{ code: "71", name: "台湾省" },
{ code: "81", name: "香港特别行政区" },
{ code: "82", name: "澳门特别行政区" }
]);
</script>
<template>
<div class="app-container">
<el-dialog v-model="showSelectProvinceDialog" title="选择省份">
<el-row>
<el-col :span="12">
<el-tag v-for="item in selectedProvinceList" :key="item"
closable style="margin-left: 12px;margin-bottom: 8px" @close="selectedProvinceList=selectedProvinceList.filter(el=>el!==item)">
{{ provinceList.find(el => el.code === item)?.name ?? "" }}
</el-tag>
</el-col>
<el-col :span="12">
<el-table :data="provinceList.filter(el=>!selectedProvinceList.includes(el.code))" max-height="420"
style="min-height: 420px">
<el-table-column label="编号" prop="code" />
<el-table-column label="名称" prop="name" />
<el-table-column>
<template #default="{row}">
<el-button icon="plus" type="primary" @click="selectedProvinceList.push(row.code)">添加省份</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<style lang="scss" scoped></style>

View File

@ -31,7 +31,8 @@ export default defineConfig(({ mode, command }) => {
proxy: {
// https://cn.vitejs.dev/config/#server-proxy
"/dev-api": {
target: "http://117.72.16.89/api",
target: "http://192.168.1.201:1616",
// target: "http://117.72.16.89/api",
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, ""),
},