Compare commits

...

2 Commits

Author SHA1 Message Date
Vinjor
03d9590d59 Merge branch 'master' of http://124.222.105.7:3000/dianliang/dl_site_system
# Conflicts:
#	dl_vue/src/router/index.js
2025-06-26 15:51:04 +08:00
Vinjor
8ffeb87743 1 2025-06-26 15:49:52 +08:00
24 changed files with 1110 additions and 106 deletions

View File

@ -0,0 +1,138 @@
package com.ruoyi.busi.controller;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.base.service.IBasePicsService;
import com.ruoyi.busi.vo.ProdNewVO;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.busi.domain.BusiProdNew;
import com.ruoyi.busi.service.IBusiProdNewService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import static com.ruoyi.constant.DictConstants.FILE_TYPE_PRODUCT;
/**
* 产品Controller
*
* @author vinjor-m
* @date 2025-06-25
*/
@RestController
@RequestMapping("/busi/prod")
public class BusiProdController extends BaseController
{
@Autowired
private IBusiProdNewService busiProdNewService;
@Autowired
private IBasePicsService basePicsService;
/**
* 查询产品列表
*/
@PreAuthorize("@ss.hasPermi('busi:prod:list')")
@GetMapping("/list")
public AjaxResult list(BusiProdNew busiProdNew,
@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize)
{
Page<BusiProdNew> page = new Page<>(pageNum, pageSize);
IPage<ProdNewVO> list = busiProdNewService.queryListPage(busiProdNew,page);
return success(list);
}
/**
* 导出产品列表
*/
@PreAuthorize("@ss.hasPermi('busi:prod:export')")
@Log(title = "产品", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, BusiProdNew busiProdNew)
{
List<BusiProdNew> list = busiProdNewService.list();
ExcelUtil<BusiProdNew> util = new ExcelUtil<BusiProdNew>(BusiProdNew.class);
util.exportExcel(response, list, "产品、文章数据");
}
/**
* 获取产品详细信息
*/
@PreAuthorize("@ss.hasPermi('busi:prod:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(busiProdNewService.getById(id));
}
/**
* 获取产品表当前最大排序
*/
@GetMapping(value = "/getMaxSort")
public AjaxResult getMaxSort(String tenantId)
{
return success(busiProdNewService.getMaxSort(tenantId));
}
/**
* 新增产品
*/
@PreAuthorize("@ss.hasPermi('busi:prod:add')")
@Log(title = "产品", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody ProdNewVO prodNewVO){
busiProdNewService.save(prodNewVO);
if(null!=prodNewVO.getFileList() && !prodNewVO.getFileList().isEmpty()){
prodNewVO.getFileList().forEach(item->{
item.setTenantId(prodNewVO.getTenantId());
item.setFileType(FILE_TYPE_PRODUCT);
});
}
return success();
}
/**
* 修改产品
*/
@PreAuthorize("@ss.hasPermi('busi:prod:edit')")
@Log(title = "产品", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody ProdNewVO prodNewVO){
busiProdNewService.updateById(prodNewVO);
if(null!=prodNewVO.getFileList() && !prodNewVO.getFileList().isEmpty()){
prodNewVO.getFileList().forEach(item->{
item.setTenantId(prodNewVO.getTenantId());
item.setFileType(FILE_TYPE_PRODUCT);
});
}
return success();
}
/**
* 删除产品
*/
@PreAuthorize("@ss.hasPermi('busi:prod:remove')")
@Log(title = "产品", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids){
List<String> list = new ArrayList<>(Arrays.asList(ids));
return toAjax(busiProdNewService.removeByIds(list));
}
}

View File

@ -0,0 +1,84 @@
package com.ruoyi.busi.domain;
import com.ruoyi.common.annotation.Excel;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import com.ruoyi.common.core.domain.DlBaseEntity;
/**
* 产品文章对象 dl_busi_prod_new
*
* @author vinjor-m
* @date 2025-06-25
*/
@TableName("dl_busi_prod_new")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BusiProdNew extends DlBaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(type = IdType.ASSIGN_UUID)
private String id;
/** 所属栏目id */
@Excel(name = "所属栏目id")
private String catgId;
/** 产品名称或文章标题 */
@Excel(name = "产品名称或文章标题")
private String title;
/** 页面title */
@Excel(name = "页面title")
private String prodTitle;
/** 页面keyword */
@Excel(name = "页面keyword")
private String prodKeyword;
/** 页面description */
@Excel(name = "页面description")
private String prodDescription;
/** 文章来源 */
@Excel(name = "文章来源")
private String newsFrom;
/** 产品主图或文章图片 */
@Excel(name = "产品主图或文章图片")
private String mainPic;
/** 产品图(多张) */
@Excel(name = "产品图", readConverterExp = "多=张")
private String pics;
/** 产品简介或文章简介(支持换行符) */
@Excel(name = "产品简介或文章简介", readConverterExp = "支=持换行符")
private String description;
/** 产品内容或文章内容(富文本) */
private String content;
/** 排序 */
private Long sort;
/** 是否首页推荐显示 */
@Excel(name = "是否首页推荐显示")
private Integer ifReco;
/** 是否发布(未发布的在草稿箱) */
@Excel(name = "是否发布", readConverterExp = "未=发布的在草稿箱")
private Integer ifPublic;
/** 站点唯一编码租户id */
private String tenantId;
}

View File

@ -0,0 +1,24 @@
package com.ruoyi.busi.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.busi.domain.BusiProdNew;
import com.ruoyi.busi.vo.ProdNewVO;
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 产品文章Mapper接口
*
* @author vinjor-m
* @date 2025-06-25
*/
@Mapper
public interface BusiProdNewMapper extends BaseMapper<BusiProdNew>
{
IPage<ProdNewVO> queryListPage(@Param("entity") BusiProdNew entity, Page<BusiProdNew> page);
Long selectMaxSort(@Param("tenantId")String tenantId);
}

View File

@ -0,0 +1,28 @@
package com.ruoyi.busi.service;
import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.busi.domain.BusiProdNew;
import com.ruoyi.busi.vo.ProdNewVO;
/**
* 产品文章Service接口
*
* @author vinjor-m
* @date 2025-06-25
*/
public interface IBusiProdNewService extends IService<BusiProdNew>
{
IPage<ProdNewVO> queryListPage(BusiProdNew pageReqVO, Page<BusiProdNew> page);
/**
* 获取产品表当前最大排序
* @author vinjor-M
* @date 16:15 2025/6/25
* @param tenantId 站点id
* @return java.lang.Long
**/
Long getMaxSort(String tenantId);
}

View File

@ -0,0 +1,46 @@
package com.ruoyi.busi.service.impl;
import java.util.List;
import com.ruoyi.busi.vo.ProdNewVO;
import com.ruoyi.common.utils.DateUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.busi.mapper.BusiProdNewMapper;
import com.ruoyi.busi.domain.BusiProdNew;
import com.ruoyi.busi.service.IBusiProdNewService;
/**
* 产品文章Service业务层处理
*
* @author vinjor-m
* @date 2025-06-25
*/
@Service
public class BusiProdNewServiceImpl extends ServiceImpl<BusiProdNewMapper,BusiProdNew> implements IBusiProdNewService
{
@Autowired
private BusiProdNewMapper busiProdNewMapper;
@Override
public IPage<ProdNewVO> queryListPage(BusiProdNew pageReqVO, Page<BusiProdNew> page) {
return busiProdNewMapper.queryListPage(pageReqVO, page);
}
/**
* 获取产品表当前最大排序
*
* @param tenantId 站点id
* @return java.lang.Long
* @author vinjor-M
* @date 16:15 2025/6/25
**/
@Override
public Long getMaxSort(String tenantId) {
Long sort = busiProdNewMapper.selectMaxSort(tenantId);
return null==sort?1:sort+1;
}
}

View File

@ -0,0 +1,32 @@
package com.ruoyi.busi.vo;
import com.ruoyi.base.domain.BasePics;
import com.ruoyi.busi.domain.BusiProdNew;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* 产品文章VO
* @author vinjor-M
* @date 14:49 2025/6/25
**/
@EqualsAndHashCode(callSuper = true)
@Data
public class ProdNewVO extends BusiProdNew {
/** 所属栏目名称 */
@Excel(name = "所属栏目名称")
private String catgName;
/** 产品发布者 */
@Excel(name = "产品发布者")
private String userName;
/**
* 批量传的图片
**/
private List<BasePics> fileList;
}

View File

@ -12,9 +12,22 @@ import java.util.Locale;
public class DictConstants
{
/**
* 博主类型字典key
* 图片所属分类字典-KEY
*/
public static final String BLOGGER_TYPES_KEY ="dl_blogger_type";
public static final String FILE_TYPE_KEY ="file_type";
/**
* 图片所属分类字典-产品
*/
public static final String FILE_TYPE_PRODUCT ="product";
/**
* 图片所属分类字典-新闻
*/
public static final String FILE_TYPE_NEWS ="news";
/**
* 图片所属分类字典-其他
*/
public static final String FILE_TYPE_OTHER ="other";
/**

View File

@ -5,9 +5,7 @@ package com.ruoyi.constant;
*
* @author ruoyi
*/
public class StrConstants
{
public class StrConstants {
}

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.busi.mapper.BusiProdNewMapper">
<resultMap type="com.ruoyi.busi.vo.ProdNewVO" id="BusiProdNewResult">
<result property="id" column="id"/>
<result property="catgId" column="catg_id"/>
<result property="title" column="title"/>
<result property="prodTitle" column="prod_title"/>
<result property="prodKeyword" column="prod_keyword"/>
<result property="prodDescription" column="prod_description"/>
<result property="newsFrom" column="news_from"/>
<result property="mainPic" column="main_pic"/>
<result property="pics" column="pics"/>
<result property="description" column="description"/>
<result property="content" column="content"/>
<result property="sort" column="sort"/>
<result property="ifReco" column="if_reco"/>
<result property="ifPublic" column="if_public"/>
<result property="tenantId" column="tenant_id"/>
<result property="creator" column="creator"/>
<result property="createTime" column="create_time"/>
<result property="updater" column="updater"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="catgName" column="catg_name"/>
<result property="userName" column="user_name"/>
</resultMap>
<sql id="selectBusiProdNewVo">
select id,
catg_id,
title,
prod_title,
prod_keyword,
prod_description,
news_from,
main_pic,
pics,
description,
content,
sort,
if_reco,
if_public,
tenant_id,
creator,
create_time,
updater,
update_time,
del_flag
from dl_busi_prod_new
</sql>
<select id="queryListPage" parameterType="BusiProdNew" resultMap="BusiProdNewResult">
SELECT
product.*,
su.nick_name AS user_name ,
dbc.catg_name AS catg_name
FROM
dl_busi_prod_new product
LEFT JOIN sys_user su ON product.creator = su.user_id
LEFT JOIN dl_busi_category dbc ON product.catg_id = dbc.id
<where>
product.del_flag = '0'
AND product.tenant_id = #{entity.tenantId}
<if test="entity.ifReco != null">
AND product.if_reco = #{entity.ifReco}
</if>
<if test="entity.ifPublic != null">
AND product.if_public = #{entity.ifPublic}
</if>
<if test="entity.catgId != null and entity.catgId != ''">
AND product.catg_id = #{entity.catgId}
</if>
<if test="entity.title != null and entity.title != ''">
AND product.title like concat('%', #{entity.title},
'%')
</if>
<if test="entity.newsFrom != null and entity.newsFrom != ''">
AND product.news_from like concat('%',
#{entity.newsFrom}, '%')
</if>
</where>
ORDER BY product.sort DESC
</select>
<select id="selectMaxSort" resultType="java.lang.Long">
SELECT
MAX( sort )
FROM
dl_busi_prod_new
WHERE
del_flag = '0'
AND tenant_id = #{tenantId}
</select>
</mapper>

View File

@ -1,10 +1,10 @@
# 页面标题
VUE_APP_TITLE = 成事达运营平台
VUE_APP_TITLE = 成事达管理平台
# 开发环境配置
ENV = 'development'
# 成事达运营平台/开发环境
# 成事达管理平台/开发环境
VUE_APP_BASE_API = '/dev-api'
# 路由懒加载

View File

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 成事达运营平台
VUE_APP_TITLE = 成事达管理平台
BABEL_ENV = production
@ -8,5 +8,5 @@ NODE_ENV = production
# 测试环境配置
ENV = 'staging'
# 成事达运营平台/测试环境
# 成事达管理平台/测试环境
VUE_APP_BASE_API = '/stage-api'

View File

@ -121,9 +121,9 @@
"insertimage", // 多图上传
"emotion", // 表情
"scrawl", // 涂鸦
"insertvideo", // 视频
"insertaudio", // 音频
"attachment", // 附件
// "insertvideo", // 视频
// "insertaudio", // 音频
// "attachment", // 附件
"insertframe", // 插入Iframe
"insertcode", // 插入代码
"pagebreak", // 分页
@ -261,7 +261,7 @@
//,theme:'default'
//,themePath:URL +"themes/"
//,zIndex : 900 //编辑器层级的基数,默认是900
,zIndex : 900 //编辑器层级的基数,默认是900
//针对getAllHtml方法会在对应的head标签中增加该编码设置。
//,charset:"utf-8"

View File

@ -25,4 +25,9 @@ export default {
#app .theme-picker {
display: none;
}
/deep/.dl-flex-column {
display: flex;
justify-content: start;
align-items: center
}
</style>

View File

@ -0,0 +1,53 @@
import request from '@/utils/request'
// 查询产品、文章列表
export function listProdNew(query) {
return request({
url: '/busi/prod/list',
method: 'get',
params: query
})
}
// 查询产品、文章列表
export function getMaxSort(query) {
return request({
url: '/busi/prod/getMaxSort',
method: 'get',
params: query
})
}
// 查询产品、文章详细
export function getProdNew(id) {
return request({
url: '/busi/prod/' + id,
method: 'get'
})
}
// 新增产品、文章
export function addProdNew(data) {
return request({
url: '/busi/prod',
method: 'post',
data: data
})
}
// 修改产品、文章
export function updateProdNew(data) {
return request({
url: '/busi/prod',
method: 'put',
data: data
})
}
// 删除产品、文章
export function delProdNew(id) {
return request({
url: '/busi/prod/' + id,
method: 'delete'
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

@ -38,7 +38,7 @@ export default {
UEDITOR_HOME_URL: '/UEditor/',
//**231218**
UEDITOR_CORS_URL: '/UEditor/',
zIndex: 99999,//z
zIndex: 999,//z
}
}
}

View File

@ -88,6 +88,20 @@ export const constantRoutes = [
}
]
},
{
path: '/product',
component: Layout,
hidden: true,
redirect: 'noredirect',
children: [
{
path: 'prodForm',
component: () => import('@/views/busi/prod/prodForm'),
name: 'ProdForm',
meta: { title: '产品详情' }
}
]
},
{
path: '/category',
component: Layout,

View File

@ -29,9 +29,11 @@
<el-row>
<el-col :span="8">
<el-form-item label="手机号码" prop="tel">
<div style="display: flex;justify-content: start;align-items: center">
<div class="dl-flex-column">
<el-input v-model="form.tel" placeholder="请输入手机号码"/>
<el-tooltip class="item" effect="dark" content="发询盘短信要用到,格式:+8618612345678 或者 +886970123456" placement="bottom">
<el-tooltip class="item" effect="dark" content="发询盘短信要用到,格式:+8618612345678 或者 +886970123456"
placement="bottom"
>
<i class="el-icon-question"></i>
</el-tooltip>
</div>
@ -123,31 +125,31 @@ export default {
//
rules: {
companyName: [
{ required: true, message: '请输入公司名称', trigger: 'blur' },
{ required: true, message: '请输入公司名称', trigger: 'blur' }
],
tel: [
{ required: true, message: '请输入手机号码', trigger: 'blur' },
{ required: true, message: '请输入手机号码', trigger: 'blur' }
],
email: [
{ required: true, message: '请输入Email账号', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
],
teams: [
{ required: true, message: '请输入Teams账号', trigger: 'blur' },
{ required: true, message: '请输入Teams账号', trigger: 'blur' }
],
icon: [
{ required: true, message: '请上传站点icon', trigger: 'blur' },
{ required: true, message: '请上传站点icon', trigger: 'blur' }
],
logo: [
{ required: true, message: '请上传站点logo', trigger: 'blur' },
{ required: true, message: '请上传站点logo', trigger: 'blur' }
],
qrCode: [
{ required: true, message: '请上传站点二维码', trigger: 'blur' },
],
{ required: true, message: '请上传站点二维码', trigger: 'blur' }
]
}
}
},
onShow(){
onShow() {
this.getDataInfo()
},
methods: {
@ -177,7 +179,11 @@ export default {
}
}
})
},
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,217 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="产品名称" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入产品名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['busi:prod:add']"
>新增</el-button>
</el-col>
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="success"-->
<!-- plain-->
<!-- icon="el-icon-edit"-->
<!-- size="mini"-->
<!-- :disabled="single"-->
<!-- @click="handleUpdate"-->
<!-- v-hasPermi="['busi:prod:edit']"-->
<!-- >修改</el-button>-->
<!-- </el-col>-->
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="danger"-->
<!-- plain-->
<!-- icon="el-icon-delete"-->
<!-- size="mini"-->
<!-- :disabled="multiple"-->
<!-- @click="handleDelete"-->
<!-- v-hasPermi="['busi:prod:remove']"-->
<!-- >删除</el-button>-->
<!-- </el-col>-->
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="warning"-->
<!-- plain-->
<!-- icon="el-icon-download"-->
<!-- size="mini"-->
<!-- @click="handleExport"-->
<!-- v-hasPermi="['busi:prod:export']"-->
<!-- >导出</el-button>-->
<!-- </el-col>-->
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="prodList" @selection-change="handleSelectionChange">
<!-- <el-table-column type="selection" width="55" align="center" />-->
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column label="所属栏目" align="center" prop="catgName" />
<el-table-column label="产品名称" align="center" prop="title" />
<el-table-column label="产品主图" align="center" prop="mainPic" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.mainPic" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="产品图" align="center" prop="pics" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.pics" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="产品简介" align="center" prop="description" />
<el-table-column label="是否首页推荐显示" align="center" prop="ifReco">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_yes_no" :value="scope.row.ifReco"/>
</template>
</el-table-column>
<el-table-column label="是否发布" align="center" prop="ifPublic">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_yes_no" :value="scope.row.ifPublic"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['busi:prod:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['busi:prod:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listProdNew, getProdNew, delProdNew, addProdNew, updateProdNew } from "@/api/busi/prod";
export default {
name: "Prod",
dicts: ['sys_yes_no'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
prodList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
catgId: null,
title: null,
newsFrom: null,
},
};
},
created() {
this.getList();
},
methods: {
/** 查询产品、文章列表 */
getList() {
this.loading = true;
listProdNew(this.queryParams).then(response => {
this.prodList = response.data.records;
this.total = response.data.total;
this.loading = false;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.$router.push({path:'/product/prodForm'})
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getProdNew(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改产品、文章";
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除产品、文章编号为"' + ids + '"的数据项?').then(function() {
return delProdNew(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('busi/prod/export', {
...this.queryParams
}, `prodNew_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -0,0 +1,222 @@
<template>
<div class="app-container">
<el-row>
<el-col :span="24">
<el-button @click="back"> </el-button>
<el-button type="success" @click="submitForm"> </el-button>
<el-button type="primary" @click="submitForm"> </el-button>
</el-col>
</el-row>
<el-divider></el-divider>
<el-form ref="form" :model="form" :rules="rules" label-width="150px">
<el-row>
<el-col :span="8">
<el-form-item label="产品名称" prop="title">
<el-input v-model="form.title" placeholder="请输入产品名称"/>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="所属分类" prop="catgId">
<div class="dl-flex-column">
<el-input v-model="form.catgId" placeholder="请输入产品名称"/>
<div class="dl-add-catg">添加产品分类</div>
</div>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="排序" prop="sort">
<el-input v-model="form.sort" type="number" placeholder="请输入排序"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="产品主图" prop="mainPic">
<el-tag style="cursor: pointer">图片库选择</el-tag>
<image-upload @uploadedImg="uploadedImg" v-model="form.mainPic" :limit="1"/>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="产品图库" prop="pics">
<el-tag style="cursor: pointer">图片库选择</el-tag>
<image-upload @uploadedImg="uploadedImg" v-model="form.pics" :limit="9"/>
</el-form-item>
</el-col>
</el-row>
<!-- <el-form-item label="页面title" prop="prodTitle">-->
<!-- <el-input v-model="form.prodTitle" placeholder="请输入页面title"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="页面keyword" prop="prodKeyword">-->
<!-- <el-input v-model="form.prodKeyword" type="textarea" placeholder="请输入内容"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="页面description" prop="prodDescription">-->
<!-- <el-input v-model="form.prodDescription" type="textarea" placeholder="请输入内容"/>-->
<!-- </el-form-item>-->
<el-row>
<el-col :span="18">
<el-form-item label="产品简介" prop="description">
<div class="dl-flex-column">
<el-input style="width: 80%" ref="descriptionInput" v-model="form.description" type="textarea"
placeholder="请输入内容" @blur="handleBlur"
/>
<el-tag style="cursor: pointer;margin-left: 10px" @click="insertBr">插入换行符</el-tag>
</div>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="首页推荐" prop="ifReco">
<el-radio-group v-model="form.ifReco">
<el-radio
v-for="dict in dict.type.true_or_false"
:key="dict.value"
:label="parseInt(dict.value)"
>{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="产品内容">
<editor v-model="form.content" :min-height="192"/>
</el-form-item>
</el-form>
<el-divider></el-divider>
<el-row>
<el-col :span="24">
<el-button @click="back"> </el-button>
<el-button type="success" @click="saveTmp"> </el-button>
<el-button type="primary" @click="submitForm"> </el-button>
</el-col>
</el-row>
</div>
</template>
<script>
import { listProdNew, getProdNew, delProdNew,getMaxSort, addProdNew, updateProdNew } from '@/api/busi/prod'
export default {
name: 'prodForm',
dicts: ['true_or_false'],
data() {
return {
//--
cursorPos: null,
//
form: {
id: null,
catgId: null,
title: null,
prodTitle: null,
prodKeyword: null,
prodDescription: null,
newsFrom: null,
mainPic: null,
pics: null,
description: null,
content: null,
sort: null,
ifReco: 0,
ifPublic: 0,
tenantId: null,
creator: null,
createTime: null,
updater: null,
updateTime: null,
delFlag: null,
//
fileList:[],
},
//
rules: {
title: [
{ required: true, message: '请输入产品名称', trigger: 'blur' }
],
catgId: [
{ required: true, message: '请选择产品分类', trigger: 'blur' }
],
sort: [
{ required: true, message: '请输入排序', trigger: 'blur' }
],
mainPic: [
{ required: true, message: '请上传产品主图', trigger: 'blur' }
],
description: [
{ required: true, message: '请输入产品简介', trigger: 'blur' }
]
}
}
},
mounted() {
this.initData()
},
methods: {
initData(){
getMaxSort({}).then(response => {
this.form.sort = response.data
})
},
/**
* 返回上一页
*/
back() {
history.back()
},
//
uploadedImg(fileList){
this.form.fileList = this.form.fileList.concat(fileList)
},
handleBlur(e) {
this.cursorPos = e.srcElement.selectionStart
},
/**
* 插入换行符
*/
insertBr() {
let str = '<br/>'
if (!this.form.description) {
this.form.description = str
} else {
const start = this.form.description.substring(0, this.cursorPos)
const end = this.form.description.substring(this.cursorPos)
this.form.description = `${start}${str}${end}`
}
},
/** 暂存 */
saveTmp(){
if (this.form.id != null) {
updateProdNew(this.form).then(response => {
this.$modal.msgSuccess('修改成功')
setTimeout(()=>{
history.back()
},1000)
})
} else {
addProdNew(this.form).then(response => {
this.$modal.msgSuccess('新增成功')
setTimeout(()=>{
history.back()
},1000)
})
}
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate(valid => {
if (valid) {
this.form.ifPublic=1
this.saveTmp()
}
})
},
}
}
</script>
<style scoped>
.dl-add-catg {
cursor: pointer;
width: 130px;
text-align: center;
color: #1890ff;
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<div class="app-container home" style="padding-top: 20%">
<div> 欢迎进入成事达运营管理平台</div>
<div> 欢迎进入成事达管理平台</div>
</div>
</template>

View File

@ -2,11 +2,13 @@
<div class="login">
<div class="centen-box">
<div class="left-box">
<img src="./../assets/images/loginleft.png">
<img style="position: absolute;left: 15px;top: 20px;height: 30px;width: auto;" src="./../assets/images/login_logo.png"
>
<img style="border-radius: 20px 0 0 20px" src="./../assets/images/loginleft.png">
</div>
<div class="right-box">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">成事达运营管理平台</h3>
<h3 class="title">欢迎登录成事达管理平台</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
@ -14,7 +16,7 @@
auto-complete="off"
placeholder="账号"
>
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
</el-input>
</el-form-item>
<el-form-item prop="password">
@ -25,7 +27,7 @@
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
@ -36,7 +38,7 @@
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
@ -48,7 +50,7 @@
:loading="loading"
size="medium"
type="primary"
style="width:100%;"
style="width:100%;background-image: linear-gradient(to right,#0959FC,#2710FF)"
@click.native.prevent="handleLogin"
>
<span v-if="!loading"> </span>
@ -65,13 +67,15 @@
title="请选择管理的站点"
:visible.sync="centerDialogVisible"
width="30%"
center>
center
>
<el-select v-model="chooseSiteCode" placeholder="请选择" style="width: 100%">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
:value="item.value"
>
</el-option>
</el-select>
<span slot="footer" class="dialog-footer">
@ -87,35 +91,36 @@
</template>
<script>
import { getCodeImg } from "@/api/login";
import { setTenantId,setTenantName } from '@/utils/auth'
import Cookies from "js-cookie";
import { getCodeImg } from '@/api/login'
import { setTenantId, setTenantName } from '@/utils/auth'
import Cookies from 'js-cookie'
import { encrypt, decrypt } from '@/utils/jsencrypt'
import { listAllSite } from "@/api/base/site";
import { listAllSite } from '@/api/base/site'
export default {
name: "Login",
name: 'Login',
data() {
return {
options: [],
chooseSiteCode: '',
//
chooseSiteCode: 'main',
centerDialogVisible: false,
codeUrl: "",
codeUrl: '',
loginForm: {
username: "",
password: "",
username: '',
password: '',
rememberMe: false,
code: "",
uuid: ""
code: '',
uuid: ''
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" }
{ required: true, trigger: 'blur', message: '请输入您的账号' }
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" }
{ required: true, trigger: 'blur', message: '请输入您的密码' }
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
code: [{ required: true, trigger: 'change', message: '请输入验证码' }]
},
loading: false,
//
@ -123,105 +128,106 @@ export default {
//
register: false,
redirect: undefined
};
}
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect;
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
created() {
this.getCode();
this.getCookie();
this.getCode()
this.getCookie()
},
methods: {
chooseSiteCodeFun(){
if(this.chooseSiteCode){
this.centerDialogVisible=false
let chooseSiteObj = this.options.filter(item=>item.value==this.chooseSiteCode)[0]
chooseSiteCodeFun() {
if (this.chooseSiteCode) {
this.centerDialogVisible = false
let chooseSiteObj = this.options.filter(item => item.value == this.chooseSiteCode)[0]
setTenantId(this.chooseSiteCode)
setTenantName(chooseSiteObj.label)
this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
}else{
this.$modal.msgWarning("请选择管理的站点");
this.$router.push({ path: this.redirect || '/' }).catch(() => {
})
} else {
this.$modal.msgWarning('请选择管理的站点')
}
},
getCode() {
getCodeImg().then(res => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.img;
this.loginForm.uuid = res.uuid;
this.codeUrl = 'data:image/gif;base64,' + res.img
this.loginForm.uuid = res.uuid
}
});
})
},
getCookie() {
const username = Cookies.get("username");
const password = Cookies.get("password");
const username = Cookies.get('username')
const password = Cookies.get('password')
const rememberMe = Cookies.get('rememberMe')
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
}
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true;
this.loading = true
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
Cookies.set('username', this.loginForm.username, { expires: 30 })
Cookies.set('password', encrypt(this.loginForm.password), { expires: 30 })
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 })
} else {
Cookies.remove("username");
Cookies.remove("password");
Cookies.remove('rememberMe');
Cookies.remove('username')
Cookies.remove('password')
Cookies.remove('rememberMe')
}
this.$store.dispatch("Login", this.loginForm).then(() => {
this.$store.dispatch('Login', this.loginForm).then(() => {
listAllSite().then(response => {
if(response.data && response.data.length>0){
response.data.map((item)=>{
if (response.data && response.data.length > 0) {
response.data.map((item) => {
this.options.push({
value:item.id,
value: item.id,
label: item.siteName
})
})
if(this.options.length>1){
if (this.options.length > 1) {
//
this.centerDialogVisible=true
}else{
this.centerDialogVisible = true
} else {
//
this.chooseSiteCode = this.options[0].value
setTenantId(this.chooseSiteCode)
this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
setTenantName(this.options[0].label)
this.$router.push({ path: this.redirect || '/' }).catch(() => {
})
}
}else{
this.$modal.msgWarning("暂无可管理站点,请联系服务提供商");
setTimeout(()=>{
} else {
this.$modal.msgWarning('暂无可管理站点,请联系服务提供商')
setTimeout(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = '/index'
})
},1000)
}, 1000)
}
});
})
}).catch(() => {
this.loading = false;
this.loading = false
if (this.captchaEnabled) {
this.getCode();
this.getCode()
}
});
})
}
});
})
}
}
};
}
</script>
<style rel="stylesheet/scss" lang="scss">
@ -234,10 +240,17 @@ export default {
background-image: url("../assets/images/x.png");
background-size: cover;
}
.title {
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
position: absolute;
top: 50px;
width: 100%;
margin: 0 auto 60px auto;
text-align: left;
border-left: 5px solid #375BE4;
padding-left: 10px;
font-weight: bold;
color: #353736;
}
.login-form {
@ -245,32 +258,39 @@ export default {
background: #ffffff;
width: 400px;
padding: 25px 25px 5px 25px;
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 33%;
height: 38px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
@ -283,33 +303,39 @@ export default {
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 38px;
}
.centen-box{
height: 700px;
.centen-box {
height: 600px;
background: white;
border-radius:20px;
box-shadow: 0px 7px 27px 0px rgba(133,169,231,0.51);
border-radius: 20px;
box-shadow: 0px 7px 27px 0px rgba(133, 169, 231, 0.51);
width: 70%;
top: 50%;
position: fixed;
left: 50%;
transform: translate(-50%,-50%);
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: space-between;
}
.left-box{
width: 50%;
.left-box {
position: relative;
width: 60%;
height: 100%;
img{
img {
width: 100%;
height: 100%;
}
}
.right-box{
width: 50%;
.right-box {
width: 40%;
height: 100%;
display: flex;
align-items: center;