Commit 30ff0ddc authored by 赵啸非's avatar 赵啸非

Merge remote-tracking branch 'origin/master'

parents abe24930 688954bf
...@@ -69,22 +69,28 @@ ...@@ -69,22 +69,28 @@
<!-- 图片 --> <!-- 图片 -->
<template slot="img" slot-scope="text"> <template slot="img" slot-scope="text">
<img <a-space v-if="text.img">
v-if="text.img" <img
class="pre-item" class="pre-item"
:src="filterRes(text.img)" v-for="(v, i) in filterRes(text.img)"
@click="handlePreview('img', text.img)" :key="i"
/> :src="v"
@click="handlePreview('img', v)"
/>
</a-space>
<span v-else>--</span> <span v-else>--</span>
</template> </template>
<!-- 视频 --> <!-- 视频 -->
<template slot="video" slot-scope="text"> <template slot="video" slot-scope="text">
<video <a-space v-if="text.video">
v-if="text.video" <video
width="50" v-for="(v, i) in filterRes(text.video)"
:src="filterRes(text.video)" :key="i"
@click="handlePreview('video', text.video)" width="50"
/> :src="v"
@click="handlePreview('video', v)"
/>
</a-space>
<span v-else>--</span> <span v-else>--</span>
</template> </template>
<!-- 操作 --> <!-- 操作 -->
...@@ -347,25 +353,19 @@ export default { ...@@ -347,25 +353,19 @@ export default {
}, },
// 过滤影音 // 过滤影音
filterRes(data) { filterRes(data) {
let resource = data.split(",").map((v) => { let resource = data.split(",");
return v; return resource;
});
return resource[0];
}, },
// 预览 // 预览
handlePreview(type, data) { handlePreview(type, url) {
let resource = data.split(",").map((v) => {
return v;
});
if (type == "img") { if (type == "img") {
this.$viewerApi({ this.$viewerApi({
images: resource, images: [url],
}); });
} else { } else {
this.previewData = { this.previewData = {
type, type,
url: resource[0], url,
}; };
this.previewVisible = true; this.previewVisible = true;
} }
......
...@@ -149,7 +149,7 @@ ...@@ -149,7 +149,7 @@
}" }"
:columns="matterColumns" :columns="matterColumns"
:data-source="siteMatterData" :data-source="siteMatterData"
:rowKey="(record) => record.id" :rowKey="(record) => record.matterId"
:row-selection="{ :row-selection="{
selectedRowKeys: matterKeys, selectedRowKeys: matterKeys,
onChange: handleChange, onChange: handleChange,
...@@ -392,7 +392,7 @@ export default { ...@@ -392,7 +392,7 @@ export default {
return { return {
windowId: this.windowInfo.id, windowId: this.windowInfo.id,
windowName: this.windowInfo.name, windowName: this.windowInfo.name,
siteMatterId: v.id, siteMatterId: v.matterId,
matterName: v.matterName, matterName: v.matterName,
deptId: v.deptId, deptId: v.deptId,
deptName: v.deptName, deptName: v.deptName,
...@@ -427,7 +427,7 @@ export default { ...@@ -427,7 +427,7 @@ export default {
this.matterKeys = keys; this.matterKeys = keys;
this.matterRows = [...new Set([...this.matterRows, ...rows])]; this.matterRows = [...new Set([...this.matterRows, ...rows])];
this.matterRows = this.matterRows.filter((v) => { this.matterRows = this.matterRows.filter((v) => {
return this.matterKeys.some((val) => val == v.id); return this.matterKeys.some((val) => val == v.matterId);
}); });
}, },
// 关闭添加窗口 // 关闭添加窗口
......
...@@ -308,6 +308,7 @@ import YCheckbox from "@/components/ycheckbox/YCheckbox.vue"; ...@@ -308,6 +308,7 @@ import YCheckbox from "@/components/ycheckbox/YCheckbox.vue";
import YSwitch from "@/components/yswitch/YSwitch.vue"; import YSwitch from "@/components/yswitch/YSwitch.vue";
// import options from "@/utils/city"; // import options from "@/utils/city";
import { regionData } from "element-china-area-data"; import { regionData } from "element-china-area-data";
import { checkPort, checkIp } from "@/utils/validate";
export default { export default {
props: { props: {
formVisible: { formVisible: {
...@@ -459,15 +460,15 @@ export default { ...@@ -459,15 +460,15 @@ export default {
siteIp: [ siteIp: [
{ {
required: true, required: true,
message: "站点服务器ip不能为空", validator: checkIp,
trigger: ["blur", "change"], trigger: "blur",
}, },
], ],
sitePort: [ sitePort: [
{ {
required: true, required: true,
message: "站点服务器端口不能为空", validator: checkPort,
trigger: ["blur", "change"], trigger: "blur",
}, },
], ],
longitude: [ longitude: [
...@@ -739,10 +740,8 @@ export default { ...@@ -739,10 +740,8 @@ export default {
.then((res) => { .then((res) => {
if (res.status == 1) { if (res.status == 1) {
let { location } = res.geocodes[0]; let { location } = res.geocodes[0];
[ [this.formInfo.longitude, this.formInfo.latitude] =
this.formInfo.longitude, location.split(",");
this.formInfo.latitude,
] = location.split(",");
} else { } else {
this.$message.error("经纬度获取失败,请输入正确的地址"); this.$message.error("经纬度获取失败,请输入正确的地址");
} }
......
...@@ -111,3 +111,55 @@ export const changeCodeNumber = (rule, value, callback) => { ...@@ -111,3 +111,55 @@ export const changeCodeNumber = (rule, value, callback) => {
callback(); callback();
} }
}; };
// 验证mac地址
export const checkMac = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入mac地址"));
} else if (
!/^(([a-f0-9][0,2,4,6,8,a,c,e]:([a-f0-9]{2}:){4})|([a-f0-9][0,2,4,6,8,a,c,e]-([a-f0-9]{2}-){4}))[a-f0-9]{2}$/i.test(
value
)
) {
callback(new Error("mac地址格式错误"));
} else {
callback();
}
};
// 验证端口
export const checkPort = (rule, value, callback) => {
if (!value) {
if (rule.required) {
callback(new Error("端口号不能为空"));
} else {
callback();
}
} else if (
!/^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/.test(
value
)
) {
callback(new Error("端口号格式错误"));
} else {
callback();
}
};
// 验证ip
export const checkIp = (rule, value, callback) => {
if (!value) {
if (rule.required) {
callback(new Error("ip不能为空"));
} else {
callback();
}
} else if (
!/^(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/.test(
value
)
) {
callback(new Error("ip格式错误"));
} else {
callback();
}
};
...@@ -13,8 +13,10 @@ import feign.hystrix.FallbackFactory; ...@@ -13,8 +13,10 @@ import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import java.util.List; import java.util.List;
...@@ -71,7 +73,8 @@ public interface IApiModelFeign extends IFeign { ...@@ -71,7 +73,8 @@ public interface IApiModelFeign extends IFeign {
@PostMapping(value = "model/census/list/bySite") @PostMapping(value = "model/census/list/bySite")
String getModelCensusBySiteId(@RequestBody ModelPdu query); String getModelCensusBySiteId(@RequestBody ModelPdu query);
@GetMapping(value = "site/siteTree")
String siteTree(@RequestHeader("Authorization") String authorization);
} }
...@@ -132,6 +135,14 @@ class ModelFeignFallbackFactory implements FallbackFactory<IApiModelFeign> { ...@@ -132,6 +135,14 @@ class ModelFeignFallbackFactory implements FallbackFactory<IApiModelFeign> {
return JSON.toJSONString(failResp); return JSON.toJSONString(failResp);
} }
@Override
public String siteTree(@RequestHeader("Authorization") String authorization) {
ApiResp<List<ModelCensusFeignVO>> failResp = new ApiResp<>();
failResp.setCode(ApiRespCodeEnum.FAILED.getValue());
failResp.setMsg("暂时无法获取站点树,请稍后再试!");
return JSON.toJSONString(failResp);
}
@Override @Override
public String getSitesAllInfoByQuery(SitePdu query) { public String getSitesAllInfoByQuery(SitePdu query) {
ApiResp<List<SiteFeignVO>> failResp = new ApiResp<>(); ApiResp<List<SiteFeignVO>> failResp = new ApiResp<>();
......
...@@ -26,6 +26,9 @@ export default { ...@@ -26,6 +26,9 @@ export default {
routerList(state) { routerList(state) {
return state.routerList; return state.routerList;
}, },
siteTreeList(state) {
return state.siteList;
},
}, },
mutations: { mutations: {
SET_routerList(state, routerList) { SET_routerList(state, routerList) {
......
...@@ -95,3 +95,22 @@ export function filterarrays(arr, field = "children") { ...@@ -95,3 +95,22 @@ export function filterarrays(arr, field = "children") {
recursiveSearch(arr); recursiveSearch(arr);
return data; return data;
} }
// 找出目标站点
export function findSitesById(data, targetId) {
let result = {};
function search(items) {
for (let item of items) {
if (item.type === "site" && item.id == targetId) {
result = item;
}
if (item.children && item.children.length > 0) {
search(item.children);
}
}
}
search(data);
return result;
}
<template>
<div :trigger="['click']" class="trigger" @click="ontrigger">
<slot>
<a class="ant-dropdown-link" @click="(e) => e.preventDefault()">
{{ siteName }} <a-icon type="down-circle" class="icon" />
</a>
</slot>
<div
slot="overlay"
class="select-site"
:style="{ left: `${offsetLeft}px` }"
v-if="show"
>
<div class="flex items-center primary-color name">
<a-icon type="environment" style="margin-right: 10px" />
<span style="">{{ siteName }}</span>
</div>
<div class="site-list">
<span
v-for="(item, index) in sitelist"
:key="index"
:class="{ 'primary-color': item.id == checkid }"
@click="setSite(item)"
>{{ item.label }}</span
>
</div>
<div class="check-site">
<span>您的选择是:</span>
<span
class="check-item"
v-for="(item, index) in checkarr"
:key="index"
@click="updataSite(item)"
>{{ index > 0 ? ">" : "" }}{{ item.label }}</span
>
</div>
<div class="site-btn">
<a-button @click="show = false" style="margin-right: 10px"
>取消</a-button
>
<a-button type="primary" @click="onSucessSite" :disabled="isSite"
>确定</a-button
>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from "vuex";
import storage from "@/utils/js/Storage";
export default {
data() {
return {
show: false,
offsetLeft: 0,
checkarr: [], //选中站点
checkid: undefined, //最终选中站点
siteName: "",
isSite: true,
sitelist: [],
};
},
computed: {
...mapGetters("user", ["siteTreeList"]),
},
created() {
this.getwaitedListdata();
},
mounted() {
const { offsetLeft } = this.$el;
this.offsetLeft = offsetLeft;
},
methods: {
// 确认站点
onSucessSite() {
if (this.checkarr.length == 0) return;
let obj = this.checkarr[this.checkarr.length - 1];
this.clickSite(obj);
},
// 选中
setSite(obj) {
this.checkid = undefined;
// 为子节点不添加数据
let data = this.checkarr[this.checkarr.length - 1];
if (data && (data.isLeaf || data.children.length == 0)) {
// 如果为子节点更新最后一个数据
this.checkid = obj.id;
this.checkarr[this.checkarr.length - 1] = obj;
// 如果选中数据有子集更新站点列表
if (obj.children && obj.children.length > 0) {
this.sitelist = obj.children;
}
} else {
this.checkarr.push(obj);
if (obj.children && obj.children.length > 0) {
this.sitelist = obj.children;
}
}
if (obj && obj.type == "site") {
this.isSite = false;
} else {
this.isSite = true;
}
},
// 更新选中
updataSite(row) {
const { id } = row;
this.checkid = undefined;
let index = this.checkarr.findIndex((v) => v.id == id);
if (index > -1) {
this.checkarr.splice(index + 1, this.checkarr.length - (index + 1));
}
if (row.children && row.children.length > 0) {
this.sitelist = row.children;
}
if (row && row.type == "site") {
this.isSite = false;
} else {
this.isSite = true;
}
// this.getwaitedListdata(id);
},
getwaitedListdata() {
this.sitelist = this.siteTreeList;
let arr = [];
const treeFn = function (e) {
e.forEach((element) => {
arr.push(element);
if (element.children && element.children.length > 0) {
treeFn(element.children);
}
});
};
const siteid = storage.get(2, "siteId");
treeFn(this.siteTreeList);
const siteObj = arr.find((v) => v.id == siteid);
this.siteName = siteObj ? siteObj.label : "请选择站点";
},
clickSite(obj) {
storage.set(2, "siteId", obj.id);
storage.set(2, "siteName", obj.label);
this.show = false;
if (location.href.search(/token/gi) >= 0) {
this.$router.push({ path: "/resource/advimg" });
setTimeout(() => {
location.reload();
});
} else {
location.reload();
}
},
ontrigger(e) {
if (e.target && e.target.nodeName == "A") {
this.show = !this.show;
}
},
},
};
</script>
<style lang="less" scoped>
.trigger {
display: inline-block;
position: relative;
line-height: 64px;
}
.ant-dropdown-link {
color: #fff;
padding: 0 20px;
font-size: 16px;
min-width: 200px;
display: inline-block;
.icon {
font-size: 12px;
}
}
.primary-color {
color: #1890ff;
}
.select-site {
position: fixed;
left: 0;
top: 65px;
background: #fff;
border-radius: 6px;
padding: 10px;
min-width: 60%;
max-width: 70%;
z-index: 9;
color: rgba(0, 0, 0, 0.8);
font-size: 14px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
.name {
font-size: 20px;
}
.site-list {
// padding: 10px 0;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
overflow: hidden;
span {
float: left;
line-height: 1.5;
padding: 10px 20px;
display: inline-block;
cursor: pointer;
&:hover {
color: #1890ff;
}
}
}
.check-site,
.site-btn {
padding: 0 20px;
}
.check-item {
cursor: pointer;
}
}
</style>
...@@ -15,12 +15,13 @@ ...@@ -15,12 +15,13 @@
{{ sysName }} {{ sysName }}
</h1> </h1>
<div class="selectOnptions"> <div class="selectOnptions">
<a-select v-model="siteInfo" labelInValue @change="handleChange"> <HeaderSite></HeaderSite>
<!-- <a-select v-model="siteInfo" labelInValue @change="handleChange">
<a-icon slot="suffixIcon" type="down-circle" /> <a-icon slot="suffixIcon" type="down-circle" />
<a-select-option v-for="v in siteList" :key="v.id" :value="v.id"> <a-select-option v-for="v in siteList" :key="v.id" :value="v.id">
{{ v.siteName }} {{ v.siteName }}
</a-select-option> </a-select-option>
</a-select> </a-select> -->
</div> </div>
</a-space> </a-space>
<!-- 菜单 --> <!-- 菜单 -->
...@@ -84,10 +85,12 @@ ...@@ -84,10 +85,12 @@
import { mapState, mapMutations, mapGetters } from "vuex"; import { mapState, mapMutations, mapGetters } from "vuex";
import { LogoutInterface } from "@/api/user"; import { LogoutInterface } from "@/api/user";
import changePassword from "./components/changePassword.vue"; import changePassword from "./components/changePassword.vue";
import HeaderSite from "./components/HeaderSite.vue";
import storage from "@/utils/js/Storage"; import storage from "@/utils/js/Storage";
export default { export default {
components: { components: {
changePassword, changePassword,
HeaderSite,
}, },
data() { data() {
return { return {
......
...@@ -248,7 +248,7 @@ import Swiper from "swiper"; ...@@ -248,7 +248,7 @@ import Swiper from "swiper";
import { LoginInterface, changeForgotPassword } from "@/api/user.js"; import { LoginInterface, changeForgotPassword } from "@/api/user.js";
import { mapMutations, mapState } from "vuex"; import { mapMutations, mapState } from "vuex";
import { changeAccount, changePassWord } from "@/utils/js/validate"; import { changeAccount, changePassWord } from "@/utils/js/validate";
import { encrypt } from "@/utils"; import { encrypt, findSitesById } from "@/utils";
import storage from "@/utils/js/Storage"; import storage from "@/utils/js/Storage";
export default { export default {
data() { data() {
...@@ -380,13 +380,17 @@ export default { ...@@ -380,13 +380,17 @@ export default {
let { code, data, msg } = res; let { code, data, msg } = res;
if (code == 1) { if (code == 1) {
let { siteList, user, token } = data; let { siteList, user, token } = data;
let { siteIds } = user;
this.set_token(token); this.set_token(token);
this.SET_USERDATA(user); this.SET_USERDATA(user);
this.set_siteList(siteList); this.set_siteList(siteList);
this.SET_routerList(this.getUrl(user.menuList)); this.SET_routerList(this.getUrl(user.menuList));
if (siteList.length) { if (siteList.length && siteIds) {
storage.set(2, "siteId", siteList[0].id); let siteId = siteIds.split(",")[0];
storage.set(2, "siteName", siteList[0].siteName); let firstSite = findSitesById(siteList, 20);
let siteName = firstSite.label;
storage.set(2, "siteId", siteId);
storage.set(2, "siteName", siteName);
} }
setTimeout(() => { setTimeout(() => {
this.$router.push("/home"); this.$router.push("/home");
......
...@@ -16,6 +16,10 @@ module.exports = defineConfig({ ...@@ -16,6 +16,10 @@ module.exports = defineConfig({
"^/api": "", "^/api": "",
}, },
}, },
"/file": {
target: process.env.VUE_APP_API_BASE_URL,
changeOrigin: true,
},
}, },
}, },
......
...@@ -111,13 +111,13 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi ...@@ -111,13 +111,13 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
SitePdu sitePdu = new SitePdu(); SitePdu sitePdu = new SitePdu();
List<String> areaCodeList = Arrays.asList(userEntity.getAreaCodes().split(",")); List<String> areaCodeList = Arrays.asList(userEntity.getAreaCodes().split(","));
sitePdu.setAreaCodeList(areaCodeList); sitePdu.setAreaCodeList(areaCodeList);
String resp = apiModelFeign.getSitesByQuery(sitePdu); String resp = apiModelFeign.siteTree(token);
ApiResp<JSONObject> apiResp = JSON.parseObject(resp, ApiResp.class); ApiResp<JSONObject> apiResp = JSON.parseObject(resp, ApiResp.class);
if (apiResp.getCode() != YesNoEnum.YES.getValue()) { if (apiResp.getCode() != YesNoEnum.YES.getValue()) {
throw new AppException("获取用户站点列表树数据失败:" + apiResp.getMsg()); throw new AppException("获取用户站点列表树数据失败:" + apiResp.getMsg());
} }
if (apiResp.getData().get("data") != null) { if (apiResp.getData().get("siteTree") != null) {
data.put("siteList", apiResp.getData().get("data")); data.put("siteList", apiResp.getData().get("siteTree"));
} else { } else {
data.put("siteList", Collections.emptyList()); data.put("siteList", Collections.emptyList());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment