c5_labsci/fapp/ciyon_ap/components/ciy-mdedit/ciy-mdedit.vue

423 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view style="width:100%;position: relative;">
<view style="min-height:10em;border:1px solid #dddddd;margin:0;background:#fafafa;">
<view v-for="(item,index) in mdlines" :key="index" @tap="rightmenu(index)" :class="item.vms">
<view v-if="item.cls == 'md-pic'">
<image :src="item.content" style="width:100%;display:block;" mode="widthFix"></image>
</view>
<view v-else :class="item.cls">{{item.content}}</view>
</view>
</view>
<view class="_edittip" style="top:-0.5em;">编辑区</view>
<input type="hidden" :name="name" :value="valuetxt" style="display:none;" />
<view style="position:relative;margin:0;border:1px solid #dddddd;">
<textarea :name="name + '_unup'" class="_textarea" v-model="etext" :fixed="true" auto-height maxlength="-1" />
<view style="display:flex;align-items: center;background:#ffffff;border-top:1px solid #dddddd;">
<view class="_icon _photo" @tap="upimg"></view>
<view style="position: absolute;bottom:0;left:4em;font-size:0.6em;color:#cccccc;">{{imgtip}}</view>
<view style="flex:1;text-align:right;padding:0 1em;">首行样式</view>
<ciy-picker name="linecls" v-model="elinecls" :range="styles" style="width:8em;"></ciy-picker>
<view class="_icon _uptxt" @tap="uptxt"></view>
</view>
<view class="_edittip" style="top:-1.5em;">录入区</view>
</view>
</view>
</template>
<script>
//下拉选择
//多行文本,每一行按照选择生成。
//按钮 上箭头,上传
//每段长按,删除、编辑、插入(在上)。
// 所见即所得的结果
// 添加文字段落
// 添加一张或多张图片
var app = getApp();
export default {
behaviors: ['uni://form-field-group']
, props: {
name: {
type: String
}
, value: {
type: String
, default: ''
}
, imgact: {
type: String
, default: 'cp|1280|60'
}
, uploadurl: {
type: String
, default: ''
}
, }
, data() {
return {
Gvalue: false
, valuetxt: '' //最终结果
, valuelines: [] //带格式的原始行
, mdlines: [] //显示的行
, eimgs: ''
, etext: ''
, imgtip: ''
, elinecls: 'md-content'
, styles: [{
id: 'md-content'
, pre: ''
, name: '正文'
}
, {
id: 'md-h1'
, pre: '#'
, name: '大标题'
}
, {
id: 'md-h1 _center'
, pre: '#c'
, name: '大标题居中'
}
, {
id: 'md-h1 _right'
, pre: '#r'
, name: '大标题靠右'
}
, {
id: 'md-h2'
, pre: '##'
, name: '二号标题 [n]'
}
, {
id: 'md-h3'
, pre: '###'
, name: '三号标题 [n.m]'
}
, {
id: 'md-h4'
, pre: '####'
, name: '四号标题 [n.m.k]'
}
, {
id: 'md-content _center'
, pre: '@c'
, name: '正文居中'
}
, {
id: 'md-content _right'
, pre: '@r'
, name: '正文靠右'
}
]
};
}
, watch: {
value(newD, oldD) {
if (this.Gvalue)
this.Gvalue = false;
else {
this.valuetxt = newD;
this.fillmdlines();
}
}
}
, mounted() {
this.valuetxt = this.value || '';
this.fillmdlines();
this.$emit('change', {
name: this.name
, from: 'create'
, value: this.valuetxt
});
}
, methods: {
fillmdlines() {
var markdown = this.valuetxt;
if (markdown.substr(0, 4) == '[MD]')
markdown = markdown.substr(4).trim();
var mds = markdown.split('\n');
var mdls = [];
for (var m in mds) {
if (mds[m].trim().length == 0) {
continue;
}
var mdl = {};
if (mds[m][0] == '#') { //标题1/2/3
if (mds[m].substr(0, 4) == '####') {
mdl.cls = 'md-h4';
mdl.content = 'n.m.k、' + mds[m].substr(4);
} else if (mds[m].substr(0, 3) == '###') {
mdl.cls = 'md-h3';
mdl.content = 'n.m、' + mds[m].substr(3);
} else if (mds[m].substr(0, 2) == '##') {
mdl.cls = 'md-h2';
mdl.content = 'n、' + mds[m].substr(2);
} else if (mds[m].substr(1, 1) == 'c') {
mdl.cls = 'md-h1 _center';
mdl.content = mds[m].substr(2);
} else if (mds[m].substr(1, 1) == 'r') {
mdl.cls = 'md-h1 _right';
mdl.content = mds[m].substr(2);
} else {
mdl.cls = 'md-h1';
mdl.content = mds[m].substr(1);
}
} else if (mds[m][0] == '@') { //c居中r靠右
if (mds[m][1] == 'c') {
mdl.cls = 'md-content _center';
mdl.content = mds[m].substr(2);
} else if (mds[m][1] == 'r') {
mdl.cls = 'md-content _right';
mdl.content = mds[m].substr(2);
} else {
mdl.cls = 'md-content';
mdl.content = mds[m].substr(1);
}
} else if (mds[m][0] == '!') { //图片
var mis = mds[m].split('|');
var url = mis[0];
url = url.substring(1);
var alt = '';
if (mis[1])
alt = ' alt="' + mis[1].replace('"', "") + '"';
if (url.substr(0, 4).toLowerCase() != 'http')
url = this.file_stor(url);//xx
mdl.cls = 'md-pic';
mdl.content = url;
} else if (mds[m][0] == '_') {} else {
mdl.cls = 'md-content';
mdl.content = mds[m];
}
if (mdl.cls) {
mdl.idx = m;
mdl.vms = '';
mdls.push(mdl);
}
}
this.mdlines = mdls;
this.valuetxt = '[MD]' + markdown;
}
, rightmenu(idx) {
for (var i in this.mdlines)
this.mdlines[i].vms = '';
this.mdlines[idx].vms = '_sel';
var menus = [];
menus.push({
name: '插入'
, url: 'ins'
});
if (this.mdlines[idx].cls != 'md-pic') {
menus.push({
name: '编辑'
, url: 'edit'
});
}
menus.push({
name: '删除'
, url: 'del'
});
uni.showActionSheet({
itemList: menus.map(item => item.name)
, success: res => {
var menu = menus[res.tapIndex];
if (menu.url == 'del') {
app.askmsg('确认删除?', () => {
var ls = this.valuetxt.split('\n');
ls.splice(this.mdlines[idx].idx, 1);
this.valuetxt = ls.join('\n');
this.fillmdlines();
this.$emit('change', {
name: this.name
, from: 'delete'
, value: this.valuetxt
});
});
} else if (menu.url == 'edit') {
this.etext = this.mdlines[idx].content;
this.elinecls = this.mdlines[idx].cls;
this.mdlines[idx].vms = '_edit';
} else if (menu.url == 'ins') {
this.mdlines[idx].vms = '_ins';
}
}
, complete: res => {
if (this.mdlines[idx].vms == '_sel')
this.mdlines[idx].vms = '';
}
});
}
, doedit(pre, txt) {
var lineidx = -1;
var op = '_append';
for (var i in this.mdlines) {
if (this.mdlines[i].vms) {
lineidx = this.mdlines[i].idx;
op = this.mdlines[i].vms;
break;
}
}
var ls = this.valuetxt.split('\n');
if (op == '_append')
ls.push(pre + txt);
else if (op == '_edit') {
ls.splice(lineidx, 1, pre + txt);
} else {
ls.splice(lineidx, 0, pre + txt);
}
this.valuetxt = ls.join('\n');
this.fillmdlines();
}
, uptxt() {
var txt = this.etext;
if (txt == '')
return app.toast('请填写内容');
var pre = '';
for (var i = 0; i < this.styles.length; i++) {
if (this.styles[i].id == this.elinecls)
pre = this.styles[i].pre;
}
this.etext = '';
this.doedit(pre, txt);
this.$emit('change', {
name: this.name
, from: 'uptxt'
, pre: pre
, content: txt
, value: this.valuetxt
});
}
, upimg: function(b) {
if (this.Grunning)
return app.toast('上传中...');
//if (app.boi && app.boi.inboi()) {
var thos = this;
uni.chooseImage({
count: 9
, sizeType: ['original', 'compressed']
, success: res => {
console.log('choose', res);
var upcount = res.tempFilePaths.length;
thos.Grunning = true;
thos.imgtip = '上传 0/' + upcount;
var upidx = 0;
for (var u in res.tempFilePaths) {
(function(idx, img) {
var updata = {};
updata.imgact = thos.imgact;
uni.uploadFile({
url: thos.uploadurl
, filePath: img
, name: 'file'
, formData: updata
, header: {
'ciyauth': app.getstorage("_auth")
, 'ciyorg': app.getstorage("_org")
}
, success: res => {
var jsonup = app.json_parse(res.data);
if (jsonup === null)
jsonup = {
code: 0
, errmsg: 'JSON Parse ERROR:' + res.data.substr(0, 30)
}
upidx++;
if (jsonup.code != 1) {
thos.Grunning = false;
thos.imgtip = '';
if (jsonup.code == 2) {
app.askmsg('您尚未登录,请登录后上传\n立即前往登录', () => {
uni.navigateTo({
url: '/main/login'
});
});
} else
thos.alert('上传失败:' + jsonup.errmsg);
return;
}
thos.doedit('!', jsonup.url);
thos.$emit('change', {
name: thos.name
, from: 'upimg'
, url: jsonup.url
, value: thos.valuetxt
});
thos.imgtip = '上传 ' + upidx + '/' + upcount;
if (upidx == upcount) {
thos.Gvalue = true;
thos.imgtip = '';
thos.Grunning = false;
}
}
});
})(u, res.tempFilePaths[u]);
}
}
});
}
}
}
</script>
<style scoped>
._edittip {
position: absolute;
top: 0;
right: 0.5em;
background: #fffad7;
border: 1px solid #dddddd;
padding: 0.2em 0.5em;
font-size: 0.6em;
border-radius: 0.5em;
line-height: 1.3em;
}
._center {
text-align: center;
}
._right {
text-align: right;
}
._ins {
border-top: 3px solid #cc0000;
}
._sel {
border: 1px solid #cc0000;
border-radius: 0.3em;
}
._edit {
border: 2px solid #009000;
}
._textarea {
display: block;
padding: 0.5em;
min-height: 5em;
background: #ffffff;
line-height:1.2em;
width: 100%;
box-sizing: border-box;
}
._photo {
background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQyOC41NzYgMzc4LjM2OGE1MC4xNzYgNTAuMTc2IDAgMSAwLTEwMC4zNTIgMCA1MC4xNzYgNTAuMTc2IDAgMCAwIDEwMC4zNTIgMG0wIDB6IG0xNjYuOTQ0IDI1Ni40NDhoNDEuNTA0di00MS41MDRjMC0zMC41NiAxOC4zMzYtNTYuOCA0NC41MTItNjguNzM2bC02Ljk0NC0yMy44MDh2LTEuNjY0aDAuMDY0bC00NS40MDgtMTM3LjE4NC0xNTguNDk2IDIwNC41MTItNDIuNDk2LTcxLjk2OC0xNjguNTc2IDE3MC4xMTJoMjc2LjA5NmE3NS4zNiA3NS4zNiAwIDAgMSA1OS43NDQtMjkuNzZtMjY3LjcxMi0zNjEuNjY0YTExMi43MDQgMTEyLjcwNCAwIDAgMC0xMTIuMzg0LTExMi4zODRIMjczLjE1MmExMTIuNzA0IDExMi43MDQgMCAwIDAtMTEyLjM4NCAxMTIuMzg0djQ3Ny42NjRhMTEyLjcwNCAxMTIuNzA0IDAgMCAwIDExMi4zODQgMTEyLjM4NGgzMzcuMTg0di0wLjAzMmwwLjEyOCAwLjAzMmEyMS4wODggMjEuMDg4IDAgMSAwIDAtNDIuMTc2bC0wLjEyOCAwLjAzMnYtMC4wMzJIMjczLjE1MmE3MC4zMDQgNzAuMzA0IDAgMCAxLTcwLjI0LTcwLjI0VjI3My4xNTJjMC0zOC43NTIgMzEuNDg4LTcwLjI0IDcwLjI0LTcwLjI0aDQ3Ny42NjRjMzguNzUyIDAgNzAuMjQgMzEuNDg4IDcwLjI0IDcwLjI0djMzNS4xMzZjMCAwLjI1Ni0wLjEyOCAwLjQ0OC0wLjEyOCAwLjY3MmEyMS4wODggMjEuMDg4IDAgMSAwIDQyLjE3NiAwbC0wLjA2NC0wLjI1NmgwLjE5MlYyNzMuMTUybS0yMS44ODggNDE2LjIyNGgtMTA3LjQyNHYtMTA3LjQyNGEyMS4wODggMjEuMDg4IDAgMSAwLTQyLjE3NiAwdjEwNy40MjRINTg0LjMyYTIxLjA4OCAyMS4wODggMCAxIDAgMCA0Mi4xNzZoMTA3LjQyNHYxMDcuNDI0YTIxLjA4OCAyMS4wODggMCAxIDAgNDIuMTc2IDBWNzMxLjUyaDEwNy40MjRhMjEuMDg4IDIxLjA4OCAwIDEgMCAwLTQyLjE0NCIgZmlsbD0iIzQ4OENDQiI+PC9wYXRoPjwvc3ZnPg==");
}
._uptxt {
background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUxMiAxMDIuNGM1NC42MTMzMzMgMCAxMDYuOTM5NzMzIDExLjM2NjQgMTU3LjAxMzMzMyAzMS44NDY0IDQ3Ljc4NjY2NyAyMC40OCA5My4yODY0IDUwLjA3MzYgMTMxLjk5MzYgODguNzQ2NjY3IDM4LjY3MzA2NyAzNi40MjAyNjcgNjguMjY2NjY3IDgxLjkyIDg4Ljc0NjY2NyAxMzEuOTkzNiAyMC40OCA1MC4wNzM2IDMxLjg0NjQgMTAyLjQgMzEuODQ2NCAxNTcuMDEzMzMzIDAgNTQuNjEzMzMzLTExLjM2NjQgMTA2LjkzOTczMy0zMS44NDY0IDE1Ny4wMTMzMzMtMjAuNDggNDcuNzg2NjY3LTUwLjA3MzYgOTMuMjg2NC04OC43NDY2NjcgMTMxLjk5MzYtMzYuNDIwMjY3IDM4LjY3MzA2Ny04MS45MiA2OC4yNjY2NjctMTMxLjk5MzYgODguNzQ2NjY3LTUwLjA3MzYgMjAuNDgtMTAyLjQgMzEuODQ2NC0xNTcuMDEzMzMzIDMxLjg0NjQtNTQuNjEzMzMzIDAtMTA2LjkzOTczMy0xMS4zNjY0LTE1Ny4wMTMzMzMtMzEuODQ2NC00Ny43ODY2NjctMjAuNDgtOTMuMjg2NC01MC4wNzM2LTEzMS45OTM2LTg4Ljc0NjY2Ny0zOC42NzMwNjctMzYuNDIwMjY3LTY4LjI2NjY2Ny04MS45Mi04OC43NDY2NjctMTMxLjk5MzYtMjAuNDgtNTAuMDczNi0zMS44NDY0LTEwMi40LTMxLjg0NjQtMTU3LjAxMzMzMyAwLTU0LjYxMzMzMyAxMS4zNjY0LTEwNi45Mzk3MzMgMzEuODQ2NC0xNTcuMDEzMzMzIDIwLjQ4LTQ3Ljc4NjY2NyA1MC4wNzM2LTkzLjI4NjQgODguNzQ2NjY3LTEzMS45OTM2IDM4LjcwNzItMzguNjczMDY3IDgxLjkyLTY4LjI2NjY2NyAxMzEuOTkzNi04OC43NDY2NjcgNTAuMDczNi0yMC40OCAxMDIuNC0zMS44NDY0IDE1Ny4wMTMzMzMtMzEuODQ2NHpNMjk1LjA4MjY2NyA1OTYuNjE2NTMzbC0yMS43MDg4IDk0LjkyNDggMzUuMjI1NiAzNS4yMjU2IDk0LjkyNDgtMjEuNzA4OC0xMDguNDQxNi0xMDguNDQxNnogbTIwOS4zNzM4NjYtMjg3LjA2MTMzM2wtMTc4Ljg1ODY2NiAxNzguODkyOGMtNC43NDQ1MzMgMzAuMTczODY3IDEuODQzMiA1MC4zMTI1MzMgMzIuOTcyOCA0Ny43ODY2NjdsMTIzLjkwNC0xMjAuMDgxMDY3IDEwLjk5MDkzMyAxMC45OTA5MzMtMTIwLjcyOTYgMTE2Ljk0MDhjNy41MDkzMzMgNDkuMDQ5NiAzOS41OTQ2NjcgNjguMjY2NjY3IDgyLjY3MDkzMyA3NC4yMDU4NjctNS42NjYxMzMgMzQuMjY5ODY3IDMuNDQ3NDY3IDU1LjAyMjkzMyA0NS45MDkzMzQgNDUuOTA5MzMzbDE3OC44NTg2NjYtMTc4Ljg5MjgtMTc1LjcxODQtMTc1Ljc1MjUzM3ogbTU1LjYzNzMzNC01NS4yOTZMNTIzLjk0NjY2NyAyOTAuMzcyMjY3bDE3NS43NTI1MzMgMTc1LjcxODQgMzYuMTQ3Mi0zNi4xNDcyYzE5Ljc5NzMzMy0xOS43OTczMzMgMTkuNzk3MzMzLTUyLjQ5NzA2NyAwLTcyLjI5NDRsLTEwMy40MjQtMTAzLjQyNGE1MS40Mzg5MzMgNTEuNDM4OTMzIDAgMCAwLTcyLjMyODUzMyAweiIgZmlsbD0iIzg1QzJGRiI+PC9wYXRoPjwvc3ZnPg==");
}
._icon {
width: 3em;
height: 3em;
background-size: cover;
}
</style>