feat: 新增删除布点联调完成

develop
donghao 10 months ago
parent 7df7fda0ed
commit ec9b89559c

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-08-02 10:40:49
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-08-14 11:10:51
* @LastEditTime: 2024-08-14 17:09:46
* @FilePath: \General-AI-Platform-Web-Client\src\api\workshops.ts
* @Description:
*/
@ -30,7 +30,36 @@ export const getWorkshopsApi = (params?: object) => {
/** 新增布点 */
export const addWorkshopsApi = (data?: object) => {
return http.request<Result>("post", baseUrlApi("workshops/"), { data });
return http.request<Result>(
"post",
baseUrlApi("workshops/"),
{ data },
{
headers: { "Content-Type": "multipart/form-data" }
}
);
};
/** 编辑布点 data有id */
export const editWorkshopsApi = (data?: object) => {
return http.request<Result>(
"post",
baseUrlApi("workshops/"),
{ data },
{
headers: { "Content-Type": "multipart/form-data" }
}
);
};
/** 删除布点 status: 1 */
export const deleteWorkshopsApi = (data?: object) => {
return http.request<Result>(
"post",
baseUrlApi("workshops/"),
{ data: { ...data, status: 1 } },
{
headers: { "Content-Type": "multipart/form-data" }
}
);
};
/** 获取布点设备 */

@ -0,0 +1,3 @@
import isDelete from "./src/isDelete";
export const IsDelete = isDelete;

@ -0,0 +1,77 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-02-22 13:38:04
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-08-14 17:03:45
* @FilePath: \General-AI-Platform-Web-Client\src\components\TableActionCard\isDelete.tsx
* @Description:
*/
import { defineComponent, ref, PropType } from "vue";
import { ElDialog, ElButton } from "element-plus";
export default defineComponent({
name: "IsDelete",
props: {
title: {
type: String as PropType<string>,
default: "提示"
},
message: {
type: String as PropType<string>,
default: "确定要删除吗?"
},
visible: {
type: Boolean as PropType<boolean>,
required: true
}
},
emits: ["update:visible", "confirm"],
setup(props, { emit }) {
// const visible = ref(props.visible);
const handleConfirm = () => {
emit("confirm");
// visible.value = false;
// emit("update:visible", false);
};
const handleCancel = () => {
// visible.value = false;
emit("update:visible", false);
};
const handleClose = (done: () => void) => {
// visible.value = false;
emit("update:visible", false);
// done();
};
watch(
() => props.visible,
val => {
visible.value = val;
}
);
return () => (
<ElDialog
title={props.title}
visible={props.visible}
width="30%"
before-close={handleClose}
v-slots={{
footer: () => (
<>
<ElButton onClick={handleCancel}></ElButton>
<ElButton type="danger" onClick={handleConfirm}>
</ElButton>
</>
)
}}
>
<span>{props.message}</span>
</ElDialog>
);
}
});

@ -0,0 +1,3 @@
import isDelete from "./src/isDelete";
export const IsDelete = isDelete;

@ -0,0 +1,69 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-02-22 13:38:04
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-08-14 15:56:12
* @FilePath: \General-AI-Platform-Web-Client\src\components\TableActionCard\isDelete.tsx
* @Description:
*/
import { defineComponent, ref, PropType } from "vue";
import { ElDialog, ElButton } from "element-plus";
export default defineComponent({
name: "IsDelete",
props: {
title: {
type: String as PropType<string>,
default: "提示"
},
message: {
type: String as PropType<string>,
default: "确定要删除吗?"
},
modelValue: {
type: Boolean as PropType<boolean>,
required: true
}
},
emits: ["update:modelValue", "confirm"],
setup(props, { emit }) {
const visible = ref(props.modelValue);
const handleConfirm = () => {
emit("confirm");
visible.value = false;
emit("update:modelValue", false);
};
const handleCancel = () => {
visible.value = false;
emit("update:modelValue", false);
};
const handleClose = (done: () => void) => {
visible.value = false;
done();
};
return () => (
<ElDialog
title={props.title}
modelValue={visible.value}
width="30%"
before-close={handleClose}
v-slots={{
footer: () => (
<>
<ElButton onClick={handleCancel}></ElButton>
<ElButton type="danger" onClick={handleConfirm}>
</ElButton>
</>
)
}}
>
<span>{props.message}</span>
</ElDialog>
);
}
});

@ -0,0 +1,19 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-08-14 14:42:09
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-08-14 14:43:30
* @FilePath: \General-AI-Platform-Web-Client\src\utils\forApi.ts
* @Description:
*/
/**
* @
* @param result
* @returns boolean
*/
export function isSuccessApi(result): boolean {
if ([200].includes(result.status)) {
return true;
}
return false;
}

@ -189,6 +189,15 @@ class PureHttp {
): Promise<P> {
return this.request<P>("get", url, params, config);
}
/** 单独抽离的上传工具函数 */
// public uploadFile<T, P>(
// url: string,
// params?: AxiosRequestConfig<T>,
// config?: PureHttpRequestConfig
// ): Promise<P> {
// return this.request<P>("post", url, params, config);
// }
}
export const http = new PureHttp();

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-08-07 14:47:44
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-08-12 15:34:22
* @LastEditTime: 2024-08-14 16:12:34
* @FilePath: \General-AI-Platform-Web-Client\src\views\deviceSetting\components\add.vue
* @Description: 新建位置
-->
@ -11,56 +11,85 @@
import historyAlarm from "@/assets/history_alarm.png";
import { UploadFilled } from "@element-plus/icons-vue";
import { message } from "@/utils/message";
import { addWorkshopsApi } from "@/api/workshops";
import { isSuccessApi } from "@/utils/forApi";
defineOptions({
name: "DeviceSettingAdd"
});
const emit = defineEmits(["finishAdd"]);
const formData = ref({
name: "",
file: null as File | null
picture: null
});
const formRef = ref(null);
const uploadRef = ref(null);
const imagePreview = ref<string | null>(null); // URL
const dialogVisible = ref<boolean>(false);
const fileList = ref([]);
const rules = {
name: [{ required: true, message: "请输入位置名称", trigger: "blur" }],
file: [{ required: true, message: "请上传图片文件", trigger: "change" }]
picture: [{ required: true, message: "请上传图片文件", trigger: "change" }]
};
const uploadAction = ""; //
const openDialog = () => {
dialogVisible.value = true;
};
const handleFileChange = (file: any) => {
// 使 FileReader
const reader = new FileReader();
reader.onload = e => {
imagePreview.value = e.target?.result as string;
};
reader.readAsDataURL(file.raw);
console.log(file, "handleFileChange");
formData.value = {
...formData.value,
file: "https://img.cgmodel.com/image/2020/1010/big/1537169-1390622992.jpg"
picture: file.raw
};
};
//
const removeFile = () => {
imagePreview.value = null;
formData.value = {
...formData.value,
picture: null
};
};
const beforeUpload = (file: File) => {
console.log("beforeUpload_file", file);
const isJPG = file.type === "image/jpeg" || file.type === "image/png";
const isLt500K = file.size / 1024 / 1024 < 0.5;
const isLt500K = file.size / 1024 / 1024 < 20;
if (!isJPG) {
ElMessage.error("上传图片只能是 JPG/PNG 格式!");
}
if (!isLt500K) {
ElMessage.error("上传图片大小不能超过 500KB!");
ElMessage.error("上传图片大小不能超过 20MB!");
}
return isJPG && isLt500K;
};
async function fetchAddPoint() {
const formParams = new FormData();
formParams.append("name", formData.value.name);
formParams.append("picture", formData.value.picture);
const resp = await addWorkshopsApi(formParams);
console.log(resp, "fetchAddPoint_resp");
if (isSuccessApi(resp)) {
message(resp.msg || "添加成功", { type: "success" });
emit("finishAdd", resp.data);
dialogVisible.value = false;
} else {
message(resp.msg || "添加失败", { type: "error" });
}
}
const submitForm = () => {
formRef.validate((valid: boolean) => {
formRef.value.validate((valid: boolean) => {
if (valid) {
message("提交成功", { type: "success" });
dialogVisible.value = false;
fetchAddPoint();
} else {
message("验证失败", { type: "error" });
return false;
@ -68,11 +97,6 @@ const submitForm = () => {
});
};
// const resetForm = (formEl: FormInstance | undefined) => {
// if (!formEl) return;
// formEl.resetFields();
// };
defineExpose({
openDialog
});
@ -113,28 +137,30 @@ defineExpose({
<el-form-item
label="上传图片(请上传png或jpeg格式图片文件尺寸不超过4096*3112px容量不超过20M)"
class="w-full"
prop="file"
prop="picture"
>
<el-upload
ref="uploadRef"
class="w-full"
drag
:action="uploadAction"
:on-change="handleFileChange"
:before-upload="beforeUpload"
:on-remove="removeFile"
:auto-upload="false"
:file-list="fileList"
:limit="1"
accept="image/*"
>
<div>
<div v-if="!formData?.file">
<div v-if="!imagePreview">
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
拖拽图片到这里或点此添加 <em>点此添加</em>
</div>
</div>
<el-image
v-else
:src="formData?.file || ''"
v-if="imagePreview"
:src="imagePreview || ''"
:fit="'contain'"
class="w-full"
/>

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-08-02 10:52:32
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-08-14 11:22:32
* @LastEditTime: 2024-08-14 17:10:19
* @FilePath: \General-AI-Platform-Web-Client\src\views\deviceSetting\index.vue
* @Description: 设备点位管理设置
@ 交互说明
@ -12,14 +12,17 @@
4. 设备关联属性设置
5. 效果预览
-->
<script name="Home" setup>
<script setup lang="ts">
//
import DeviceAttr from "./components/deviceAttr.vue";
import DeviceSettingAdd from "./components/add.vue";
import DeviceSelect from "./components/deviceSelect.vue";
import { IsDelete } from "@/components/Action";
import { usePointObject } from "./hooks/usePointObject";
import { getWorkshopsApi } from "@/api/workshops";
import { getWorkshopsApi, deleteWorkshopsApi } from "@/api/workshops";
import { getLinkDevicesApi } from "@/api/device";
import { isSuccessApi } from "@/utils/forApi";
// TODO
//
import { CanvasEventEmitter } from "@/utils/event/notifier";
@ -72,7 +75,7 @@ const activePoint = ref({
name: ""
});
const deviceList = ref([]);
const isDeleteVisible = ref(false);
//
const initFile = () => {
// console.log("canvasEditor");
@ -120,16 +123,6 @@ const initFabric = () => {
/**
* @设备点位
*/
//
function addPoint() {
deviceSettingAddRef.value?.openDialog();
}
//
function editPoint() {
deviceSettingAddRef.value?.openDialog();
}
//
function deletePoint() {}
//
async function fetchPointList() {
const { data } = await getWorkshopsApi();
@ -179,6 +172,69 @@ function tabPoint(tab) {
});
}
//
function addPoint() {
deviceSettingAddRef.value?.openDialog();
}
//
function afterFinishAdd(record) {
//
pointList.value = [...toRaw(pointList.value), record];
activePointId.value = record.id;
activePoint.value = record;
console.log("afterFinishAdd", record);
nextTick(() => {
initFile();
});
}
//
function editPoint() {
deviceSettingAddRef.value?.openDialog();
}
//
function beforeDeletePoint() {
isDeleteVisible.value = true;
}
function afterFinishDelete() {
// pointList
const currPointList = toRaw(pointList.value);
const targetIndex = currPointList.findIndex(
item => item.id === activePointId.value
);
currPointList.splice(targetIndex, 1);
// false
pointList.value = currPointList;
if (!currPointList.length) {
activePoint.value = {};
activePointId.value = null;
return;
}
if (targetIndex > 0) {
activePoint.value = currPointList[targetIndex - 1];
activePointId.value = currPointList[targetIndex - 1].id;
} else {
activePoint.value = currPointList[0];
activePointId.value = currPointList[0].id;
}
nextTick(() => {
initFile();
});
}
async function deletePoint() {
const resp = await deleteWorkshopsApi({
id: activePointId.value
});
if (isSuccessApi(resp)) {
isDeleteVisible.value = false;
afterFinishDelete();
}
//
}
//
watch(
() => pointList.value,
@ -279,14 +335,21 @@ provide("canvasEditor", canvasEditor);
<el-button
type="danger"
plain
@click="deletePoint"
@click="beforeDeletePoint"
v-if="pointList.length"
>删除位置</el-button
>
<IsDelete
v-model="isDeleteVisible"
@update:visible="val => (isDeleteVisible = val)"
title="删除确认"
message="您确定要删除该项目吗?"
@confirm="deletePoint"
/>
</div>
</div>
</div>
<DeviceSettingAdd ref="deviceSettingAddRef" />
<DeviceSettingAdd ref="deviceSettingAddRef" @finishAdd="afterFinishAdd" />
</div>
</template>

Loading…
Cancel
Save