|
@@ -1,7 +1,380 @@
|
|
|
-<script setup lang="ts"></script>
|
|
|
+<script setup lang="ts">
|
|
|
+import { reactive, ref, watch, nextTick } from "vue"
|
|
|
+import { getComponentclassApi } from "@/api/classify/index"
|
|
|
+import { createComponentListApi, deleteComponentListApi, updateComponentListApi, getComponentListApi } from "@/api/subassembly/index"
|
|
|
+import { getQiniuToken } from "@/api/uploading/index"
|
|
|
+import HeadSearch from "@/components/HeadSearch/index.vue"
|
|
|
+import tables from "@/components/tables/index.vue"
|
|
|
+import { type CreateOrUpdateTableRequestData, type TableData } from "@/api/subassembly/types/index"
|
|
|
+import { ElMessage, ElMessageBox, ElNotification, ElLoading } from "element-plus"
|
|
|
+import { CirclePlus } from "@element-plus/icons-vue"
|
|
|
+import { cloneDeep } from "lodash-es"
|
|
|
+import "codemirror/mode/javascript/javascript.js"
|
|
|
+import Codemirror from "codemirror-editor-vue3"
|
|
|
+import type { CmComponentRef } from "codemirror-editor-vue3"
|
|
|
+import SideBarItem from './sidebarItem.vue';
|
|
|
+import 'codemirror/theme/idea.css'
|
|
|
+import * as qiniu from 'qiniu-js';
|
|
|
+const cmOptions = reactive({
|
|
|
+ autorefresh: true,
|
|
|
+ tabSize: 4,
|
|
|
+ mode: "text/javascript",
|
|
|
+ theme: "idea",
|
|
|
+ line: true,
|
|
|
+ viewportMargin: Infinity, //处理高度自适应时搭配使用
|
|
|
+ highlightDifferences: true,
|
|
|
+ autofocus: false,
|
|
|
+ indentUnit: 4,
|
|
|
+ smartIndent: true,
|
|
|
+ // readOnly: true, // 只读
|
|
|
+ showCursorWhenSelecting: true,
|
|
|
+ firstLineNumber: 1,
|
|
|
+});
|
|
|
+const cmRef = ref<CmComponentRef>()
|
|
|
+const searchTerms = [{
|
|
|
+ type: 'input',
|
|
|
+ label: '名称',
|
|
|
+ field: 'name',
|
|
|
+ placeholder: '请输入组件名称',
|
|
|
+}]
|
|
|
+const searchRuleForm = {
|
|
|
+ name: '',
|
|
|
+}
|
|
|
+const operatingList = [{
|
|
|
+ id: 'add',
|
|
|
+ typeStyle: 'primary',
|
|
|
+ title: '新增组件',
|
|
|
+ icon: CirclePlus,
|
|
|
+}]
|
|
|
+const tableColumns = reactive([
|
|
|
+ { prop: "index", width: '50' },
|
|
|
+ { prop: 'name', label: '组件名称' },
|
|
|
+ {
|
|
|
+ prop: 'action',
|
|
|
+ label: '操作',
|
|
|
+ labelButton: [{
|
|
|
+ type: 'details',
|
|
|
+ label: '详情',
|
|
|
+ style: 'success',
|
|
|
+ }, {
|
|
|
+ type: 'edit',
|
|
|
+ label: '编辑',
|
|
|
+ style: 'primary',
|
|
|
+ }, {
|
|
|
+ type: 'del',
|
|
|
+ label: '删除',
|
|
|
+ style: 'danger',
|
|
|
+ }]
|
|
|
+ }
|
|
|
+])
|
|
|
+const operationType: any = ref('')
|
|
|
+const componentData: any = ref([])
|
|
|
+const treeCurrent: any = ref(null)
|
|
|
+//#region 增
|
|
|
+const DEFAULT_FORM_DATA: CreateOrUpdateTableRequestData = {
|
|
|
+ ID: null,
|
|
|
+ name: "",
|
|
|
+ image: "",
|
|
|
+ data: "",
|
|
|
+ imageName: "",
|
|
|
+}
|
|
|
+const classifyId: any = ref(null)
|
|
|
+const formData = ref<CreateOrUpdateTableRequestData>(cloneDeep(DEFAULT_FORM_DATA))
|
|
|
+const dialogVisible: any = ref<boolean>(false)
|
|
|
+const fileList: any = ref([])
|
|
|
+const operationBtn = (event: any) => {
|
|
|
+ if (classifyId.value) {
|
|
|
+ if (event.id == 'add') {
|
|
|
+ dialogVisible.value = true
|
|
|
+ }
|
|
|
+ nextTick(() => {
|
|
|
+ cmRef.value?.refresh()
|
|
|
+ cmRef.value?.resize('100%', '600px')
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ ElMessage.warning('请先选择分类')
|
|
|
+ }
|
|
|
+}
|
|
|
+const handleUpdate = (event: any, type: any) => {
|
|
|
+ operationType.value = type.type
|
|
|
+ if (type.type == 'edit' || type.type == 'details') {
|
|
|
+ dialogVisible.value = true
|
|
|
+ formData.value.ID = event.ID
|
|
|
+ formData.value.name = event.name
|
|
|
+ formData.value.image = event.image
|
|
|
+ formData.value.data = event.data
|
|
|
+ formData.value.imageName = event.image_name
|
|
|
+ let imgArr = {
|
|
|
+ name: event.image_name,
|
|
|
+ url: event.image,
|
|
|
+ }
|
|
|
+ fileList.value.push(imgArr)
|
|
|
+ } else if (type.type == 'del') {
|
|
|
+ handleDelete(event)
|
|
|
+ }
|
|
|
+ nextTick(() => {
|
|
|
+ cmRef.value?.refresh()
|
|
|
+ cmRef.value?.resize('100%', '600px')
|
|
|
+ })
|
|
|
+}
|
|
|
+const loading = ref<boolean>(false)
|
|
|
+const addEditLoading = ref<boolean>(false)
|
|
|
+const paginationData: any = ref({})
|
|
|
+const tableData = ref([])
|
|
|
+// 搜索
|
|
|
+const handleSearch = () => {
|
|
|
+ getTableData()
|
|
|
+}
|
|
|
+// 分类列表查询
|
|
|
+const getTableData = () => {
|
|
|
+ loading.value = true
|
|
|
+ getComponentclassApi({
|
|
|
+ currentPage: paginationData.currentPage,
|
|
|
+ size: paginationData.pageSize,
|
|
|
+ name: searchRuleForm.name,
|
|
|
+ }).then((res: any) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ tableData.value = res.data
|
|
|
+ treeCurrent.value = String(tableData.value[0].ID)
|
|
|
+ classifyId.value = tableData.value[0].ID
|
|
|
+ getComponentData(tableData.value[0].ID)
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ tableData.value = []
|
|
|
+ }).finally(() => {
|
|
|
+ loading.value = false
|
|
|
+ })
|
|
|
+}
|
|
|
+// 确定添加
|
|
|
+const handleCreateOrUpdate = async () => {
|
|
|
+ if (formData.value.name) {
|
|
|
+ if (fileList.value.length > 0) {
|
|
|
+ addEditLoading.value = true
|
|
|
+ const arrList = {
|
|
|
+ name: formData.value.name,
|
|
|
+ image: formData.value.image,
|
|
|
+ data: formData.value.data,
|
|
|
+ component_id: classifyId.value,
|
|
|
+ image_name: formData.value.imageName,
|
|
|
+ ID: formData.value.ID
|
|
|
+ }
|
|
|
+ let msgTitle = ''
|
|
|
+ if (formData.value.ID) {
|
|
|
+ delete arrList.component_id
|
|
|
+ msgTitle = '修改成功'
|
|
|
+ } else {
|
|
|
+ delete arrList.ID
|
|
|
+ msgTitle = '添加成功'
|
|
|
+ }
|
|
|
+ const api = formData.value.ID === null ? createComponentListApi : updateComponentListApi
|
|
|
+ api(arrList).then((res: any) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ ElMessage.success(msgTitle)
|
|
|
+ dialogVisible.value = false
|
|
|
+ getComponentData(classifyId.value)
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.message)
|
|
|
+ }
|
|
|
+ addEditLoading.value = false
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ ElMessage.warning('请上传组件图片')
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ElMessage.warning('请输入组件名称')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//#region 删
|
|
|
+const handleDelete = (row: TableData) => {
|
|
|
+ ElMessageBox.confirm(`正在删除组件:${row.name},确认删除?`, "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ }).then(() => {
|
|
|
+ deleteComponentListApi({ id: row.ID }).then(() => {
|
|
|
+ ElMessage.success("删除成功")
|
|
|
+ getComponentData(classifyId.value)
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+// 选择组件分类搜索组件
|
|
|
+const handleOpen = (event: any) => {
|
|
|
+ classifyId.value = event
|
|
|
+ getComponentData(event)
|
|
|
+}
|
|
|
+// 组件列表查询
|
|
|
+const getComponentData = (id) => {
|
|
|
+ loading.value = true
|
|
|
+ getComponentListApi(id).then((res: any) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ componentData.value = res.data
|
|
|
+ }
|
|
|
+ }).catch((err) => {
|
|
|
+ ElMessage.error(err)
|
|
|
+ }).finally(() => {
|
|
|
+ loading.value = false
|
|
|
+ })
|
|
|
+}
|
|
|
+const fileImage = ref(null)
|
|
|
+// 上传组件图片
|
|
|
+const singleUpload = (event) => {
|
|
|
+ fileImage.value = event.file
|
|
|
+ getQiniuToken(event.file).then((res: any) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ QiniuYun(res.data)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+const QiniuYun = (token) => {
|
|
|
+ const loading = ElLoading.service({
|
|
|
+ lock: true,
|
|
|
+ text: '正在上传文件,请稍后...',
|
|
|
+ background: 'rgba(255, 255, 255, 0.5)',
|
|
|
+ spinner: 'el-icon-loading'
|
|
|
+ })
|
|
|
+ let key = fileImage.value.name
|
|
|
+ var config = {
|
|
|
+ useCdnDomain: false, //表示是否使用 cdn 加速域名,为布尔值,true 表示使用,默认为 false。
|
|
|
+ region: qiniu.region.z2,
|
|
|
+ domain: "https://qiniu.region.z2", //配置好的七牛云域名 如 https://cdn.qniyun.com/
|
|
|
+ chunkSize: 1000, //每个分片的大小,单位mb,默认值3
|
|
|
+ forceDirect: false //直传还是断点续传方式,true为直传
|
|
|
+ };
|
|
|
+ var putExtra: any = {
|
|
|
+ fname: key, //文件原始文件名
|
|
|
+ params: {},
|
|
|
+ mimeType: []
|
|
|
+ };
|
|
|
+ var observable = qiniu.upload(fileImage.value, key, token, putExtra, config);
|
|
|
+ var observer = {
|
|
|
+ next(res) {
|
|
|
+ //上传进度
|
|
|
+ let filePercent = parseInt(res.total.percent)
|
|
|
+ if (filePercent === 100) {
|
|
|
+ //console.log('实例监听对象', res)
|
|
|
+ }
|
|
|
+ //
|
|
|
+ },
|
|
|
+ // 接收上传错误信息
|
|
|
+ error(err) {
|
|
|
+ loading.close()
|
|
|
+ switch (err.code) {
|
|
|
+ case 413:
|
|
|
+ ElMessage.error('错了哦,图片可能太大了哦')
|
|
|
+ break
|
|
|
+ case 408:
|
|
|
+ ElMessage.error('错了哦,请求超时')
|
|
|
+ break
|
|
|
+ default:
|
|
|
+ ElMessage.error('错了哦,上传错误')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 接收上传完成后的信息
|
|
|
+ complete(com) {
|
|
|
+ loading.close()
|
|
|
+ formData.value.image = com.key
|
|
|
+ formData.value.imageName = key
|
|
|
+ }
|
|
|
+ };
|
|
|
+ observable.subscribe(observer);
|
|
|
+}
|
|
|
+// 超出限制
|
|
|
+const onExceed = (event) => {
|
|
|
+ ElNotification({
|
|
|
+ title: '警告',
|
|
|
+ message: '超出最大上传限制',
|
|
|
+ type: 'warning',
|
|
|
+ })
|
|
|
+}
|
|
|
+const resetForm = () => {
|
|
|
+ formData.value = cloneDeep(DEFAULT_FORM_DATA)
|
|
|
+ fileList.value = []
|
|
|
+}
|
|
|
+watch([() => paginationData.currentPage, () => paginationData.pageSize], getTableData, { immediate: true })
|
|
|
+</script>
|
|
|
|
|
|
<template>
|
|
|
- <div>test列表</div>
|
|
|
+ <div class="app-container">
|
|
|
+ <HeadSearch :searchTerms="searchTerms" :ruleForm="searchRuleForm" @handleSearch="handleSearch"></HeadSearch>
|
|
|
+ <div class="card_content_interior">
|
|
|
+ <div class="left_interior">
|
|
|
+ <el-menu :default-active="treeCurrent" @select="handleOpen">
|
|
|
+ <SideBarItem :routerList="tableData" />
|
|
|
+ </el-menu>
|
|
|
+ </div>
|
|
|
+ <div class="right_interior">
|
|
|
+ <tables v-loading="loading" :tableData="componentData" :operatingList="operatingList"
|
|
|
+ :tableColumns="tableColumns" @operationBtn="operationBtn" @handleUpdate="handleUpdate"></tables>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 新增/修改 -->
|
|
|
+ <div class="card_module" v-loading="addEditLoading">
|
|
|
+ <el-dialog v-model="dialogVisible" :title="formData.ID === null ? '新增组件' : '修改组件'" @closed="resetForm"
|
|
|
+ width="90%">
|
|
|
+ <div>
|
|
|
+ <div class="componet_Name">
|
|
|
+ <span style="flex: none;margin-right: 10px;">组件名称</span>
|
|
|
+ <el-input v-model="formData.name" placeholder="请输入组件名称" />
|
|
|
+ </div>
|
|
|
+ <el-upload action="#" v-model:file-list="fileList" show-file-list list-type="picture" :limit="1"
|
|
|
+ :http-request="singleUpload" :on-exceed="onExceed">
|
|
|
+ <el-button type="primary">上传组件图片</el-button>
|
|
|
+ </el-upload>
|
|
|
+ <Codemirror ref="cmRef" v-model:value="formData.data" :options="cmOptions" border></Codemirror>
|
|
|
+ </div>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="handleCreateOrUpdate" :loading="loading">确认</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
-<style lang="scss" scoped></style>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.card_content_interior {
|
|
|
+ display: flex;
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 5px;
|
|
|
+ box-shadow: 0 2px 4px rgba(0, 0, 0, .05);
|
|
|
+ margin-top: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.left_interior {
|
|
|
+ width: 20%;
|
|
|
+ // padding: 10px 0px;
|
|
|
+ // border-right: 1px solid #e4e7ed;
|
|
|
+}
|
|
|
+
|
|
|
+.right_interior {
|
|
|
+ width: 80%;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-card) {
|
|
|
+ border: none !important;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.span-ellipsis) {
|
|
|
+ font-size: 16px !important;
|
|
|
+}
|
|
|
+
|
|
|
+.span-ellipsis {
|
|
|
+ width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ margin-right: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.componet_Name {
|
|
|
+ width: 300px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.card_module :deep(.el-dialog) {
|
|
|
+ margin-top: 4vh
|
|
|
+}
|
|
|
+</style>
|