Преглед на файлове

Merge branch 'feature-admin' into develop

master
JinxChen преди 2 години
родител
ревизия
8687e4bab0
променени са 20 файла, в които са добавени 942 реда и са изтрити 94 реда
  1. +0
    -36
      gps_card_admin_run.sh
  2. +10
    -10
      setup_development.sh
  3. +7
    -7
      setup_production.sh
  4. +9
    -9
      setup_test.sh
  5. +2
    -2
      src/App.vue
  6. +2
    -2
      src/components/TTable/TTable.vue
  7. +111
    -0
      src/components/Tinymce/components/EditorImage.vue
  8. +59
    -0
      src/components/Tinymce/dynamicLoadScript.js
  9. +247
    -0
      src/components/Tinymce/index.vue
  10. +7
    -0
      src/components/Tinymce/plugins.js
  11. +6
    -0
      src/components/Tinymce/toolbar.js
  12. +4
    -4
      src/router/index.js
  13. +4
    -4
      src/store/localStore.js
  14. +1
    -0
      src/styles/index.scss
  15. +5
    -5
      src/utils/clear-local-storage.js
  16. +26
    -0
      src/utils/index.js
  17. +139
    -6
      src/views/message-manage/main/add-articles/index.vue
  18. +66
    -0
      src/views/message-manage/main/add-mass/index.scss
  19. +200
    -9
      src/views/message-manage/main/add-mass/index.vue
  20. +37
    -0
      telpo_user_admin_run.sh

+ 0
- 36
gps_card_admin_run.sh Целия файл

@@ -1,36 +0,0 @@
#!/bin/bash
###
# @Date: 2021-11-15 09:37:49
# @LastEditors: JinxuChen
# @LastEditTime: 2021-12-02 15:19:14
# @FilePath: \GpsCardAdmin\gps_card_admin_run.sh
# @description: 功能
###
environment=$1
version=$2
echo "环境变量为${environment},版本为$version!"
if [[ ${environment} = 'production' ]]; then
echo "开始远程构建容器"
docker stop gps_card_admin_web || true;
docker rm gps_card_admin_web || true;
docker rmi -f $(docker images | grep registry.cn-shanghai.aliyuncs.com/gps_card/gps_card_admin_web | awk '{print $3}')
#docker login --username=telpo_linwl@1111649216405698 --password=telpo#1234 registry.cn-shanghai.aliyuncs.com;
docker login --username=rzl_wangjx@1111649216405698 --password=telpo.123 registry.cn-shanghai.aliyuncs.com
docker pull registry.cn-shanghai.aliyuncs.com/gps_card/gps_card_admin_web:$version
docker run -p 8803:80 -d --restart=always --name gps_card_admin_web registry.cn-shanghai.aliyuncs.com/gps_card/gps_card_admin_web:$version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
docker ps -a

elif [[ ${environment} == 'test' ]]; then
echo "开始在测试环境远程构建容器"
docker stop gps_card_admin_web || true
docker rm gps_card_admin_web || true
docker rmi -f $(docker images | grep 139.224.254.18:5000/gps_card_admin_web | awk '{print $3}')
docker pull 139.224.254.18:5000/gps_card_admin_web:$version
docker run -p 8803:80 -d --restart=always --name gps_card_admin_web 139.224.254.18:5000/gps_card_admin_web:$version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
docker ps -a

fi

+ 10
- 10
setup_development.sh Целия файл

@@ -1,10 +1,10 @@
###
# @Author: JinxuChen
# @Date: 2021-11-15
# @LastEditTime: 2021-12-02 15:19:22
# @LastEditors: JinxuChen
# @LastEditTime: 2022-09-08 14:19:26
# @LastEditors: JinxChen
# @Description: In User Settings Edit
# @FilePath: \GpsCardAdmin\setup_development.sh
# @FilePath: \TelpoUserManageAdmin\setup_development.sh
###
#!/bin/bash
npm -v
@@ -13,18 +13,18 @@ npm config list
npm install
npm run build-test
image_version=`date +%Y%m%d%H%M`;
docker stop gps_card_admin_web || true;
docker stop telpo_user_admin || true;
# 删除gps_parent_web容器
docker rm gps_card_admin_web || true;
docker rm telpo_user_admin || true;
# 删除镜像
docker rmi -f $(docker images | grep telpo/gps_card_admin_web | awk '{print $3}')
# 构建telpo/gps_card_admin_web:$image_version镜像
docker build . -t telpo/gps_card_admin_web:$image_version;
docker rmi -f $(docker images | grep telpo/telpo_user_admin | awk '{print $3}')
# 构建telpo/telpo_user_admin:$image_version镜像
docker build . -t telpo/telpo_user_admin:$image_version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
# 查看镜像列表
docker images;
# 启动容器
docker run -p 8803:80 -d --restart=always --name gps_card_admin_web telpo/gps_card_admin_web:$image_version;
docker run -p 8073:80 -d --restart=always --name telpo_user_admin telpo/telpo_user_admin:$image_version;
# 查看日志
docker logs gps_card_admin_web;
docker logs telpo_user_admin;

+ 7
- 7
setup_production.sh Целия файл

@@ -1,10 +1,10 @@
###
# @Author: JinxuChen
# @Date: 2021-11-15
# @LastEditTime: 2021-12-02 15:17:27
# @LastEditors: JinxuChen
# @LastEditTime: 2022-08-12 14:21:49
# @LastEditors: JinxChen
# @Description: In User Settings Edit
# @FilePath: \GpsCardAdmin\setup_production.sh
# @FilePath: \TelpoUserManageAdmin\setup_production.sh
###
#!/bin/bash
npm -v
@@ -12,15 +12,15 @@ npm install
npm run build
image_version=$version;
# 删除镜像
docker rmi -f $(docker images | grep registry.cn-shanghai.aliyuncs.com/gps_card/gps_card_admin_web | awk '{print $3}')
docker rmi -f $(docker images | grep registry.cn-shanghai.aliyuncs.com/gps_card/telpo_user_admin | awk '{print $3}')

docker build . -t telpo/gps_card_admin_web:$image_version;
docker build . -t telpo/telpo_user_admin:$image_version;
#TODO:推送镜像到阿里仓库
echo '=================开始推送镜像======================='
#docker login --username=telpo_linwl@1111649216405698 --password=telpo#1234 registry.cn-shanghai.aliyuncs.com;
docker login --username=rzl_wangjx@1111649216405698 --password=telpo.123 registry.cn-shanghai.aliyuncs.com
docker tag telpo/gps_card_admin_web:$image_version registry.cn-shanghai.aliyuncs.com/gps_card/gps_card_admin_web:$image_version
docker push registry.cn-shanghai.aliyuncs.com/gps_card/gps_card_admin_web:$image_version
docker tag telpo/telpo_user_admin:$image_version registry.cn-shanghai.aliyuncs.com/gps_card/telpo_user_admin:$image_version
docker push registry.cn-shanghai.aliyuncs.com/gps_card/telpo_user_admin:$image_version
echo '=================推送镜像完成======================='
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')


+ 9
- 9
setup_test.sh Целия файл

@@ -1,10 +1,10 @@
###
# @Author: JinxuChen
# @Date: 2021-11-15
# @LastEditTime: 2021-12-02 15:17:38
# @LastEditors: JinxuChen
# @LastEditTime: 2022-08-12 14:21:45
# @LastEditors: JinxChen
# @Description: In User Settings Edit
# @FilePath: \GpsCardAdmin\setup_test.sh
# @FilePath: \TelpoUserManageAdmin\setup_test.sh
###
#!/usr/bin/env bash
npm -v
@@ -16,16 +16,16 @@ npm run build-test
image_version=$version
# 删除镜像
docker rmi -f $(
docker images | grep 139.224.254.18:5000/gps_card_admin_web | awk '{print $3}'
docker images | grep 139.224.254.18:5000/telpo_user_admin | awk '{print $3}'
)
# 构建gps_card_admin:$image_version镜像
docker build . -t telpo/gps_card_admin_web:$image_version;
# 构建telpo_user_admin:$image_version镜像
docker build . -t telpo/telpo_user_admin:$image_version;
#TODO:推送镜像到私有仓库
echo '=================开始推送镜像======================='
docker tag telpo/gps_card_admin_web:$image_version 139.224.254.18:5000/gps_card_admin_web:$image_version
docker push 139.224.254.18:5000/gps_card_admin_web:$image_version
docker tag telpo/telpo_user_admin:$image_version 139.224.254.18:5000/telpo_user_admin:$image_version
docker push 139.224.254.18:5000/telpo_user_admin:$image_version
echo '=================推送镜像完成======================='
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
# 查看镜像列表
docker images
docker images

+ 2
- 2
src/App.vue Целия файл

@@ -1,8 +1,8 @@
<!--
* @Date: 2021-11-29 11:20:34
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-06 10:27:35
* @FilePath: \telpoAdminTemplate\src\App.vue
* @LastEditTime: 2022-08-18 15:21:04
* @FilePath: \TelpoUserManageAdmin\src\App.vue
* @description:
-->
<template>


+ 2
- 2
src/components/TTable/TTable.vue Целия файл

@@ -1,7 +1,7 @@
<!--
* @Date: 2021-11-30 17:19:51
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-08 16:11:03
* @LastEditTime: 2022-08-16 16:13:27
* @FilePath: \TelpoUserManageAdmin\src\components\TTable\TTable.vue
* @description: 封装通用的table组件
-->
@@ -49,7 +49,7 @@
//import Pagination from "@/components/Pagination";
import waves from "@/directive/waves"; // waves directive
export default {
name: "",
name: "TTable",
//components: { Pagination },
directives: { waves },
props: {


+ 111
- 0
src/components/Tinymce/components/EditorImage.vue Целия файл

@@ -0,0 +1,111 @@
<template>
<div class="upload-container">
<!-- <el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true">
upload
</el-button> -->
<el-dialog :visible.sync="dialogVisible">
<el-upload
:multiple="true"
:file-list="fileList"
:show-file-list="true"
:on-remove="handleRemove"
:on-success="handleSuccess"
:before-upload="beforeUpload"
class="editor-slide-upload"
action="https://httpbin.org/post"
list-type="picture-card"
>
<el-button size="small" type="primary">
Click upload
</el-button>
</el-upload>
<el-button @click="dialogVisible = false">
Cancel
</el-button>
<el-button type="primary" @click="handleSubmit">
Confirm
</el-button>
</el-dialog>
</div>
</template>

<script>
// import { getToken } from 'api/qiniu'

export default {
name: 'EditorSlideUpload',
props: {
color: {
type: String,
default: '#1890ff'
}
},
data() {
return {
dialogVisible: false,
listObj: {},
fileList: []
}
},
methods: {
checkAllSuccess() {
return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess)
},
handleSubmit() {
const arr = Object.keys(this.listObj).map(v => this.listObj[v])
if (!this.checkAllSuccess()) {
this.$message('Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!')
return
}
this.$emit('successCBK', arr)
this.listObj = {}
this.fileList = []
this.dialogVisible = false
},
handleSuccess(response, file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
this.listObj[objKeyArr[i]].url = response.files.file
this.listObj[objKeyArr[i]].hasSuccess = true
return
}
}
},
handleRemove(file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
delete this.listObj[objKeyArr[i]]
return
}
}
},
beforeUpload(file) {
const _self = this
const _URL = window.URL || window.webkitURL
const fileName = file.uid
this.listObj[fileName] = {}
return new Promise((resolve, reject) => {
const img = new Image()
img.src = _URL.createObjectURL(file)
img.onload = function() {
_self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height }
}
resolve(true)
})
}
}
}
</script>

<style lang="scss" scoped>
.editor-slide-upload {
margin-bottom: 20px;
::v-deep .el-upload--picture-card {
width: 100%;
}
}
</style>

+ 59
- 0
src/components/Tinymce/dynamicLoadScript.js Целия файл

@@ -0,0 +1,59 @@
let callbacks = []

function loadedTinymce() {
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144
// check is successfully downloaded script
return window.tinymce
}

const dynamicLoadScript = (src, callback) => {
const existingScript = document.getElementById(src)
const cb = callback || function() {}

if (!existingScript) {
const script = document.createElement('script')
script.src = src // src url for the third-party library being loaded.
script.id = src
document.body.appendChild(script)
callbacks.push(cb)
const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd
onEnd(script)
}

if (existingScript && cb) {
if (loadedTinymce()) {
cb(null, existingScript)
} else {
callbacks.push(cb)
}
}

function stdOnEnd(script) {
script.onload = function() {
// this.onload = null here is necessary
// because even IE9 works not like others
this.onerror = this.onload = null
for (const cb of callbacks) {
cb(null, script)
}
callbacks = null
}
script.onerror = function() {
this.onerror = this.onload = null
cb(new Error('Failed to load ' + src), script)
}
}

function ieOnEnd(script) {
script.onreadystatechange = function() {
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
this.onreadystatechange = null
for (const cb of callbacks) {
cb(null, script) // there is no way to catch loading errors in IE8
}
callbacks = null
}
}
}

export default dynamicLoadScript

+ 247
- 0
src/components/Tinymce/index.vue Целия файл

@@ -0,0 +1,247 @@
<template>
<div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}">
<textarea :id="tinymceId" class="tinymce-textarea" />
<div class="editor-custom-btn-container">
<editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" />
</div>
</div>
</template>

<script>
/**
* docs:
* https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce
*/
import editorImage from './components/EditorImage'
import plugins from './plugins'
import toolbar from './toolbar'
import load from './dynamicLoadScript'

// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'

export default {
name: 'Tinymce',
components: { editorImage },
props: {
id: {
type: String,
default: function() {
return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
}
},
value: {
type: String,
default: ''
},
toolbar: {
type: Array,
required: false,
default() {
return []
}
},
menubar: {
type: String,
default: 'file edit insert view format table'
},
height: {
type: [Number, String],
required: false,
default: 360
},
width: {
type: [Number, String],
required: false,
default: 'auto'
}
},
data() {
return {
hasChange: false,
hasInit: false,
tinymceId: this.id,
fullscreen: false,
languageTypeList: {
'en': 'en',
'zh': 'zh_CN',
'es': 'es_MX',
'ja': 'ja'
}
}
},
computed: {
containerWidth() {
const width = this.width
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
return `${width}px`
}
return width
}
},
watch: {
value(val) {
if (!this.hasChange && this.hasInit) {
this.$nextTick(() =>
window.tinymce.get(this.tinymceId).setContent(val || ''))
}
}
},
mounted() {
this.init()
},
activated() {
if (window.tinymce) {
this.initTinymce()
}
},
deactivated() {
this.destroyTinymce()
},
destroyed() {
this.destroyTinymce()
},
methods: {
init() {
// dynamic load tinymce from cdn
load(tinymceCDN, (err) => {
if (err) {
this.$message.error(err.message)
return
}
this.initTinymce()
})
},
initTinymce() {
const _this = this
window.tinymce.init({
selector: `#${this.tinymceId}`,
language: this.languageTypeList['zh'],
height: this.height,
body_class: 'panel-body ',
object_resizing: false,
toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
menubar: this.menubar,
plugins: plugins,
end_container_on_empty_block: true,
powerpaste_word_import: 'clean',
code_dialog_height: 250,
code_dialog_width: 1000,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
default_link_target: '_blank',
link_title: false,
nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value)
}
_this.hasInit = true
editor.on('NodeChange Change KeyUp SetContent', () => {
this.hasChange = true
this.$emit('input', editor.getContent())
})
},
setup(editor) {
editor.on('FullscreenStateChanged', (e) => {
_this.fullscreen = e.state
})
},
// it will try to keep these URLs intact
// https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
// https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
convert_urls: false
// 整合七牛上传
// images_dataimg_filter(img) {
// setTimeout(() => {
// const $image = $(img);
// $image.removeAttr('width');
// $image.removeAttr('height');
// if ($image[0].height && $image[0].width) {
// $image.attr('data-wscntype', 'image');
// $image.attr('data-wscnh', $image[0].height);
// $image.attr('data-wscnw', $image[0].width);
// $image.addClass('wscnph');
// }
// }, 0);
// return img
// },
// images_upload_handler(blobInfo, success, failure, progress) {
// progress(0);
// const token = _this.$store.getters.token;
// getToken(token).then(response => {
// const url = response.data.qiniu_url;
// const formData = new FormData();
// formData.append('token', response.data.qiniu_token);
// formData.append('key', response.data.qiniu_key);
// formData.append('file', blobInfo.blob(), url);
// upload(formData).then(() => {
// success(url);
// progress(100);
// })
// }).catch(err => {
// failure('出现未知问题,刷新页面,或者联系程序员')
// console.log(err);
// });
// },
})
},
destroyTinymce() {
const tinymce = window.tinymce.get(this.tinymceId)
if (this.fullscreen) {
tinymce.execCommand('mceFullScreen')
}

if (tinymce) {
tinymce.destroy()
}
},
setContent(value) {
window.tinymce.get(this.tinymceId).setContent(value)
},
getContent() {
window.tinymce.get(this.tinymceId).getContent()
},
imageSuccessCBK(arr) {
arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`))
}
}
}
</script>

<style lang="scss" scoped>
.tinymce-container {
position: relative;
line-height: normal;
}

.tinymce-container {
::v-deep {
.mce-fullscreen {
z-index: 10000;
}
}
}

.tinymce-textarea {
visibility: hidden;
z-index: -1;
}

.editor-custom-btn-container {
position: absolute;
right: 4px;
top: 4px;
/*z-index: 2005;*/
}

.fullscreen .editor-custom-btn-container {
z-index: 10000;
position: fixed;
}

.editor-upload-btn {
display: inline-block;
}
</style>

+ 7
- 0
src/components/Tinymce/plugins.js Целия файл

@@ -0,0 +1,7 @@
// Any plugins you want to use has to be imported
// Detail plugins list see https://www.tinymce.com/docs/plugins/
// Custom builds see https://www.tinymce.com/download/custom-builds/

const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']

export default plugins

+ 6
- 0
src/components/Tinymce/toolbar.js Целия файл

@@ -0,0 +1,6 @@
// Here is a list of the toolbar
// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols

const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']

export default toolbar

+ 4
- 4
src/router/index.js Целия файл

@@ -70,7 +70,7 @@ export const constantRoutes = [{
{
path: '/collection-order-system',
component: Layout,
redirect: 'collection-order-system/collection-order-list',
redirect: '/collection-order-list',
name: 'collection-order-system',
meta: {
title: '收单系统',
@@ -93,7 +93,7 @@ export const constantRoutes = [{
{
path: 'crowd-funding-otrder-system',
component: Layout,
redirect: 'crowd-funding-otrder-system/package-manage',
redirect: '/package-manage',
name: 'crowd-funding-otrder-system',
meta: {
title: '众筹拼单系统',
@@ -165,7 +165,7 @@ export const constantRoutes = [{
{
path: 'message-manage',
component: Layout,
redirect: 'message-manage/wechat-fans',
redirect: '/wechat-fans',
name: 'message-manage',
meta: {
title: '消息管理',
@@ -228,7 +228,7 @@ export const constantRoutes = [{
{
path: '/system-manage',
component: Layout,
redirect: 'system-manage/system-setting',
redirect: '/system-setting',
name: 'system-manage',
meta: {
title: '系统管理',


+ 4
- 4
src/store/localStore.js Целия файл

@@ -1,15 +1,15 @@
/*
* @Date: 2021-12-08 16:13:09
* @LastEditors: JinxuChen
* @LastEditTime: 2021-12-10 10:19:33
* @FilePath: \GpsCardAdmin\src\store\localStore.js
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-12 14:21:23
* @FilePath: \TelpoUserManageAdmin\src\store\localStore.js
* @description: store 使用local Storage
*/
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);
const prefix = 'gps_card_admin_';
const prefix = 'telpo_user_admin_';
export default new Vuex.Store({
state: {
userName:'',


+ 1
- 0
src/styles/index.scss Целия файл

@@ -63,6 +63,7 @@ div:focus {
}
// main-container global css
.home-container {
height: 600px;
position: relative;
margin: 60px 20px 0 20px;
padding: 10px 0;


+ 5
- 5
src/utils/clear-local-storage.js Целия файл

@@ -1,11 +1,11 @@
/*
* @Date: 2021-12-08 16:23:20
* @LastEditors: JinxuChen
* @LastEditTime: 2021-12-08 16:23:45
* @FilePath: \GpsCardAdmin\src\utils\clear-local-storage.js
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-12 14:21:39
* @FilePath: \TelpoUserManageAdmin\src\utils\clear-local-storage.js
* @description: 增加 清除local Storage的方法
*/
const prefix = 'gps_card_admin_';
const prefix = 'telpo_user_admin_';
const LocalStorageService = {
clearAll(store) {
for (let k in store.getters) {
@@ -17,4 +17,4 @@ const LocalStorageService = {
window.localStorage[ prefix + type ] = '';
},
};
export default LocalStorageService;
export default LocalStorageService;

+ 26
- 0
src/utils/index.js Целия файл

@@ -94,6 +94,32 @@ export function formatTime(time, option) {
}
}


/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function initTime(time, option) {
console.log("option:;", option);
const year = time.getFullYear();
const month = time.getMonth() + 1;
const day = time.getDate();
const hours = time.getHours();
const minutes = time.getMinutes();
if(option === 'ymdhm') {
return year + '年' + month + '月' + day + '日' + hours + '时' + minutes +'分';
} else if (option === 'ymdh') {
return year + '年' + month + '月' + day + '日' + hours + '时';
} else if (option === 'ymd') {
return year + '年' + month + '月' + day + '日';
} else if (option === 'ym') {
return year + '年' + month + '月';
}
// year + '年' + month + '月' + day + '日' + hours + '时';

}

/**
* @param {string} url
* @returns {Object}


+ 139
- 6
src/views/message-manage/main/add-articles/index.vue Целия файл

@@ -1,38 +1,171 @@
<!--
* @Date: 2022-08-08 10:09:45
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-08 16:08:00
* @LastEditTime: 2022-08-09 16:44:50
* @FilePath: \TelpoUserManageAdmin\src\views\message-manage\main\add-articles\index.vue
* @description: 添加文章
-->

<template>
<div class="app-container">
<div class="home-container">
<!-- 顶部内容 -->
<div class="top-container">
<TopMenu :buttonList="buttonList"/>
</div>
<!-- 表单 -->
<el-form ref="form" :model="form" label-width="80px" size="small">
<el-form-item label="文章标题:">
<el-input v-model="form.articleTitle" ></el-input>
</el-form-item>
<el-form-item label="文章类型:">
<el-select v-model="form.articleType" placeholder="请选择文章类型">
<el-option :label="item.label" :value="item.label" v-for="(item, index) in articleTypes" :key="index"/>
</el-select>
</el-form-item>
<el-form-item label="分享标题:">
<el-input v-model="form.shareTitle"></el-input>
</el-form-item>
<el-form-item label="分享简介:">
<el-input v-model="form.shareAbout"></el-input>
</el-form-item>
<el-form-item label="分享图片:">
<el-button v-show="fileList.length > 0" disabled type="warning">请删除图片后再上传</el-button>
<el-upload
class="upload-img"
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="onPreview"
:on-remove="onRemove"
:on-progress="onProgress"
:before-remove="beforeRemove"
:before-upload="beforeUpload"
:on-error="onError"
:on-success="onSuccess"
:on-change="onUploadChange"
:auto-upload="false"
:limit="1"
list-type="picture"
:file-list="fileList">
<el-button size="small" type="primary" v-show="fileList.length <= 0">点击上传</el-button>
<div slot="tip" class="el-upload__tip">
<p>最多上传一张,尺寸750X300</p>
</div>
</el-upload>
</el-form-item>


<!-- 富文本编辑器 -->
<el-form-item label="文章内容:">
<tinymce v-model="form.articleContent" :height="5" menubar="false" />
<!-- <p>文章内容:{{form.articleContent}}</p> -->
</el-form-item>

<!-- 保存 -->
<el-form-item class="footer-btn">
<el-button type="primary" @click="onSave">保存</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>

<script>
import TopMenu from "@/components/TopMenu/index";
import Tinymce from '@/components/Tinymce'
export default {
name: 'wechat-fans',
components: { TopMenu },
components: { TopMenu, Tinymce },
data(){
return {
buttonList: [], // 头部按钮,例子: {name: '添加', type: 'primary', icon: 'el-icon-circle-plus', click: () => { this.AddDialog();}}
// 表单数据
form: {
articleTitle: '', //文章标题
articleType: '普通文章', //文章类型
shareTitle: '', //分享标题
shareAbout: '', //分享简介
shareImage: '', //分享图片
articleContent: '', //文章内容

},
// 文章类型
articleTypes: [
{ label: '普通文章', value: '普通文章' },
{ label: '特别文章', value: '特别文章' },
{ label: '其它文章', value: '其它文章' },
],
// 图片列表
fileList: [],

}
},
mounted() {},
created() {},
created() {
this.clearFiles();
console.log("本地的上传图片列表", this.fileList);
},
methods: {

// 清空本地上传的图片列表
clearFiles() {},
// 删除上传的图片
onRemove() {
this.fileList = []
},
// 点击文件列表中已上传的文件时的钩子
onPreview(file) {
console.log("点击了上传图片", file);
},
// 删除上传图片
beforeRemove(file) {
return this.$confirm(`确定删除 ${ file.name }?`);
},
// 上传图片前
beforeUpload(file) {
console.log("上传图片前::", file);
},
// 上传失败
onError(err) {
return this.$confirm(`上传失败,请联系管理人`);
},
// 上传成功
onSuccess(file) {
console.log("上传成功", file);
},
// 文件上传时
onProgress(fileList) {
console.log("fileList", fileList);
},
// 上传文件发生变化时
onUploadChange(file) {
console.log('传文件发生变化时', file);
if(this.fileList.length > 0) {
this.fileList.length = 0
} else {
this.fileList.push(file);
}
},
// 保存
onSave() {
console.log("保存的内容::", this.form);
}
}
}
</script>

<style scoped lang="scss">

.home-container {
position: relative;
height: 600px;
overflow-y: scroll;
overflow-x: hidden;
padding: 0 20px;
p {
padding: 5px;
}
}
.upload-img {
width: 400px;
.el-button {
margin-left: 0;
}
}
</style>

+ 66
- 0
src/views/message-manage/main/add-mass/index.scss Целия файл

@@ -0,0 +1,66 @@
.home-container {
padding: 0 20px;
//overflow-y: scroll;
overflow-x: hidden;
border: none;
box-shadow: none;
.form-container {
height: 500px;
border: 1px solid #d8dce5;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
p {
margin: 5px 0;
}
.input-width-400 {
width: 400px;
}
.input-width-600 {
width: 600px;
}
.inline-form-item {
display: inline-block;
}
}
.footer-container {
height: 100px;
display: flex;
justify-content: center;
align-items: center;
.el-button {
width: 120px;
}
}
.preview-container {
//height: 400px;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-direction: column;
margin: 20px;
border: 1px solid #d8dce5;
.top {
width: 100%;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-direction: column;
padding: 0 40px;
border-bottom: 1px solid #d8dce5 ;
}
.fot {
width: 100%;
padding: 0 40px;
display: flex;
justify-content: space-between;
align-items: center;
}
}
.preview-btn {
display: flex;
justify-content: center;
align-items: center;
}
}

+ 200
- 9
src/views/message-manage/main/add-mass/index.vue Целия файл

@@ -1,38 +1,229 @@
<!--
* @Date: 2022-08-08 10:09:47
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-08 16:08:07
* @LastEditTime: 2022-08-10 09:43:22
* @FilePath: \TelpoUserManageAdmin\src\views\message-manage\main\add-mass\index.vue
* @description: 添加群发
-->

<template>
<div class="app-container">
<!-- 顶部内容 -->
<div class="top-container">
<TopMenu :buttonList="buttonList"/>
<div class="home-container">
<div class="form-container">
<!-- 表单 -->
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="消息主题:" size="small">
<el-input v-model="form.msgTheme" class="input-width-400" clearable ></el-input>
</el-form-item>
<el-form-item label="内容模板:" size="small">

<p>{{firstData}}</p>
<el-input v-model="form.contentTitle" class="input-width-600" clearable ></el-input>

<p>学习账号{{keyword1Data}}</p>
<el-input v-model="form.studyAccount" class="input-width-400" clearable ></el-input>

<p>更新内容{{keyword2Data}}</p>
<el-input v-model="form.updateCon" class="input-width-600" clearable ></el-input>

<p>{{remarkData}}</p>
<el-input v-model="form.contentDetails" class="input-width-600" clearable ></el-input>
</el-form-item>

<el-form-item label="内容链接:" size="small" class="inline-form-item">
<el-input v-model="form.contentUrl" placeholder="请选择文章或者输入外部URL" class="input-width-400"></el-input>
<el-select v-model="article" placeholder="选择文章" clearable filterable @change="onSelectArt">
<el-option :label="item.label" :value="item.label" v-for="(item, index) in articleList" :key="index"/>
</el-select>
</el-form-item>
<el-form-item label="群发对象:" size="small">
<el-select v-model="form.group" placeholder="选择分组" clearable filterable @change="onSelectMass">
<el-option :label="item.label" :value="item.label" v-for="(item, index) in groupList" :key="index"/>
</el-select>
<el-button type="primary" @click="onCheckList">查看名单</el-button>
</el-form-item>
</el-form>
</div>
<!-- 底部操作按钮 -->
<div class="footer-container">
<el-button type="primary" v-for="(item, index) in footBtnList" :key="index" @click="item.click">{{item.name}}</el-button>
</div>
<!-- 预览dialog -->
<el-dialog title="预览信息" :visible.sync="previewShow">
<div class="preview-container">
<div class="top">
<p>{{form.contentTitle}}</p>
<p>学习账号:{{form.studyAccount}}</p>
<p>更新内容:{{form.updateCon}}</p>
<p>更新时间:{{updateTime}}</p>
<p>{{form.contentDetails}}</p>
</div>
<div class="fot">
<p>详情</p>
<p>></p>
</div>
</div>
<div class="preview-btn">
<el-button type="primary" @click="onConfirm">确认</el-button>
</div>
</el-dialog>
</div>
</template>

<script>
import TopMenu from "@/components/TopMenu/index";
//import TopMenu from "@/components/TopMenu/index";
import { initTime } from '@/utils/index.js';
/* import './index.scss' */
export default {
name: 'add-mass',
components: { TopMenu },
components: { },
data(){
return {
buttonList: [], // 头部按钮,例子: {name: '添加', type: 'primary', icon: 'el-icon-circle-plus', click: () => { this.AddDialog();}}
firstData: '{{first.DATA}}:',
keyword1Data: '{{keyword1DATA}}:',
keyword2Data: '{{keyword2DATA}}:',
remarkData: '{{remarkDATA}}:',
form: {
msgTheme: '' || '财商学习通知',
contentTitle: '' || '家长您好,您孩子所需的财商学习内容有更新', //内容模板标题
studyAccount: '' || 'csds', //学习账号
updateCon: '' || '财商36问', //更新内容
contentDetails: '' || '请点击内容查看详情', //内容详情
contentUrl: '', //内容连接
group: '', //分组
},
article: '', //选择文章
articleList: [
{ label: '文章1', value: '文章1' },
{ label: '文章2', value: '文章2' },
{ label: '文章3', value: '文章3' },
{ label: '文章4', value: '文章4' },
],
// 用户分组
groupList: [
{ label: '分组1', value: '分组2' },
{ label: '分组2', value: '分组2' },
{ label: '分组3', value: '分组3' },
{ label: '分组4', value: '分组4' },
],
// 底部操作按钮
footBtnList: [
{ name: '立即发送', click: () => { this.onSend()}},
{ name: '保存', click: () => { this.onSave()} },
{ name: '预览', click: () => { this.onPreview()} },

],
// 预览dialog
previewShow: false,
}
},
computed: {
// 初始弹窗更新时间
updateTime() {
return initTime(new Date(), 'ymdh'); //更新时间
}
},
mounted() {},
created() {},
methods: {

// 查看白名单
onCheckList() {},
// 立即发送
onSend() {},
// 保存
onSave() {
},
// 预览
onPreview() {
this.previewShow = true;
},
// 预览确认
onConfirm() {
this.previewShow = false;
},
// 选择文章
onSelectArt(value) {
if(value) {
this.form.contentUrl = value;
console.log("this.form.contentUrl", this.form.contentUrl);
}
},
// 选择群发对象分组
onSelectMass(value) {
if(value) {
this.form.group = value;
console.log("this.form.group", this.form.group);
}
}
}
}
</script>

<style scoped lang="scss">

.home-container {
padding: 0 20px;
//overflow-y: scroll;
overflow-x: hidden;
border: none;
box-shadow: none;
.form-container {
height: 500px;
border: 1px solid #d8dce5;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
p {
margin: 5px 0;
}
.input-width-400 {
width: 400px;
}
.input-width-600 {
width: 600px;
}
.inline-form-item {
display: inline-block;
}
}
.footer-container {
height: 100px;
display: flex;
justify-content: center;
align-items: center;
.el-button {
width: 120px;
}
}
.preview-container {
//height: 400px;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-direction: column;
margin: 20px;
border: 1px solid #d8dce5;
.top {
width: 100%;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-direction: column;
padding: 0 40px;
border-bottom: 1px solid #d8dce5 ;
}
.fot {
width: 100%;
padding: 0 40px;
display: flex;
justify-content: space-between;
align-items: center;
}
}
.preview-btn {
display: flex;
justify-content: center;
align-items: center;
}
}
</style>

+ 37
- 0
telpo_user_admin_run.sh Целия файл

@@ -0,0 +1,37 @@
#!/bin/bash
###
# @Date: 2022-08-06 16:12:07
# @LastEditors: JinxChen
# @LastEditTime: 2022-09-08 14:19:48
# @FilePath: \TelpoUserManageAdmin\telpo_user_admin_run.sh
# @description:
###

environment=$1
version=$2
echo "环境变量为${environment},版本为$version!"
if [[ ${environment} = 'production' ]]; then
echo "开始远程构建容器"
docker stop telpo_user_admin || true;
docker rm telpo_user_admin || true;
docker rmi -f $(docker images | grep registry.cn-shanghai.aliyuncs.com/gps_card/telpo_user_admin | awk '{print $3}')
#docker login --username=telpo_linwl@1111649216405698 --password=telpo#1234 registry.cn-shanghai.aliyuncs.com;
docker login --username=rzl_wangjx@1111649216405698 --password=telpo.123 registry.cn-shanghai.aliyuncs.com
docker pull registry.cn-shanghai.aliyuncs.com/gps_card/telpo_user_admin:$version
docker run -p 8073:80 -d --restart=always --name telpo_user_admin registry.cn-shanghai.aliyuncs.com/gps_card/telpo_user_admin:$version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
docker ps -a

elif [[ ${environment} == 'test' ]]; then
echo "开始在测试环境远程构建容器"
docker stop telpo_user_admin || true
docker rm telpo_user_admin || true
docker rmi -f $(docker images | grep 139.224.254.18:5000/telpo_user_admin | awk '{print $3}')
docker pull 139.224.254.18:5000/telpo_user_admin:$version
docker run -p 8073:80 -d --restart=always --name telpo_user_admin 139.224.254.18:5000/telpo_user_admin:$version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
docker ps -a

fi

Loading…
Отказ
Запис