This commit is contained in:
2025-02-08 09:49:17 +08:00
parent 4cfa96d061
commit 98fd6893a6
7 changed files with 4356 additions and 6 deletions

View File

@@ -89,7 +89,7 @@
> >
<template slot-scope="scope"> <template slot-scope="scope">
<slot name="operation" :row="scope.row"></slot> <slot name="operation" :row="scope.row"></slot>
<el-button type="text" @click="editCourse(scope.row)" <el-button type="text" v-if="urlList.editCourse" @click="editCourse(scope.row)"
>编辑</el-button >编辑</el-button
> >
<el-button <el-button
@@ -371,6 +371,7 @@ export default {
} }
}) })
.then(async ({ data }) => { .then(async ({ data }) => {
console.log('data at line 373:', data)
if (data && data.code === 0) { if (data && data.code === 0) {
this.associatedGoodsList = [ this.associatedGoodsList = [
...data[this.otherInfo.httpDataValueName] ...data[this.otherInfo.httpDataValueName]

View File

@@ -119,18 +119,19 @@
" "
> >
<div <div
style="width: 90px;float: left;font-weight: 800;border: 1px solid #bbbb; border-radius: 4px;line-height: 30px;" style="width: 120px;float: left;font-weight: 800;line-height: 30px;overflow: hidden;"
> >
<!-- <el-tag type="success" > --> <!-- <el-tag type="success" > -->
{{ v.title }} <span style="width: 80px;float: left;font-weight: 800;border: 1px solid #bbbb; border-radius: 4px;line-height: 30px;"> {{ v.title }} </span>
<!-- </el-tag> --> <span v-if="v.productList.length != 0"><img src="../../../../static/img/editPrice.png" alt="" @click="priceHandle(v)" style="width: 25px;height: 25px;"></span>
<!-- </el-tag> -->
</div> </div>
<div <div
class="right" class="right"
:style=" :style="
`width: calc(100% - ${ `width: calc(100% - ${
scope.row.courseCatalogueEntityList.length > 1 ? 100 : 0 scope.row.courseCatalogueEntityList.length >= 1 ? 130 : 0
}px);float: right;` }px);float: right;`
" "
> >
@@ -405,6 +406,11 @@
></question-bank> ></question-bank>
</div> </div>
</el-drawer> </el-drawer>
<price
v-if="priceVisible"
ref="priceUpdate"
@refreshDataList="getDataList"
></price>
</div> </div>
</template> </template>
@@ -413,9 +419,11 @@ import commonShopTable from "./shopproductTable.vue";
import commonCommont from "@/views/components/courseList/commont.vue"; import commonCommont from "@/views/components/courseList/commont.vue";
import AddOrUpdate from "./course-add-or-update"; import AddOrUpdate from "./course-add-or-update";
import questionBank from "./examination/questionBank"; import questionBank from "./examination/questionBank";
import price from "./catalogue-price";
export default { export default {
data() { data() {
return { return {
priceVisible: false,
selectCourse: {}, selectCourse: {},
showQuestionBank: false, showQuestionBank: false,
commontListVisible: false, commontListVisible: false,
@@ -478,7 +486,8 @@ export default {
AddOrUpdate, AddOrUpdate,
commonShopTable, commonShopTable,
questionBank, questionBank,
commonCommont commonCommont,
price
}, },
activated() { activated() {
if (this.$route.query.upPageInde != null) { if (this.$route.query.upPageInde != null) {
@@ -490,6 +499,13 @@ export default {
this.getTreeList(this.urlList.sociologyList, 2); this.getTreeList(this.urlList.sociologyList, 2);
}, },
methods: { methods: {
priceHandle(row) {
console.log("row1", row);
this.priceVisible = true;
this.$nextTick(() => {
this.$refs.priceUpdate.init(row, this.courseid);
});
},
delPro(val) { delPro(val) {
console.log(val, this.relationProducts); console.log(val, this.relationProducts);
let list = this.relationProducts; let list = this.relationProducts;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,864 @@
<template>
<div class="mod-config">
<commonTree source="tags" @changeCurrentNode="changeCurrentNode" ref="commonTree" :dataList="treeDataList" @getCommonShopDataList="getCommonShopDataList"
@handleClickNodes="handleClickNodes" :urlList="urlList"></commonTree>
<div v-if="isFresh" v-loading="!isFresh"
style="width: calc(100% - 360px); height: 100%; float: right; border: 1px solid #bababa; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); border-radius: 10px;position: relative;">
<div class="border_box info_box">
<div class="title_box">
<div class="title"><span class="line"></span>基本标签信息</div>
</div>
<div class="addFormBox">
<el-form :model="addForm" ref="addForm" label-width="80px">
<el-form-item label="标签名称" prop="title" class="form_item">
<el-input placeholder="请输入标签名称" style="width: 100%" v-model="addForm.title" clearable>
</el-input>
</el-form-item>
<el-form-item label="排序" prop="sort" class="form_item">
<el-input-number placeholder="请输入标签排序" style="width: 100%" v-model="addForm.sort" :min="0" clearable
@keyup.native="UpNumber" @keydown.native="UpNumber">
</el-input-number>
</el-form-item>
<el-form-item label="是否为最终级" prop="isLast" label-width="120px" class="form_item">
<el-switch v-model="addForm.isLast" active-color="#13ce66" :active-value="1" :inactive-value="0"
active-text="" inactive-text="" @change="handleChangeIsLast">
</el-switch>
</el-form-item>
</el-form>
</div>
<div style=" border: 1px dashed #bababa;" v-if="currentNode && currentNode.data.isLast == 1"></div>
</div>
<div class="border_box tree_content_box" v-if="currentNode && currentNode.data.isLast == 1">
<div class="title_box" style="margin-bottom: 10px; height: 40px">
<div class="title">
<span class="line"></span>已关联商品列表
<el-button plain type="primary" style="margin-left: 20px" @click="openTable('addForm')"
size="mini">新增</el-button>
<!-- <div style="" class="button_box"> -->
<el-button plain type="danger" @click="handleCheckAllChange(true)" size="mini">清空</el-button>
<!-- </div> -->
</div>
</div>
<commonShop :currentId="addForm.id ? addForm.id : ''" currentType="bookMarketId" :dataList="associatedGoodsList"
:urlList="urlList" @delete="dataFormDelete" :isEdit="isEdit" :oprateType="oprateType" ref="commonShop" :style="`height: calc(100% - 50px); `"></commonShop>
<!-- <div class="submitButtonBox" v-if="isEdit">
<el-checkbox v-model="checkAll" @change="handleCheckAllChange" style="float: left">全选</el-checkbox>
<div class="submitButton">
<el-button type="danger" @click="dataFormDelete('addForm')" size="small">删除</el-button>
</div>
</div> -->
<!-- <div class="submitButtonBox" v-else> -->
<!-- <el-button @click="handlereset" size="small">取消</el-button> -->
<div class="submitButton submitButtonBox" >
<!-- <el-button size="small" @click.stop="dataFormEdit()">
取消
</el-button> -->
<el-button type="primary" @click="dataFormSubmit('addForm')" size="small">确定</el-button>
<!-- </div> -->
</div>
</div>
<div class="submitButton submitButtonBox" style="position: absolute;bottom: 13px;right: 15px;" v-if="!isEdit">
<!-- <el-button size="small" @click.stop="dataFormEdit()">
取消
</el-button> -->
<el-button type="primary" @click="dataFormSubmit('addForm')" size="small">确定</el-button>
<!-- </div> -->
</div>
</div>
<!-- <el-form
:inline="true"
:model="dataForm"
@keyup.enter.native="getDataList()"
>
</el-form> -->
<commonShopTable ref="commonShopTable" :currentId="addForm.id" currentType="bookMarketId"
@submit="handleSubmitShopTable"></commonShopTable>
<add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update>
</div>
</template>
<script>
import debounce from "lodash/debounce"; //导入lodash中的debounce
import AddOrUpdate from "./commonMedicineTags/bookTagsForm.vue";
import commonShop from "./commonMedicineTags/shopproduct.vue";
import commonShopTable from "./commonMedicineTags/shopproductTable.vue";
import commonTree from "./commonMedicineTags/tags.vue";
// import dialogComponent from './seckillprodrelation'
export default {
data() {
return {
isEdit: false,
checkAll: false,
isIndeterminate: true,
urlList: {
treeList: "/master/psycheLabelAndMarket/marketTree",
delete: "/master/psycheLabelAndMarket/delMarket",
deleteShop: "/master/psycheLabelAndMarket/delToMarket",
saveShop: "/master/psycheLabelAndMarket/saveToMarket",
add: "/master/psycheLabelAndMarket/saveOrUpdateMarket",
getAssociatedGoodsList: "/master/psycheLabelAndMarket/getToMarketList",
},
oprateType:"yingxiao", // yingxiao类型是营销 fenlei:类型是分类
addForm: {},
isFresh: false,
dataRule: {
name: [
{
required: true,
message: "标签名称不能为空",
// trigger: "change",
},
],
},
currentNode: {},
treeDataList: [],
associatedGoodsList: [], //已关联商品列表
isact: "", //当前hover的节点
isactTitle: "", //记录修改节点名称
curNode: undefined, //当前选中节点
isUpdateGroup: false, //是否在修改模板组
filterText: "",
indexRecord: [], //记录节点轨迹
isBreak: false, //是否结束循环
defaultProps: {
children: "children",
label: "title",
},
dataForm: {
key: "",
},
dataList: [],
pageIndex: 1,
pageSize: 10,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
addOrUpdateVisible: false,
};
},
components: {
AddOrUpdate,
commonShop,
commonTree,
commonShopTable,
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
activated() {
this.isEdit = false;
this.getDataList();
},
methods: {
UpNumber(e) {
e.target.value = e.target.value.replace(/[^\d]/g, "");
},
dataFormEdit() {
this.checkAll = false;
this.isEdit = !this.isEdit;
},
handleCheckAllChange(val) {
this.$nextTick(() => {
this.$refs.commonShop.handleCheckAllChange(val);
});
},
handleSubmitShopTable: debounce(async function (ids) {
await this.$http({
url: this.$http.adornUrl(`${this.urlList.saveShop}`),
method: "post",
data: this.$http.adornData({
productId: ids,
psycheMarketId: this.addForm.id,
}),
}).then(async ({ data }) => {
if (data && data.code === 0) {
this.$message.success(data.msg);
if (this.$refs.commonShop) {
this.$refs.commonShop.getAssociatedGoodsList({
bookMarketId: this.addForm.id,
});
}
if (this.$refs.commonShopTable) {
this.$refs.commonShopTable.close();
}
} else {
this.$message.error(data.msg);
}
});
}, 200),
openTable() {
this.isEdit = false;
this.$nextTick(() => {
this.$refs.commonShopTable.open(this.addForm.id);
});
},
handleChangeIsLast(e) {
console.log("🚀 ~ handleChangeIsLast ~ e:", e);
this.$nextTick(() => {
if (e == 1) {
if (this.$refs.commonShop) {
this.$refs.commonShop.getAssociatedGoodsList({
bookMarketId: this.addForm.id ? this.addForm.id : null,
});
}
}
});
},
async getCommonShopDataList(type, id, form) {
this.isFresh = false;
this.isEdit = false;
this.isFresh = true;
console.log("🚀 ~ getCommonShopDataList ~ type, id:", type, id);
this.currentNode = { data: { ...form } }
this.addForm = form;
await this.getDataList();
// this.$refs.commonTree.setCurrentNodeShow();
this.$nextTick(() => {
// this.$refs.commonShop.clear();
// this.$refs.commonShop.bookMarketId = null;
if (form.isLast == 1) {
if (this.$refs.commonShop) {
this.$refs.commonShop.getAssociatedGoodsList();
}
}
});
},
//新增修改
dataFormSubmit: debounce(async function (formName) {
// return false
if (this.addForm.title == "" || !this.addForm.title) {
this.$message.error("请输入标签名称");
return false;
}
await this.$refs[formName].validate(async (valid) => {
if (valid) {
await this.$http({
url: this.$http.adornUrl(`${this.urlList.add}`),
method: "post",
data: this.$http.adornData({
...this.addForm,
}),
}).then(async ({ data }) => {
if (data && data.code === 0) {
// var status = await this.correlationShop(data.result.id);
await this.getDataList();
this.$nextTick(async () => {
this.$refs.commonTree.setCurrentNodeShow(data.result.id);
this.addForm = data.result;
this.currentNode = { data: { ...data.result } }
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.visible = false;
},
});
});
} else {
this.$message.error(data.msg);
}
});
}
});
}, 200),
//新增修改
dataFormDelete: debounce(async function (row, deleteType) {
this.$confirm(`确定要删除${deleteType != 'all' ? '该' : '所有'}关联商品嘛?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(async () => {
var lableIds = row[0].bookLabelId
var productIds = row.map(e => e.productId)
// // return false
// var selectShopArr = this.$refs.commonShop.selectShopArr;
// console.log(selectShopArr, "1111");
// if (selectShopArr.length == 0) {
// this.$message.error("请选择已关联的商品");
// return false;
// }
this.$refs.commonShop.dataListLoading = true;
await this.$http({
url: this.$http.adornUrl(
`${this.urlList.deleteShop}?marketId=${this.addForm.id}&productId=${productIds.toString(",")}`
),
method: "post",
}).then(async ({ data }) => {
if (data && data.code === 0) {
this.$message.success("删除成功");
} else {
this.$message.error(data.msg);
}this.$nextTick(() => {
// this.$refs.commonShop.selectShopArr = [];
if (this.$refs.commonShop) {
this.$refs.commonShop.getAssociatedGoodsList({
bookLabelId: this.addForm.id,
});
}
});
});
})
.catch(() => { });
}, 200),
setCheckedKeys() {
this.$refs.tree.setCheckedKeys([0]);
},
changeCurrentNode(val) {
this.changeCurrentNode = val;
this.$forceUpdate()
},
handlereset() {
this.currentNode = null;
this.isFresh = false;
this.isFresh = true;
},
handleClickNodes(node, data, type) {
this.isEdit = false;
this.addForm = {};
// console.log(this.$refs.tree.handleClickNodes(), "当前选中节点");
console.log(node, data, "当前选中节点");
this.currentNode = node ? node : {};
this.isFresh = false;
this.isFresh = true;
var form = {};
switch (type) {
case "add":
form = { ...data };
break;
case "edit":
form = { ...node.data };
break;
case "addChildren":
form = {
children: [],
delFlag: 0,
isLast: 0,
pid: data.id,
sort: 0,
title: "",
};
break;
}
this.addForm = { ...form };
this.$nextTick(() => {
this.$refs.commonShop.clear();
// this.$refs.commonShop.bookMarketId = null;
this.$refs.commonShop.getDataList(type == "edit" ? form.id : "");
});
},
addOrUpdateHandle() {
var addform = {
children: [],
delFlag: 0,
isLast: 0,
pid: 0,
sort: 0,
title: "",
};
this.handleClickNodes({ data: addform }, addform, "add");
// if (!this.currentNode) {
// this.$message.error("请先选择分类");
// return;
// }
},
filterNode(value, data) {
if (!value) return true;
return data.title.indexOf(value) !== -1;
},
// renderContent(h, { node, data, store }) {
// return;
// `<span
// style="flex: 1; display: flex; align-items: center; justify-content: space-between; padding-right: 8px;"
// on-mouseenter={() => this.mouseenteract(data)}
// on-mouseleave={() => this.mouseleaveact(data)}
// >
// <span>
// <span>{node.label}</span>
// </span>
// {this.isact == data ? (
// <span>
// {this.isact.typeName == "模板组" ? (
// <el-button
// class="m-r-10"
// type="text"
// icon="el-icon-edit"
// on-click={() => this.handleUpdateGroup(node, data)}
// ></el-button>
// ) : (
// <span></span>
// )}
// <el-button
// type="text"
// icon="el-icon-delete"
// on-click={(e) => this.handleDelete(node, data, e)}
// ></el-button>
// </span>
// ) : (
// <span></span>
// )}
// </span>`;
// },
updateRenderContent(h, { node, data, store }) {
return `
<span style="flex: 1; display: flex; align-items: center; justify-content: space-between; padding-right: 8px;">
<span>
{this.isact == data ? (
<input
type="text"
onChange={this.handleChangeTitle.bind(this)}
value={node.label}
/>
) : (
<span>{node.label}</span>
)}
</span>
{this.isact == data ? (
<span>
{this.isact.typeName == "模板组" ? (
<span>
<el-button
class="m-r-10"
type="text"
icon="el-icon-check"
on-click={() => this.updateGroup(node, data)}
></el-button>
<el-button
class="m-r-10"
type="text"
icon="el-icon-close"
on-click={(e) => this.cancelUpdate(node, data, e)}
></el-button>
</span>
) : (
<span></span>
)}
</span>
) : (
<span></span>
)}
</span>`;
},
//获取鼠标进入节点的数据
mouseenteract(da) {
this.isact = da;
},
mouseleaveact(da) {
this.isact = "";
},
handleNodeClick(pdata) {
this.curNode = pdata;
document
.getElementsByClassName("el-tree-node__content")[0]
.setAttribute("class", "el-tree-node__content");
},
handleDelete(node, data, e) {
e.stopPropagation();
//存在则添加到子级
const parent = node.parent;
const children = parent.data.nodes || parent.data;
//若parent.data是对象操作的是子级如果是数组操作的是最外层
if (Array.isArray(parent.data)) {
const parentIndex = parent.data.findIndex((d) => d.id === data.id);
parent.data.splice(parentIndex, 1);
} else {
const childIndex = children.findIndex((d) => d.id === data.id);
children.splice(childIndex, 1);
}
this.curNode = undefined;
},
//新增组
handleAddGroup() {
/**
* 如果模版深度最多两层,取消该部分注释
* //最多只有两层组 不可能添加在dept2的组上 curNode存在 并且 深度超过1
if (this.curNode != undefined && this.curNode.depth != 1) {
this.$message.warning("不能添加超过两层");
return;
}
*/
//如果isUpdateGroup 已经是true了 说明重复点击了
if (this.isUpdateGroup) {
return;
}
let id = ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
(
c ^
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
).toString(16)
);
let newChild = {
parentId: "", //如果有这个id 是插入第二层 否则是第一层 可有可无
text: "", //必须有 this.templateContent.tempName
nodes: [],
id: id,
typeName: "模板组",
temporaryData: "1", //用来区分临时数据
};
/* 如果模版深度最多两层,以下条件改成该部分注释
this.curNode && this.curNode.depth == 1
*/
this.indexRecord = [];
if (this.curNode) {
if (!this.curNode.nodes) {
this.$message.warning("模板不可添加");
return;
}
newChild.parentId = this.curNode.id;
/* 如果模版深度最多两层,以下条件改成该部分注释
const index = this.treeDataList.findIndex(
item => item.id == this.curNode.id
);
this.treeDataList[index].nodes.push(newChild);
*/
//找到tree中的index轨迹
this.getTemplateTreeNode(this.curNode.id, this.treeDataList, 0);
//按照index轨迹插入节点
this.insertNode(
newChild,
this.treeDataList,
this.indexRecord,
this.indexRecord.length
);
this.isBreak = false;
} else if (this.curNode == undefined) {
//没有选中的时候 添加到最外层
newChild.depth = 1;
this.treeDataList.push(newChild);
}
//调用出updateRender的input
this.isact = newChild;
this.isUpdateGroup = true;
},
//递归遍历获得选中node
getTemplateTreeNode(target, list, dept) {
//空数组直接返回
if (list.length == 0) return;
let dataLen = list.length;
for (let i = 0; i < dataLen; i++) {
//如果不匹配
if (target != list[i].id) {
//存在nodes 遍历nodes里的节点
if (list[i].nodes) {
this.indexRecord[dept] = i;
let recordDept = dept + 1;
this.getTemplateTreeNode(target, list[i].nodes, recordDept);
} else {
//不存在nodes 继续遍历
continue;
}
} else {
//匹配,则修改下标数组
this.indexRecord[dept] = i;
this.isBreak = true;
break;
}
//删除不匹配的轨迹 如果已经break了说明已经找到正确的节点就不用再删了
if (!this.isBreak) {
this.indexRecord.pop();
}
}
},
//插入节点
insertNode(insertChild, tree, indexArr, len) {
let index = indexArr.length - len;
if (len == 0) {
tree.push(insertChild);
} else {
this.insertNode(
insertChild,
tree[indexArr[index]].nodes,
indexArr,
len - 1
);
}
},
//修改组
handleUpdateGroup() {
this.isUpdateGroup = true;
},
//修改组名时获取title
handleChangeTitle(e) {
let value = e.target.value;
this.isactTitle = value;
},
updateGroup(node, data) {
//先handleChangeTitle获取title 再调用
setTimeout(() => {
if (this.isactTitle.trim() == "") {
this.$message.warning("名称不能为空");
return;
}
//修改数据组
this.isUpdateGroup = false;
const parent = node.parent;
const children = parent.data.nodes || parent.data;
const index = children.findIndex((d) => d.id === data.id);
let temp = data;
temp.text = this.isactTitle;
children.splice(index, 1, temp);
}, 500);
},
cancelUpdate(node, data, e) {
this.$message.info("已取消");
this.isUpdateGroup = false;
//如果是插入操作 需要移除数据
if (this.isact.temporaryData) {
this.handleDelete(node, data, e);
}
},
// 获取数据列表
async getDataList() {
this.dataListLoading = true;
await this.$http({
url: this.$http.adornUrl(this.urlList.treeList),
method: "get",
// params: this.$http.adornParams({
// 'page': this.pageIndex,
// 'limit': this.pageSize,
// 'key': this.dataForm.key
// })
}).then(({ data }) => {
console.log("🚀 ~ getDataList ~ data:", data);
if (data && data.code === 0) {
this.treeDataList = data.result;
// this.totalPage = data.page.totalCount
} else {
this.treeDataList = [];
// this.totalPage = 0
}
this.dataListLoading = false;
});
},
// 每页数
sizeChangeHandle(val) {
this.pageSize = val;
this.pageIndex = 1;
this.getDataList();
},
// 当前页
currentChangeHandle(val) {
this.pageIndex = val;
this.getDataList();
},
// 多选
selectionChangeHandle(val) {
this.dataListSelections = val;
},
// // 新增 / 修改
// addOrUpdateHandle(row) {
// this.addOrUpdateVisible = true;
// this.$nextTick(() => {
// this.$refs.addOrUpdate.init(row);
// });
// },
},
};
</script>
<style lang="less" scoped>
.tree_box {
width: 350px !important;
height: 100%;
float: left;
border: 1px solid #bababa;
border-radius: 10px;
padding: 15px;
box-sizing: border-box;
// background: #fafafa;
}
.border_box {
height: 100px;
margin-bottom: 10px;
.title_box {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
.button_box {
// width: 200px;
float: right;
}
}
.title {
width: 300px;
min-width: 200px;
float: left;
display: flex;
align-items: center;
font-weight: 600;
font-size: 16px;
// color: #17b3a3;
.line {
width: 4px;
height: 20px;
margin-right: 8px;
background: #17b3a3;
}
}
}
.border_box {
width: 100%;
float: right;
background: #fffefe;
border-radius: 10px;
padding: 15px 15px;
box-sizing: border-box;
}
.tree_content_box {
height: calc(100% - 110px) !important;
}
.mod-config {
width: 100%;
height: 82vh;
overflow: hidden;
}
.el-tree-node__content {
.el-button {
display: none;
}
}
.el-tree-node__content:hover {
.el-button {
display: inline;
}
}
.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
background-color: #eaebed;
color: #4796ec;
font-weight: bold;
}
.el-tree {
height: 350px;
overflow-y: auto !important;
.el-tree-node__content span {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
// .el-card {
// background: none !important;
// }
p {
margin: 0;
margin-bottom: 10px;
}
.submitButtonBox {
margin-top: 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.submitButton {
float: right;
}
// .el-tree-node__content .el-button {
// // width: 120px !important;
// display: block !important;
// }
// ::v-deep .el-tree .el-tree-node__content span:nth-child(2) {
// width: 120px;
// display: flex !important;
// align-items: center !important;
// justify-content: space-between !important;
// }
// /deep/.el-table__row--level-1 {
// display: block !important;
// }
.addFormBox {
overflow: hidden;
.form_item {
width: 33%;
float: left;
}
}
.custom-tree-container {
height: calc(100% - 100px);
.filter-tree {
height: 100%;
}
}
.info_bg {
background: #e0dede;
height: 28px;
line-height: 28px;
padding-left: 10px;
// padding: 8px 5px;
box-sizing: border-box;
// margin-top: -10px;
border-radius: 4px;
font-size: 14px;
width: calc(100% - 120px);
float: left;
}
</style>

View File

@@ -0,0 +1,855 @@
<template>
<div class="mod-config">
<commonTree source="tags" ref="commonTree" :dataList="treeDataList" @getCommonShopDataList="getCommonShopDataList"
@changeCurrentNode="changeCurrentNode" :urlList="urlList"></commonTree>
<div v-if="isFresh" v-loading="!isFresh"
style="width: calc(100% - 360px); height: 100%; float: right; border: 1px solid #bababa; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); border-radius: 10px;position: relative;">
<div class="border_box info_box">
<div class="title_box">
<div class="title"><span class="line"></span>基本标签信息</div>
</div>
<div class="addFormBox">
<el-form :model="addForm" ref="addForm" label-width="80px">
<el-form-item label="标签名称" prop="title" class="form_item">
<el-input placeholder="请输入标签名称" style="width: 100%" v-model="addForm.title" clearable>
</el-input>
</el-form-item>
<el-form-item label="排序" prop="sort" class="form_item">
<el-input-number placeholder="请输入标签排序" style="width: 100%" v-model="addForm.sort" clearable :min="0"
@keyup.native="UpNumber" @keydown.native="UpNumber">
</el-input-number>
</el-form-item>
<el-form-item label="是否为最终级" prop="isLast" label-width="120px" class="form_item">
<el-switch v-model="addForm.isLast" active-color="#13ce66" :active-value="1" :inactive-value="0"
active-text="" inactive-text="" @change="handleChangeIsLast">
</el-switch>
</el-form-item>
</el-form>
</div>
<div style=" border: 1px dashed #bababa;" v-if="currentNode && currentNode.data.isLast == 1"></div>
</div>
<div class="border_box tree_content_box" v-if="currentNode && currentNode.data.isLast == 1">
<div class="title_box" style="margin-bottom: 10px; height: 40px">
<div class="title">
<span class="line"></span>已关联商品列表
<el-button plain type="primary" style="margin-left: 20px" @click="openTable('addForm')"
size="mini">新增</el-button>
<!-- <div style="" class="button_box"> -->
<el-button plain type="danger" @click="handleCheckAllChange(true)" size="mini">清空</el-button>
<!-- </div> -->
</div>
</div>
<commonShop :currentId="addForm.id ? addForm.id : ''" currentType="bookLabelId" :dataList="associatedGoodsList"
:urlList="urlList" :isEdit="isEdit" ref="commonShop" :style="`height: calc(100% - 50px); `"
@delete="dataFormDelete"></commonShop>
<div class="submitButtonBox" v-if="isEdit">
<el-checkbox v-model="checkAll" @change="handleCheckAllChange" style="float: left">全选</el-checkbox>
<!-- <el-button @click="handlereset" size="small">取消</el-button> -->
<div class="submitButton">
<!-- <el-button size="small" @click.stop="dataFormEdit()">
取消
</el-button> -->
<el-button type="danger" @click="dataFormDelete('addForm')" size="small">删除</el-button>
</div>
</div>
<!-- <div class="submitButtonBox" v-else> -->
<!-- <el-button @click="handlereset" size="small">取消</el-button> -->
</div>
<div class="submitButton submitButtonBox" style="position: absolute;bottom: 13px;right: 15px;" v-if="!isEdit">
<!-- <el-button size="small" @click.stop="dataFormEdit()">
取消
</el-button> -->
<el-button type="primary" @click="dataFormSubmit('addForm')" size="small">确定</el-button>
<!-- </div> -->
</div>
</div>
<!-- <el-form
:inline="true"
:model="dataForm"
@keyup.enter.native="getDataList()"
>
</el-form> -->
<commonShopTable ref="commonShopTable" :currentId="addForm.id" currentType="bookLabelId"
@submit="handleSubmitShopTable"></commonShopTable>
<add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update>
</div>
</template>
<script>
import AddOrUpdate from "./commonMedicineTags/bookTagsForm.vue";
import commonShop from "./commonMedicineTags/shopproduct.vue";
import commonShopTable from "./commonMedicineTags/shopproductTable.vue";
import commonTree from "./commonMedicineTags/tags.vue";
import debounce from "lodash/debounce"; //导入lodash中的debounce
// import dialogComponent from './seckillprodrelation'
export default {
data() {
return {
isEdit: false,
checkAll: false,
isIndeterminate: true,
urlList: {
treeList: "/master/psycheLabelAndMarket/labelTree",
delete: "/master/psycheLabelAndMarket/delLabel",
deleteShop: "/master/psycheLabelAndMarket/delToLable",
saveShop: "/master/psycheLabelAndMarket/saveToLabel",
add: "/master/psycheLabelAndMarket/saveOrUpdateLabel",
getAssociatedGoodsList: "/master/psycheLabelAndMarket/getToLabelList",
},
addForm: {},
isFresh: false,
dataRule: {
name: [
{
required: true,
message: "标签名称不能为空",
// trigger: "change",
},
],
},
currentNode: {},
treeDataList: [],
associatedGoodsList: [], //已关联商品列表
isact: "", //当前hover的节点
isactTitle: "", //记录修改节点名称
curNode: undefined, //当前选中节点
isUpdateGroup: false, //是否在修改模板组
filterText: "",
indexRecord: [], //记录节点轨迹
isBreak: false, //是否结束循环
defaultProps: {
children: "children",
label: "title",
},
dataForm: {
key: "",
},
dataList: [],
pageIndex: 1,
pageSize: 10,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
addOrUpdateVisible: false,
};
},
components: {
AddOrUpdate,
commonShop,
commonTree,
commonShopTable,
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
activated() {
this.isEdit = false;
this.getDataList();
},
methods: {
// 只可输入数字
UpNumber(e) {
e.target.value = e.target.value.replace(/[^\d]/g, "");
},
dataFormEdit() {
this.checkAll = false;
this.isEdit = !this.isEdit;
},
handleCheckAllChange(val) {
this.$nextTick(() => {
this.$refs.commonShop.handleCheckAllChange(val);
});
},
handleSubmitShopTable: debounce(async function (ids) {
await this.$http({
url: this.$http.adornUrl(`${this.urlList.saveShop}`),
method: "post",
data: this.$http.adornData({
productId: ids,
psycheLabelId: this.addForm.id,
}),
}).then(async ({ data }) => {
if (data && data.code === 0) {
this.$message.success(data.msg);
if (this.$refs.commonShop) {
this.$refs.commonShop.getAssociatedGoodsList({
bookLabelId: this.addForm.id,
});
}
if (this.$refs.commonShopTable) {
this.$refs.commonShopTable.close();
}
} else {
this.$message.error(data.msg);
}
});
}, 200),
openTable() {
this.isEdit = false;
this.$nextTick(() => {
this.$refs.commonShopTable.open(this.addForm.id);
});
},
handleChangeIsLast(e) {
console.log("🚀 ~ handleChangeIsLast ~ e:", e);
this.$nextTick(() => {
if (e == 1) {
if (this.$refs.commonShop) {
this.$refs.commonShop.getAssociatedGoodsList({
bookLabelId: this.addForm.id ? this.addForm.id : null,
});
}
}
});
},
async getCommonShopDataList(type, id, form) {
this.isFresh = false;
this.isEdit = false; this.isFresh = true;
console.log("🚀 ~ getCommonShopDataList ~ type, id:", type, id);
this.currentNode = { data: { ...form } }
this.addForm = form;
await this.getDataList();
// this.$refs.commonTree.setCurrentNodeShow();
this.$nextTick(() => {
// this.$refs.commonShop.clear();
// this.$refs.commonShop.bookMarketId = null;
if (form.isLast == 1) {
if (this.$refs.commonShop) {
this.$refs.commonShop.getAssociatedGoodsList();
}
}
});
},
//新增修改
dataFormSubmit: debounce(async function (formName) {
// return false
if (this.addForm.title == "" || !this.addForm.title) {
this.$message.error("请输入标签名称");
return false;
}
await this.$refs[formName].validate(async (valid) => {
if (valid) {
await this.$http({
url: this.$http.adornUrl(`${this.urlList.add}`),
method: "post",
data: this.$http.adornData({
...this.addForm,
}),
}).then(async ({ data }) => {
if (data && data.code === 0) {
await this.getDataList();
this.$nextTick(async () => {
this.$refs.commonTree.setCurrentNodeShow(data.result.id);
this.addForm = data.result;
this.currentNode = { data: { ...data.result } }
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.visible = false;
},
});
});
} else {
this.$message.error(data.msg);
}
});
}
});
}, 200),
//删除关联图书
dataFormDelete: debounce(async function (row, deleteType) {
this.$confirm(`确定要删除${deleteType != 'all' ? '该' : '所有'}关联商品嘛?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(async () => {
var lableIds = row[0].bookLabelId
var productIds = row.map(e => e.productId)
// // return false
// var selectShopArr = this.$refs.commonShop.selectShopArr;
// console.log(selectShopArr, "1111");
// if (selectShopArr.length == 0) {
// this.$message.error("请选择已关联的商品");
// return false;
// }
this.$refs.commonShop.dataListLoading = true;
await this.$http({
url: this.$http.adornUrl(
`${this.urlList.deleteShop}?lableId=${this.addForm.id}&productId=${productIds.toString(",")}`
),
method: "post",
}).then(async ({ data }) => {
if (data && data.code === 0) {
this.$message.success("删除成功");
} else {
this.$message.error(data.msg);
}this.$nextTick(() => {
// this.$refs.commonShop.selectShopArr = [];
if (this.$refs.commonShop) {
this.$refs.commonShop.getAssociatedGoodsList({
bookLabelId: this.addForm.id,
});
}
});
});
})
.catch(() => { });
}, 200),
setCheckedKeys() {
this.$refs.tree.setCheckedKeys([0]);
},
changeCurrentNode(val) {
this.changeCurrentNode = val;
this.$forceUpdate()
},
handlereset() {
this.currentNode = null;
this.isFresh = false;
this.isFresh = true;
},
handleClickNodes(node, data, type) {
this.isEdit = false;
this.addForm = {};
// console.log(this.$refs.tree.handleClickNodes(), "当前选中节点");
// console.log(node, data, "当前选中节点");
this.currentNode = node ? node : {};
this.isFresh = false;
this.isFresh = true;
var form = {};
switch (type) {
case "add":
form = { ...data };
break;
case "edit":
form = { ...node.data };
break;
case "addChildren":
form = {
children: [],
delFlag: 0,
isLast: 0,
pid: data.id,
sort: 0,
title: "",
};
break;
}
this.addForm = { ...form };
this.$nextTick(() => {
this.$refs.commonShop.clear();
// this.$refs.commonShop.bookMarketId = null;
this.$refs.commonShop.getDataList(type == "edit" ? form.id : "");
});
},
addOrUpdateHandle() {
var addform = {
children: [],
delFlag: 0,
isLast: 0,
pid: 0,
sort: 0,
title: "",
};
this.handleClickNodes({ data: addform }, addform, "add");
// if (!this.currentNode) {
// this.$message.error("请先选择分类");
// return;
// }
},
filterNode(value, data) {
if (!value) return true;
return data.title.indexOf(value) !== -1;
},
// renderContent(h, { node, data, store }) {
// return;
// `<span
// style="flex: 1; display: flex; align-items: center; justify-content: space-between; padding-right: 8px;"
// on-mouseenter={() => this.mouseenteract(data)}
// on-mouseleave={() => this.mouseleaveact(data)}
// >
// <span>
// <span>{node.label}</span>
// </span>
// {this.isact == data ? (
// <span>
// {this.isact.typeName == "模板组" ? (
// <el-button
// class="m-r-10"
// type="text"
// icon="el-icon-edit"
// on-click={() => this.handleUpdateGroup(node, data)}
// ></el-button>
// ) : (
// <span></span>
// )}
// <el-button
// type="text"
// icon="el-icon-delete"
// on-click={(e) => this.handleDelete(node, data, e)}
// ></el-button>
// </span>
// ) : (
// <span></span>
// )}
// </span>`;
// },
updateRenderContent(h, { node, data, store }) {
return `
<span style="flex: 1; display: flex; align-items: center; justify-content: space-between; padding-right: 8px;">
<span>
{this.isact == data ? (
<input
type="text"
onChange={this.handleChangeTitle.bind(this)}
value={node.label}
/>
) : (
<span>{node.label}</span>
)}
</span>
{this.isact == data ? (
<span>
{this.isact.typeName == "模板组" ? (
<span>
<el-button
class="m-r-10"
type="text"
icon="el-icon-check"
on-click={() => this.updateGroup(node, data)}
></el-button>
<el-button
class="m-r-10"
type="text"
icon="el-icon-close"
on-click={(e) => this.cancelUpdate(node, data, e)}
></el-button>
</span>
) : (
<span></span>
)}
</span>
) : (
<span></span>
)}
</span>`;
},
//获取鼠标进入节点的数据
mouseenteract(da) {
this.isact = da;
},
mouseleaveact(da) {
this.isact = "";
},
handleNodeClick(pdata) {
this.curNode = pdata;
document
.getElementsByClassName("el-tree-node__content")[0]
.setAttribute("class", "el-tree-node__content");
},
handleDelete(node, data, e) {
e.stopPropagation();
//存在则添加到子级
const parent = node.parent;
const children = parent.data.nodes || parent.data;
//若parent.data是对象操作的是子级如果是数组操作的是最外层
if (Array.isArray(parent.data)) {
const parentIndex = parent.data.findIndex((d) => d.id === data.id);
parent.data.splice(parentIndex, 1);
} else {
const childIndex = children.findIndex((d) => d.id === data.id);
children.splice(childIndex, 1);
}
this.curNode = undefined;
},
//新增组
handleAddGroup() {
/**
* 如果模版深度最多两层,取消该部分注释
* //最多只有两层组 不可能添加在dept2的组上 curNode存在 并且 深度超过1
if (this.curNode != undefined && this.curNode.depth != 1) {
this.$message.warning("不能添加超过两层");
return;
}
*/
//如果isUpdateGroup 已经是true了 说明重复点击了
if (this.isUpdateGroup) {
return;
}
let id = ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
(
c ^
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
).toString(16)
);
let newChild = {
parentId: "", //如果有这个id 是插入第二层 否则是第一层 可有可无
text: "", //必须有 this.templateContent.tempName
nodes: [],
id: id,
typeName: "模板组",
temporaryData: "1", //用来区分临时数据
};
/* 如果模版深度最多两层,以下条件改成该部分注释
this.curNode && this.curNode.depth == 1
*/
this.indexRecord = [];
if (this.curNode) {
if (!this.curNode.nodes) {
this.$message.warning("模板不可添加");
return;
}
newChild.parentId = this.curNode.id;
/* 如果模版深度最多两层,以下条件改成该部分注释
const index = this.treeDataList.findIndex(
item => item.id == this.curNode.id
);
this.treeDataList[index].nodes.push(newChild);
*/
//找到tree中的index轨迹
this.getTemplateTreeNode(this.curNode.id, this.treeDataList, 0);
//按照index轨迹插入节点
this.insertNode(
newChild,
this.treeDataList,
this.indexRecord,
this.indexRecord.length
);
this.isBreak = false;
} else if (this.curNode == undefined) {
//没有选中的时候 添加到最外层
newChild.depth = 1;
this.treeDataList.push(newChild);
}
//调用出updateRender的input
this.isact = newChild;
this.isUpdateGroup = true;
},
//递归遍历获得选中node
getTemplateTreeNode(target, list, dept) {
//空数组直接返回
if (list.length == 0) return;
let dataLen = list.length;
for (let i = 0; i < dataLen; i++) {
//如果不匹配
if (target != list[i].id) {
//存在nodes 遍历nodes里的节点
if (list[i].nodes) {
this.indexRecord[dept] = i;
let recordDept = dept + 1;
this.getTemplateTreeNode(target, list[i].nodes, recordDept);
} else {
//不存在nodes 继续遍历
continue;
}
} else {
//匹配,则修改下标数组
this.indexRecord[dept] = i;
this.isBreak = true;
break;
}
//删除不匹配的轨迹 如果已经break了说明已经找到正确的节点就不用再删了
if (!this.isBreak) {
this.indexRecord.pop();
}
}
},
//插入节点
insertNode(insertChild, tree, indexArr, len) {
let index = indexArr.length - len;
if (len == 0) {
tree.push(insertChild);
} else {
this.insertNode(
insertChild,
tree[indexArr[index]].nodes,
indexArr,
len - 1
);
}
},
//修改组
handleUpdateGroup() {
this.isUpdateGroup = true;
},
//修改组名时获取title
handleChangeTitle(e) {
let value = e.target.value;
this.isactTitle = value;
},
updateGroup(node, data) {
//先handleChangeTitle获取title 再调用
setTimeout(() => {
if (this.isactTitle.trim() == "") {
this.$message.warning("名称不能为空");
return;
}
//修改数据组
this.isUpdateGroup = false;
const parent = node.parent;
const children = parent.data.nodes || parent.data;
const index = children.findIndex((d) => d.id === data.id);
let temp = data;
temp.text = this.isactTitle;
children.splice(index, 1, temp);
}, 500);
},
cancelUpdate(node, data, e) {
this.$message.info("已取消");
this.isUpdateGroup = false;
//如果是插入操作 需要移除数据
if (this.isact.temporaryData) {
this.handleDelete(node, data, e);
}
},
// 获取数据列表
async getDataList() {
this.dataListLoading = true;
await this.$http({
url: this.$http.adornUrl(this.urlList.treeList),
method: "get",
}).then(({ data }) => {
console.log("🚀 ~ getDataList ~ data:", data);
if (data && data.code === 0) {
this.treeDataList = data.result;
// this.totalPage = data.page.totalCount
} else {
this.treeDataList = [];
// this.totalPage = 0
}
this.dataListLoading = false;
});
},
// 每页数
sizeChangeHandle(val) {
this.pageSize = val;
this.pageIndex = 1;
this.getDataList();
},
// 当前页
currentChangeHandle(val) {
this.pageIndex = val;
this.getDataList();
},
// 多选
selectionChangeHandle(val) {
this.dataListSelections = val;
},
// // 新增 / 修改
// addOrUpdateHandle(row) {
// this.addOrUpdateVisible = true;
// this.$nextTick(() => {
// this.$refs.addOrUpdate.init(row);
// });
// },
},
};
</script>
<style lang="less" scoped>
.tree_box {
width: 350px !important;
height: 100%;
float: left;
border: 1px solid #bababa;
border-radius: 10px;
padding: 15px;
box-sizing: border-box;
// background: #fafafa;
}
.border_box {
height: 100px;
margin-bottom: 10px;
.title_box {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
.button_box {
// width: 200px;
float: right;
}
}
.title {
width: 300px;
min-width: 200px;
float: left;
display: flex;
align-items: center;
font-weight: 600;
font-size: 16px;
// color: #17b3a3;
.line {
width: 4px;
height: 20px;
margin-right: 8px;
background: #17b3a3;
}
}
}
.border_box {
width: 100%;
float: right;
background: #fffefe;
border-radius: 10px;
padding: 15px 15px;
box-sizing: border-box;
}
.tree_content_box {
height: calc(100% - 110px) !important;
}
.mod-config {
width: 100%;
height: 82vh;
overflow: hidden;
}
.el-tree-node__content {
.el-button {
display: none;
}
}
.el-tree-node__content:hover {
.el-button {
display: inline;
}
}
.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
background-color: #eaebed;
color: #4796ec;
font-weight: bold;
}
.el-tree {
height: 350px;
overflow-y: auto !important;
.el-tree-node__content span {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
// .el-card {
// background: none !important;
// }
p {
margin: 0;
margin-bottom: 10px;
}
.submitButtonBox {
margin-top: 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.submitButton {
float: right;
}
// .el-tree-node__content .el-button {
// // width: 120px !important;
// display: block !important;
// }
// ::v-deep .el-tree .el-tree-node__content span:nth-child(2) {
// width: 120px;
// display: flex !important;
// align-items: center !important;
// justify-content: space-between !important;
// }
// /deep/.el-table__row--level-1 {
// display: block !important;
// }
.addFormBox {
overflow: hidden;
.form_item {
width: 33%;
float: left;
}
}
.custom-tree-container {
height: calc(100% - 100px);
.filter-tree {
height: 100%;
}
}
.info_bg {
background: #e0dede;
height: 28px;
line-height: 28px;
padding-left: 10px;
// padding: 8px 5px;
box-sizing: border-box;
// margin-top: -10px;
border-radius: 4px;
font-size: 14px;
width: calc(100% - 120px);
float: left;
}
</style>

BIN
static/img/editPrice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB