master
lion 1 year ago
parent 2c19a5a489
commit 4345926d07

@ -49,12 +49,14 @@
default: false,
},
plugins: {
type: [String, Array],
default: "code image axupimgs paste preview searchreplace autolink directionality visualblocks visualchars fullscreen template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave ",
type: [String, Array],
// axupimgs
default: "code image paste preview searchreplace autolink directionality visualblocks visualchars fullscreen template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave ",
},
toolbar: {
type: [String, Array],
default: ` undo redo restoredraft | code | image | axupimgs | imagetools | assignment | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough anchor | alignleft aligncenter alignright alignjustify outdent indent |
type: [String, Array],
// axupimgs
default: ` undo redo restoredraft | code | image | imagetools | assignment | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough anchor | alignleft aligncenter alignright alignjustify outdent indent |
styleselect formatselect fontselect fontsizeselect | table charmap emoticons hr pagebreak | bullist numlist | blockquote subscript superscript removeformat |
insertdatetime print preview | fullscreen | bdmap indent2em lineheight formatpainter`,
},
@ -69,8 +71,8 @@
showImg: false,
imgUploadUrl: `${process.env.VUE_APP_UPLOAD_API}`,
init: {
language_url: "/public/tinymce/langs/zh_CN.js", //
language: "zh_CN",
// language_url: "/public/tinymce/langs/zh_CN.js", //
// language: "zh_CN",
height: this.height,
plugins: this.plugins,
fontsize_formats: "8px 10px 12px 14px 16px 18px 24px 28px 36px",
@ -92,7 +94,7 @@
let file = blobInfo.blob();
const isLt2M = file.size / 1024 < 2048;
if (!isLt2M) {
failure("上传失败图片不可超过2M!");
failure("Upload failed, the image cannot exceed 2M");
return false;
}
let formdate = new FormData();

@ -108,17 +108,27 @@
methods: {
//
clickSource(active, editor) {
let value = editor.getHtml();
let value = this.editor.getHtml();
console.log("getHtml",value)
//
this.editor.clear();
if (active) {
// htmlhtml dangerouslyInsertHtmlhtmlhtml
this.editor.dangerouslyInsertHtml(parseEditorCode(value));
// htmlhtml dangerouslyInsertHtmlhtmlhtml
value = parseEditorCode(value)
console.log("active",value)
this.editor.dangerouslyInsertHtml(value);
this.html = value
} else {
// htmleditorhtml
this.editor.dangerouslyInsertHtml(parseCodeEditor(value));
// console.log("parseCodeEditor(value)", parseCodeEditor(value))
value = parseCodeEditor(value);
// htmleditorhtml
value = parseCodeEditor(value)
console.log("else", value)
this.editor.dangerouslyInsertHtml(value);
// value = parseCodeEditor(value);
console.log("nowHtml",parseCodeEditor(this.editor.getHtml()))
this.html = value
}
},
onCreated(editor) {
@ -133,8 +143,10 @@
onChange() {
const text = this.editor.getText();
//
this.useLen = (text || '').length;
// change
this.useLen = (text || '').length;
let value = this.editor.getHtml();
// change
console.log("this.html",value)
this.$emit('change', this.html);
},

@ -1,65 +1,72 @@
import SourceMenu from "./sourceMenu.js";
import prettier from 'prettier/standalone';
import parserHtml from 'prettier/parser-html';
/**
* 在编辑器中得到的html源码是没有格式的html字符串
* 所以需要格式化展示代码
* 格式化html代码
*/
export const parserHtmlCode = (code) => {
try {
return prettier.format(code, {
parser: 'html',
plugins: [parserHtml],
// 格式化的标签不换行 例如span标签等>格式化后会换行
htmlWhitespaceSensitivity: 'ignore'
});
} catch (e) {
console.error('格式化代码错误', e);
return code;
}
}
/**
* 将编辑器html转换为代码块内容
*/
export const parseEditorCode = (html) => {
const code = html
.replace(/&nbsp;/g, '')
.replace(new RegExp('<p><br></p>', 'g'), '');
const data = parserHtmlCode(code).trim();
const textCode = data
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
import SourceMenu from "./sourceMenu.js";
import prettier from 'prettier/standalone';
import parserHtml from 'prettier/parser-html';
/**
* 在编辑器中得到的html源码是没有格式的html字符串
* 所以需要格式化展示代码
* 格式化html代码
*/
export const parserHtmlCode = (code) => {
try {
return prettier.format(code, {
parser: 'html',
plugins: [parserHtml],
// 格式化的标签不换行 例如span标签等>格式化后会换行
htmlWhitespaceSensitivity: 'ignore'
});
} catch (e) {
console.error('格式化代码错误', e);
return code;
}
}
/**
* 将编辑器html转换为代码块内容
*/
export const parseEditorCode = (html) => {
const code = html
.replace(/&nbsp;/g, '')
.replace(new RegExp('<p><br></p>', 'g'), '');
const data = parserHtmlCode(code).trim();
const textCode = data
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/ /g, "&nbsp;");
return `<pre><code class="language-html">${textCode}</code></pre>`;
}
/**
* 将代码块转换为编辑器html
*/
export const parseCodeEditor = (preCode) => {
// 转码
let data = encodeURI(preCode);
// 将&nbsp;转换为空格
data = data.replace(/%C2%A0/g, '%20');
// 解码
data = decodeURI(data);
const htmlStr = data
.replace('<pre><code class="language-html">', '')
.replace('</code></pre>', '')
.replace(/&lt;/ig, "<")
console.log("textcode",textCode)
return `<pre><code class="language-html">${textCode}</code></pre>`;
// return `${textCode}`;
}
/**
* 将代码块转换为编辑器html
*/
export const parseCodeEditor = (preCode) => {
// 转码
let data = encodeURI(preCode);
// 将&nbsp;转换为空格
data = data.replace(/%C2%A0/g, '%20');
// 解码
data = decodeURI(data);
const htmlStr = data
.replace('<pre><code class="language-html">', '')
.replace('</code></pre>', '')
.replace(/&lt;/ig, "<")
.replace(/&gt;/ig, ">");
return htmlStr
.replace(new RegExp('\\n', 'g'), '')
.replace(new RegExp('<p><br></p>', 'g'), '')
.trim();
}
export const sourceConf = {
// 工具栏中的唯一key
key: 'source',
// 组件
factory: () => new SourceMenu()
console.log("htmlStr",htmlStr
.replace(new RegExp('\\n', 'g'), '')
.replace(new RegExp('<p><br></p>', 'g'), '')
.trim())
return htmlStr
.replace(new RegExp('\\n', 'g'), '')
.replace(new RegExp('<p><br></p>', 'g'), '')
.trim();
}
export const sourceConf = {
// 工具栏中的唯一key
key: 'source',
// 组件
factory: () => new SourceMenu()
};

@ -9,11 +9,11 @@ export default {
}
},
created() {
this.getProductList()
this.getProductParaList()
},
methods: {
// 获取产品参数 有detail的下拉没有的填写
async getProductList(){
async getProductParaList(){
const res = await listparameter({
page: 1,
page_size: 999,

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 4052909 */
src: url('iconfont.woff2?t=1683361610626') format('woff2'),
url('iconfont.woff?t=1683361610626') format('woff'),
url('iconfont.ttf?t=1683361610626') format('truetype');
font-family: "iconfont"; /* Project id 4764550 */
src: url('iconfont.woff2?t=1732857913289') format('woff2'),
url('iconfont.woff?t=1732857913289') format('woff'),
url('iconfont.ttf?t=1732857913289') format('truetype');
}
.iconfont {
@ -13,107 +13,119 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-jurassic_process-list:before {
content: "\e6c4";
.icon-product:before {
content: "\e611";
}
.icon-biaodan:before {
content: "\e663";
.icon-icon_note:before {
content: "\e64c";
}
.icon-biaozhunhuaguizeguanli:before {
content: "\e60a";
.icon-zixunguanli:before {
content: "\e610";
}
.icon-a-zhidu6:before {
content: "\eb07";
.icon-application-parameters:before {
content: "\e642";
}
.icon-dat:before {
content: "\e691";
.icon-chanpinxuanze:before {
content: "\e6ca";
}
.icon-audio:before {
content: "\e692";
.icon-chanpincanshu:before {
content: "\e600";
}
.icon-video:before {
content: "\e693";
.icon-fangwenjilu:before {
content: "\e602";
}
.icon-zip:before {
content: "\e694";
.icon-liuyan:before {
content: "\e627";
}
.icon-image:before {
content: "\e695";
.icon-xuanze:before {
content: "\e68b";
}
.icon-pdf:before {
content: "\e696";
.icon-phase:before {
content: "\e620";
}
.icon-ppt:before {
content: "\e697";
.icon-yonghuzhongxin:before {
content: "\e68c";
}
.icon-21excel:before {
content: "\e698";
.icon-dingdan:before {
content: "\e897";
}
.icon-21word:before {
content: "\e699";
.icon-dingdanjihe:before {
content: "\e898";
}
.icon-21move:before {
content: "\e69a";
.icon-Usermanuals:before {
content: "\e607";
}
.icon-21setting:before {
content: "\e69b";
.icon-interact:before {
content: "\e86a";
}
.icon-21upload:before {
content: "\e69c";
.icon-application:before {
content: "\e88a";
}
.icon-21download:before {
content: "\e69d";
.icon-gonggongshiye:before {
content: "\e613";
}
.icon-21cancel:before {
content: "\e69e";
.icon-ziyuanguanli:before {
content: "\e770";
}
.icon-21ok:before {
content: "\e69f";
.icon--Faq:before {
content: "\e60e";
}
.icon-21copy:before {
content: "\e6a0";
.icon-mulu:before {
content: "\e60f";
}
.icon-21delete:before {
content: "\e6a1";
.icon-yonghuliebiao:before {
content: "\e7f1";
}
.icon-21edit:before {
content: "\e6a2";
.icon-webinar:before {
content: "\ec3c";
}
.icon-21new:before {
content: "\e6a3";
.icon-longzishuxing:before {
content: "\e601";
}
.icon-21folder:before {
content: "\e6a4";
.icon-chanpinfenlei:before {
content: "\e656";
}
.icon-21mutil:before {
content: "\e6a5";
.icon-canshuguanli:before {
content: "\e640";
}
.icon-21file:before {
content: "\e6a6";
.icon-chanpinzhongxin:before {
content: "\e603";
}
.icon-ic_flyer:before {
content: "\e60b";
}
.icon-market-poster:before {
content: "\e7a7";
}
.icon-yingyongfenlei:before {
content: "\e6fb";
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -25,6 +25,19 @@ let base = {
isUrl (url) {
return this.checkUrl(url)
},
// 判断数组中 是否有相同的 项
findDuplicateKeys(arr, key) {
const seen = new Set();
const duplicates = new Set();
for (const item of arr) {
if (seen.has(item[key])) {
duplicates.add(item[key]); // 添加重复的key值
} else {
seen.add(item[key]);
}
}
return Array.from(duplicates); // 将Set转换为数组并返回
},
checkUrl (url) {
// url= 协议://(ftp的登录信息)[IP|域名](:端口号)(/或?请求参数)
var strRegex =

@ -181,7 +181,6 @@
filesList: [],
appCategoryList: [],
productCategoryList:[],
showWang: false,
detail_item: [{
type: 'index',
width: 50
@ -236,9 +235,6 @@
}
this.filesList = fileList
},
changeEditor(e) {
this.form.content = e
},
addRow() {
var len = this.form.application_details.length;
this.form.application_details.push({
@ -300,9 +296,7 @@
show_relation: ['applicationDetails']
}).then(res => {
this.form = this.base.requestToForm(res, this.form)
this.form.content = res.content ? res.content : ''
this.form.application_details = res.application_details ? res.application_details : [],
this.showWang = true
this.form.application_details = res.application_details ? res.application_details : []
if (res.files && res.files.length > 0) {
this.filesList = []
res.files.map(item => {
@ -322,11 +316,9 @@
if (this.type === 'editor') {
this.getDetail()
}
this.showWang = true
} else {
this.id = ''
this.filesList = []
this.showWang = false
this.form = {
application_type_id: '',
category_id:[],
@ -349,7 +341,6 @@
<style scoped lang="scss">
::v-deep .file_ids,
::v-deep .content,
::v-deep .application_details {
flex-basis: 100%;
}

@ -19,7 +19,8 @@
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>Content
</div>
<div class="xy-table-item-content">
<wangEditor :isShow="isShow" v-show="showWang" :value="form.content" @change="changeEditor"></wangEditor>
<!-- <wangEditor :isShow="isShow" v-show="showWang" :value="form.content" @change="changeEditor"></wangEditor> -->
<my-tinymce v-if="showWang" @input="changeEditor" :value="form.content"></my-tinymce>
</div>
</div>

@ -61,7 +61,7 @@
<template slot-scope="scope">
<el-select style="width:100%" @change="(key)=>{changeKey(key,scope.row)}" v-model="scope.row.key"
placeholder="Please Select">
<el-option v-for="(pvalue,key,index) in productDetailsKeyList" :key="index" :label="pvalue.key"
<el-option v-for="(pvalue,key,index) in selectList" :key="index" :label="pvalue.key"
:value="pvalue.key">
</el-option>
</el-select>
@ -125,7 +125,8 @@
token: ""
},
action: `${process.env.VUE_APP_UPLOAD_API}`,
pictureList: [],
pictureList: [],
selectList:[],
detail_item: [{
type: 'index',
width: 50,
@ -205,7 +206,29 @@
this.form.picture_id = p_files[0]
} else {
this.form.picture_id = ''
}
}
if(this.form.product_category_details.length>0){
//
for(var p of this.form.product_category_details){
if(p.value.length<1){
this.$message({
type: 'warning',
message: `${p.key} cannot be empty in the property`
})
return
}
}
//
let filterArr = this.base.findDuplicateKeys(this.form.product_category_details,'key')
if(filterArr.length>0){
this.$message({
type: 'warning',
message: `${filterArr.join("、")} cannot be repeated in the property`
})
return
}
}
console.log("this.form", this.form)
// return
save({
@ -250,11 +273,26 @@
if (newVal) {
if (this.type === 'editor') {
this.getDetail()
}
for(var k in this.productDetailsKeyList){
if(this.productDetailsKeyList[k]["type"]==='select'){
this.selectList.push(this.productDetailsKeyList[k])
if (this.type === 'add') {
this.form.product_category_details.push({
key:this.productDetailsKeyList[k]["key"],
type:this.productDetailsKeyList[k]["type"],
value:[],
list:this.productDetailsKeyList[k]["list"]
})
}
}
}
} else {
this.id = ''
this.type = "add"
this.pictureList = []
this.pictureList = []
this.selectList = []
this.form = {
name: '',
sort: 0,

@ -59,57 +59,57 @@
</el-upload>
</div>
</div>
</template>
<template v-slot:product_category_details>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>Property
</div>
<div class="xy-table-item-content">
<el-button type="primary" style="margin-bottom:10px" size="small" @click="addRow">Add</el-button>
<xy-table style="width:850px" :list="form.product_category_details" :isPage="false" :height="350"
:table-item="detail_item">
<template v-slot:key>
<el-table-column align='left' label="key" width="340">
<template slot-scope="scope">
<el-select style="width:100%" @change="(key)=>{changeKey(key,scope.row)}" v-model="scope.row.key"
placeholder="Please Select">
<el-option v-for="(pvalue,key,index) in productDetailsKeyList" :key="index" :label="pvalue.key"
:value="pvalue.key">
</el-option>
</el-select>
</template>
</el-table-column>
</template>
<template v-slot:value>
<el-table-column align='left' label="value" width="340">
<template slot-scope="scope">
<el-select multiple collapse-tags v-if="scope.row.type==='select'" style="width:100%"
v-model="scope.row.value" placeholder="Please Select">
<el-option v-for="(item,index) in scope.row.list" :key="index" :label="item.value"
:value="item.value">
</el-option>
</el-select>
<el-input v-else placeholder="Please Input" style="width:100%" v-model="scope.row.value"></el-input>
</template>
</el-table-column>
</template>
<template v-slot:btns>
<el-table-column align='center' label="operate" width="120" header-align="center">
<template slot-scope="scope">
<el-popconfirm confirm-button-text="confirm" cancel-button-text="cancel" style="margin:0 10px"
@confirm="delRow(scope.$index)" title="Are you sure to delete it?">
<el-button type="danger" size="small" slot="reference">delete</el-button>
</el-popconfirm>
</template>
</el-table-column>
</template>
</xy-table>
</div>
</div>
</template>
</template>
<template v-slot:product_category_details>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>Property
</div>
<div class="xy-table-item-content">
<el-button type="primary" style="margin-bottom:10px" size="small" @click="addRow">Add</el-button>
<xy-table style="width:850px" :list="form.product_category_details" :isPage="false" :height="350"
:table-item="detail_item">
<template v-slot:key>
<el-table-column align='left' label="key" width="340">
<template slot-scope="scope">
<el-select style="width:100%" @change="(key)=>{changeKey(key,scope.row)}" v-model="scope.row.key"
placeholder="Please Select">
<el-option v-for="(pvalue,key,index) in productDetailsKeyList" :key="index" :label="pvalue.key"
:value="pvalue.key">
</el-option>
</el-select>
</template>
</el-table-column>
</template>
<template v-slot:value>
<el-table-column align='left' label="value" width="340">
<template slot-scope="scope">
<el-select multiple collapse-tags v-if="scope.row.type==='select'" style="width:100%"
v-model="scope.row.value" placeholder="Please Select">
<el-option v-for="(item,index) in scope.row.list" :key="index" :label="item.value"
:value="item.value">
</el-option>
</el-select>
<el-input v-else placeholder="Please Input" style="width:100%" v-model="scope.row.value"></el-input>
</template>
</el-table-column>
</template>
<template v-slot:btns>
<el-table-column align='center' label="operate" width="120" header-align="center">
<template slot-scope="scope">
<el-popconfirm confirm-button-text="confirm" cancel-button-text="cancel" style="margin:0 10px"
@confirm="delRow(scope.$index)" title="Are you sure to delete it?">
<el-button type="danger" size="small" slot="reference">delete</el-button>
</el-popconfirm>
</template>
</el-table-column>
</template>
</xy-table>
</div>
</div>
</template>
<template v-slot:product_category_applications>
<div class="xy-table-item">
@ -138,7 +138,7 @@
</div>
</div>
</template>
<!-- <template v-slot:download_ids>
<!-- <template v-slot:download_ids>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>Downloads
@ -153,14 +153,17 @@
</template> -->
<template v-slot:characteristics>
<template v-slot:character>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>Characteristics
</div>
<div class="xy-table-item-content">
<wangEditor :isShow="isShow" v-show="showWang" :value="form.characteristics"
@change="(e)=>{changeEditor(e,'characteristics')}"></wangEditor>
<!-- <wangEditor :isShow="isShow" v-show="showWang" :value="form.character"
@change="(e)=>{changeEditor(e,'character')}"></wangEditor> -->
<my-tinymce v-if="showWang" @input="(e)=>{changeEditor(e,'character')}"
:value="form.character"></my-tinymce>
</div>
</div>
</template>
@ -189,9 +192,9 @@
save,
show,
index
} from "@/api/product/category.js"
import {
getToken
} from "@/api/product/category.js"
import {
getToken
} from '@/utils/auth'
import {
destroy,
@ -219,6 +222,7 @@
pictureList: [],
downloadsList: [],
applicationsList: [],
selectList: [],
application_detail_item: [{
type: 'index',
width: 50,
@ -227,34 +231,34 @@
label: 'Title',
align: 'left',
width: 620
}],
detail_item: [{
type: 'index',
width: 50,
}, {
prop: 'key',
label: 'Key',
align: 'left',
width: 620
}, {
prop: 'value',
label: 'Value',
align: 'left',
width: 620
}],
detail_item: [{
type: 'index',
width: 50,
}, {
prop: 'key',
label: 'Key',
align: 'left',
width: 620
}, {
prop: 'value',
label: 'Value',
align: 'left',
width: 620
}],
form: {
product_category_links_by_sub: [],
name: '',
sort: 0,
description: '',
picture_id: '',
product_category_details:[],
picture_id: '',
product_category_details: [],
product_category_applications: [],
download_ids: [],
characteristics: '',
packing: '',
character: '',
// packing: '',
pid: 0,
},
rules: {
@ -308,21 +312,21 @@
changeEditor(e, type) {
this.form[type] = e
},
// product_category_details
addRow() {
this.form.product_category_details.push({
key: '',
type:'select',
value: []
})
},
delRow(index) {
this.form.product_category_details.splice(index, 1)
},
changeKey(e,row) {
row.type = this.productDetailsKeyList[e].type
row.list = this.productDetailsKeyList[e].list
row.value = row.type=='select'?[]:''
// product_category_details
addRow() {
this.form.product_category_details.push({
key: '',
type: 'select',
value: []
})
},
delRow(index) {
this.form.product_category_details.splice(index, 1)
},
changeKey(e, row) {
row.type = this.productDetailsKeyList[e].type
row.list = this.productDetailsKeyList[e].list
row.value = row.type == 'select' ? [] : ''
},
// addApplication
addAppRow(id, type) {
@ -381,7 +385,7 @@
})
})
}
this.form.product_category_links_by_sub = pc_arr
this.form.product_category_links_by_sub = pc_arr
let d_files = []
if (this.downloadsList.length > 0) {
@ -409,7 +413,7 @@
this.form.picture_id = p_files[0]
} else {
this.form.picture_id = ''
}
}
// application
let a_ids = []
if (this.applicationsList.length > 0) {
@ -419,6 +423,28 @@
this.form.product_category_applications = a_ids
}
this.form.type = 2
if (this.form.product_category_details.length > 0) {
//
for (var p of this.form.product_category_details) {
if (p.value.length < 1) {
this.$message({
type: 'warning',
message: `${p.key} cannot be empty in the property`
})
return
}
}
//
let filterArr = this.base.findDuplicateKeys(this.form.product_category_details, 'key')
if (filterArr.length > 0) {
this.$message({
type: 'warning',
message: `${filterArr.join("、")} cannot be repeated in the property`
})
return
}
}
console.log("this.form", this.form)
// return
save({
@ -439,10 +465,10 @@
show_relation: ['productCategoryApplications', 'picture'],
}).then(res => {
this.form = this.base.requestToForm(res, this.form)
this.description = res.description ? res.description : ''
this.characteristics = res.characteristics ? res.characteristics : ''
this.packing = res.packing ? res.packing : ''
this.applicationsList = res.product_category_applications
this.form.description = res.description ? res.description : ''
this.form.character = res.character ? res.character : ''
// this.packing = res.packing ? res.packing : ''
this.form.applicationsList = res.product_category_applications
this.showWang = true
// category
@ -452,14 +478,14 @@
this.pcSubList.push(pc.main_category_id)
})
}
// product_category_details
res.product_category_details.map(item=>{
item.type = this.productDetailsKeyList[item.key]['type']
if(this.productDetailsKeyList[item.key].type==='select'){
item.list = this.productDetailsKeyList[item.key]['list']
}
})
this.form.product_category_details = res.product_category_details
// product_category_details
res.product_category_details.map(item => {
item.type = this.productDetailsKeyList[item.key]['type']
if (this.productDetailsKeyList[item.key].type === 'select') {
item.list = this.productDetailsKeyList[item.key]['list']
}
})
this.form.product_category_details = res.product_category_details
if (res.download && res.download.length > 0) {
this.downloadsList = []
@ -488,9 +514,20 @@
this.getCategoryList()
if (this.type === 'editor') {
this.getDetail()
} else if (this.type === 'add') {
this.form.pid = 0
this.form.pName = 'Top'
}
for (var k in this.productDetailsKeyList) {
if (this.productDetailsKeyList[k]["type"] === 'select') {
this.selectList.push(this.productDetailsKeyList[k])
if (this.type === 'add') {
this.form.product_category_details.push({
key: this.productDetailsKeyList[k]["key"],
type: this.productDetailsKeyList[k]["type"],
value: [],
list: this.productDetailsKeyList[k]["list"]
})
}
}
}
this.showWang = true
} else {
@ -500,17 +537,18 @@
this.downloadsList = []
this.pictureList = []
this.applicationsList = []
this.selectList = []
this.form = {
product_category_links_by_sub: [],
name: '',
sort: 0,
picture_id: '',
product_category_details:[],
picture_id: '',
product_category_details: [],
product_category_applications: [],
download_ids: [],
description: '',
characteristics: '',
packing: '',
character: '',
// packing: '',
pid: 0,
}
this.$refs['dialog'].reset()
@ -529,7 +567,7 @@
::v-deep .download_ids,
::v-deep .description,
::v-deep .packing,
::v-deep .characteristics,
::v-deep .character,
{
flex-basis: 100%;
}

@ -1,6 +1,6 @@
<template>
<div>
<xy-dialog ref="dialog" :width="70" :is-show.sync="isShow" :type="'form'" :title="$route.meta.title" :form="form"
<xy-dialog ref="dialog" :width="60" :is-show.sync="isShow" :type="'form'" :title="$route.meta.title" :form="form"
:rules='rules' @submit="submit">
<template v-slot:name>
<div class="xy-table-item">
@ -28,9 +28,9 @@
<span style="color: red;font-weight: bold;padding-right: 4px;">*</span>Product Phase
</div>
<div class="xy-table-item-content">
<el-select multiple style="width:100%" v-model="form.category_id" placeholder="Please Select">
<el-option v-for="(item,index) in categoryList" :key="index" :label="item.name" :value="item.id">
</el-option>
<el-select multiple style="width:100%" v-model="form.category_id" placeholder="Please Select">
<el-option v-for="(item,index) in categoryList" :key="index" :label="item.name" :value="item.id">
</el-option>
</el-select>
</div>
</div>
@ -104,9 +104,9 @@
</div>
<div class="xy-table-item-content">
<el-button type="primary" style="margin-bottom:10px" size="small" @click="addRow">Add Row</el-button>
<xy-table :list="form.product_details" :isPage="false" :height="350" :table-item="detail_item">
<xy-table style="width:850px" :list="form.product_details" :isPage="false" :height="350" :table-item="detail_item">
<template v-slot:key>
<el-table-column align='left' label="key">
<el-table-column align='left' label="key" width="340">
<template slot-scope="scope">
<el-select style="width:100%" @change="(key)=>{changeKey(key,scope.row)}" v-model="scope.row.key"
placeholder="Please Select">
@ -118,7 +118,7 @@
</el-table-column>
</template>
<template v-slot:value>
<el-table-column align='left' label="value">
<el-table-column align='left' label="value" width="340">
<template slot-scope="scope">
<el-select v-if="scope.row.type==='select'" style="width:100%" v-model="scope.row.value"
placeholder="Please Select">
@ -240,7 +240,7 @@
},
changeEditor(e) {
this.form.content = e
},
},
// product_details
addRow() {
var len = this.form.product_details.length;
@ -276,7 +276,28 @@
} else {
this.form.file_ids = []
}
console.log("this.form", this.form)
console.log("this.form", this.form)
if (this.form.product_details.length > 0) {
//
for (var p of this.form.product_details) {
if (this.base.isNull(p.value)) {
this.$message({
type: 'warning',
message: `${p.key} cannot be empty in the product details`
})
return
}
}
//
let filterArr = this.base.findDuplicateKeys(this.form.product_details, 'key')
if (filterArr.length > 0) {
this.$message({
type: 'warning',
message: `${filterArr.join("、")} cannot be repeated in the product details`
})
return
}
}
// return
save({
...this.form
@ -293,20 +314,20 @@
getDetail() {
show({
id: this.id,
show_relation:['productDetails']
id: this.id,
show_relation: ['productDetails']
}).then(res => {
this.form = this.base.requestToForm(res, this.form)
// this.form.content = res.content ? res.content : ''
this.form.category_id = res.category_id?res.category_id:[]
res.product_details.map(item=>{
item.type = this.productDetailsKeyList[item.key]['type']
if(this.productDetailsKeyList[item.key].type==='select'){
item.list = this.productDetailsKeyList[item.key]['list']
}
})
this.form.product_details = res.product_details
// this.form.content = res.content ? res.content : ''
this.form.category_id = res.category_id ? res.category_id : []
res.product_details.map(item => {
item.type = this.productDetailsKeyList[item.key]['type']
if (this.productDetailsKeyList[item.key].type === 'select') {
item.list = this.productDetailsKeyList[item.key]['list']
}
})
this.form.product_details = res.product_details
// this.showWang = true
// if (res.files && res.files.length > 0) {
@ -327,12 +348,21 @@
if (newVal) {
if (this.type === 'editor') {
this.getDetail()
} else {
for (var k in this.productDetailsKeyList) {
this.form.product_details.push({
key: this.productDetailsKeyList[k]["key"],
type: this.productDetailsKeyList[k]["type"],
value: '',
list: this.productDetailsKeyList[k]["list"]
})
}
}
this.showWang = true
} else {
this.id = ''
// this.filesList = []
this.showWang = false
this.showWang = false
this.form = {
name: "",
number: '',
@ -343,7 +373,7 @@
show_price: 1,
file_ids: '',
product_details: [],
content: '',
content: '',
}
this.$refs['dialog'].reset()
}

@ -24,13 +24,25 @@
</lx-header>
</div>
</div>
<xy-table :list="list" :total="total" @pageIndexChange="pageIndexChange"
@pageSizeChange="pageSizeChange" :table-item="table_item">
<xy-table :list="list" :total="total" @pageIndexChange="pageIndexChange" @pageSizeChange="pageSizeChange"
:table-item="table_item">
<template v-slot:category>
<el-table-column align='left' label="Product Phase" width="360" header-align="left">
<template slot-scope="scope">
<div v-if="scope.row.category.length>0">
<el-tag style="margin:5px" v-for="item in scope.row.category">{{item.name}}</el-tag>
</div>
<div v-else></div>
</template>
</el-table-column>
</template>
<template v-slot:btns>
<el-table-column align='left' fixed="right" label="Operate" width="180" header-align="center">
<template slot-scope="scope">
<el-button type="primary" size="small" @click="editProduct('editor',scope.row.id)">edit</el-button>
<el-popconfirm confirm-button-text="confirm" cancel-button-text="cancel" style="margin:0 10px" @confirm="deleteList(scope.row.id)" title="Are you sure to delete it?">
<el-popconfirm confirm-button-text="confirm" cancel-button-text="cancel" style="margin:0 10px"
@confirm="deleteList(scope.row.id)" title="Are you sure to delete it?">
<el-button type="danger" size="small" slot="reference">delete</el-button>
</el-popconfirm>
</template>
@ -43,12 +55,12 @@
<script>
import addProduct from './components/addProduct.vue';
import {
index,
destroy
} from "@/api/product/index.js"
import {
index as getCategory
import {
index,
destroy
} from "@/api/product/index.js"
import {
index as getCategory
} from "@/api/product/category.js"
export default {
components: {
@ -60,59 +72,67 @@
name: '',
page: 1,
page_size: 10,
},
categoryList:[],
},
categoryList: [],
total: 0,
list: [],
table_item: [{
type: 'index',
width: 50,
fixed: 'left'
}, {
prop: 'category',
label: 'Product Phase(产品项)',
align: 'left',
}, {
prop: 'name',
label: 'Product Name(产品名称)',
align: 'left',
width: 360
}, {
prop: 'number',
label: 'Product Number(产品编号)',
align: 'left',
width: 360
}, {
prop: 'list_price',
label: 'List Price(产品价格)',
align: 'left',
width: 240
},
{
prop: 'is_visible',
label: 'Visible(前台是否显示)',
align: 'center',
width: 120,
formatter:(cell,data,value)=>{
return value==1 ? 'Yes':'No'
width: 120,
formatter: (cell, data, value) => {
return value == 1 ? 'Yes' : 'No'
}
},
{
prop: 'is_sell',
label: 'Active(当前是否售卖)',
align: 'center',
width: 120,
formatter:(cell,data,value)=>{
return value==1 ? 'Yes':'No'
width: 120,
formatter: (cell, data, value) => {
return value == 1 ? 'Yes' : 'No'
}
},
{
prop: 'show_price',
label: 'Web Visibility(是否显示价格)',
align: 'center',
width: 120,
formatter:(cell,data,value)=>{
return value==1 ? 'Yes':'No'
width: 120,
formatter: (cell, data, value) => {
return value == 1 ? 'Yes' : 'No'
}
}
]
}
},
created() {
created() {
this.getCategoryList()
this.getList()
},
@ -120,8 +140,8 @@
editProduct(type, id) {
if (type == 'editor') {
this.$refs.addProduct.id = id
}
this.$refs.addProduct.categoryList = this.categoryList
}
this.$refs.addProduct.categoryList = this.categoryList
this.$refs.addProduct.type = type
this.$refs.addProduct.isShow = true
},
@ -139,26 +159,32 @@
this.select.name = ''
this.getList()
},
async getList() {
const res = await index({
...this.select,
filter:[{
key:'name',
op:'like',
value:this.select.name
}]
async getList() {
const res = await index({
...this.select,
filter: [{
key: 'name',
op: 'like',
value: this.select.name
}]
})
this.list = res.data
this.total = res.total
},
async getCategoryList(){
const res = await getCategory({page:1,page_size:999,type:2,sort_name:'sort',sort_type:'ASC'})
this.categoryList = res.data
},
async getCategoryList() {
const res = await getCategory({
page: 1,
page_size: 999,
type: 2,
sort_name: 'sort',
sort_type: 'ASC'
})
this.categoryList = res.data
},
deleteList(id) {
var that = this;
destroy({
id:id
destroy({
id: id
}).then(response => {
this.$Message.success('Success');
this.getList()

@ -31,7 +31,9 @@
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>Content
</div>
<div class="xy-table-item-content">
<wangEditor :isShow="isShow" v-show="showWang" :value="form.content" @change="changeEditor"></wangEditor>
<!-- <wangEditor :isShow="isShow" v-show="showWang" :value="form.content" @change="changeEditor"></wangEditor> -->
<my-tinymce v-if="showWang" @input="changeEditor" :value="form.content"></my-tinymce>
</div>
</div>
</template>

@ -45,7 +45,8 @@
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>Content
</div>
<div class="xy-table-item-content">
<wangEditor :isShow="isShow" v-show="showWang" :value="form.content" @change="changeEditor"></wangEditor>
<!-- <wangEditor :isShow="isShow" v-show="showWang" :value="form.content" @change="changeEditor"></wangEditor> -->
<my-tinymce v-if="showWang" @input="changeEditor" :value="form.content"></my-tinymce>
</div>
</div>
</template>

@ -58,7 +58,9 @@
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>Content
</div>
<div class="xy-table-item-content">
<wangEditor :isShow="isShow" v-show="showWang" :value="form.content" @change="changeEditor"></wangEditor>
<!-- <wangEditor :isShow="isShow" v-show="showWang" :value="form.content" @change="changeEditor"></wangEditor> -->
<my-tinymce v-if="showWang" @input="changeEditor" :value="form.content"></my-tinymce>
</div>
</div>
</template>

@ -25,7 +25,7 @@ module.exports = {
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: process.env.ENV === 'staging' ? '/admin_test' : '/admin',
outputDir: '/Users/mac/Documents/朗业/2024/s-美国赛分/saifen/public/admin_test',
outputDir: '/Users/mac/Documents/朗业/2024/s-美国赛分/saifen/public/admin',
assetsDir: 'static',
css: {
loaderOptions: { // 向 CSS 相关的 loader 传递选项

Loading…
Cancel
Save