Vue-admin 模板项目

杂牌技巧

配置页面不需要登录
permission.js 里面的:
const whiteList = [‘/login’] // 不重定向白名单

配置页面不需要菜单和顶部
配在route里面的顶部即可。

路由跳转写法:
this. r o u t e r . p u s h ( n a m e : " p a t i e n t I n f o " , q u e r y : w a r d : w a r d I d ) ; t h i s . router.push({ name: "patientInfo", query: { ward: wardId} }); this. router.push(name:"patientInfo",query:ward:wardId);this.router.push({ path: ‘/userCity’, query: { cityName: this.cityName }})
获取方式:

提示:{{this.$route.params.alert}}

提示:{{this.$route.query.alert}}

参考:[https://www.cnblogs.com/toonezhr/p/10325457.html](https://www.cnblogs.com/toonezhr/p/10325457.html)

几秒后执行的写法:
setTimeout(function() {
that.activeName = ‘first’
}, 500)
参考:链接

网页https访问注意:
编译的时候,prod.env.js 文件按如下设置,访问的时候直接用https的地址访问

module.exports = {
  NODE_ENV: '"production"',
  TIME_OUT: '"60000"',
  BASE_API: '"https://zhanshen888.mynatapp.cc/"',
}

post请求里面参数不合法
试试params修改为data

insert(data) {
  return request({
    url: '/lwPortalConfig/insert',
    method: 'post',
    data
  })
},

常规开发

Step1、创建表结构
通常,在后端项目下的pdm文件夹里面打开pdm文件,编辑好表信息。
拷贝建表语法到指定数据库,执行。

Step2、生成代码
使用的是自定义的代码生成器,可以生成配套的后端和前端代码。

进入该目录,打开cmd,输入rapid-gen.bat
执行 gen + 表名,生成具体代码

Step3、后端代码开发
后端主要是web + service + mapper + entity + mapper.xml,五个文件。
正常目录没有特殊要求的话,导入进来接口就能用了。
通常要改的是分页语法:

<select id="findListPage" resultType="lyOrgDict">
    select
    t.*
    from
    ly_org_dict t
    where 1=1
    <if test="query != null and query != ''">
        AND (INSTR(t.ORG_NAME , #{query})>0 OR INSTR(t.ORG_ID , #{query})>0)
    </if>
    <if test="model.validFlag != null and model.validFlag != ''">
        and t.VALID_FLAG = #{model.validFlag}
    </if>
</select>

然后是关联查询:

select
    t.*,
		(SELECT o.NICK_NAME FROM lw_user_info o WHERE o.USER_ID = T.USER_ID) nickName,
		(SELECT o.ORG_NAME FROM ly_org_dict o WHERE o.ORG_ID = T.ORDER_ORG) orgName,
		(SELECT o.PRO_PRICE FROM ly_product_dict o WHERE o.PRO_ID = T.PRO_ID) proPrice,
		(SELECT o.OBJ_NAME FROM ly_server_object o WHERE o.OBJ_ID = T.OBJ_ID) objName
    from
    ly_order_record t
    where 1=1

Step4、前端代码开发

4.1、前置检查
先确认一下vue文件里面的api目录是否正常,配置一下路由指向这个vue文件。

然后,可以运行起来程序,确认一下页面访问是否正常。
打开页面代码,先格式化一下!

4.2、处理表格列
代码生成器生成的,所有字段都会作为列,这里去掉不要的。
同时可以往数据库插入一条合理的数据,看是否要调整宽度。
如果是图片类型的话,写法要变化一下。

<img v-if="scope.row.itemImg" :src="fileBefore + scope.row.itemImg" style="width: 50px;height: 50px;">

如果某列是一个字典,需要翻译,则按如下处理:

<el-tag :type="scope.row.itemType | statusFilter" slot-scope="scope">
  {{ scope.row.itemType | commonFilter(orderStatusObj) }}
</el-tag>
  
orderStatusObj: { //状态类型
  '1': '荣誉资质',
  '2': '设备展示',
  '3': '合作客户',
},

4.3、处理搜索条件
默认搜索条件是query模糊搜索和validFlag下拉搜索。
query搜索需要改一下后端的page语法,看具体根据什么字段模糊搜索。
后端语法里面是否根据排序号和时间排序按需调整。
范例参考如下:

<select id="findListPage" resultType="oaInfoConfig">
    select 
        t.*
      from 
        oa_info_config t
     where 1=1
    <if test="query != null and query != ''">
        AND INSTR(t.ITEM_NAME , #{query})>0
    </if>
    <if test="model.validFlag != null and model.validFlag != ''">
        and t.VALID_FLAG = #{model.validFlag}
    </if>
    <if test="model.itemType != null and model.itemType != ''">
        and t.ITEM_TYPE = #{model.itemType}
    </if>
    order by t.SORT_NO
</select>

如果要根据某个字典进行过滤,代码接4.1继续:

<el-select v-model="listQuery.itemType" placeholder="产品类型" clearable class="filter-item"
           style="width: 150px"
           @change="handleFilter">
  <el-option v-for="(value, key) in orderStatusObj" :key="key" :label="value" :value="key"/>
</el-select>

4.4、处理表单信息
部分参考代码如下:

<el-row :gutter="20" v-if="dialogStatus === 'update'">
  <el-col :span="12">
    <el-form-item label="项目ID" label-width="105px" prop="itemId">
      <el-input v-model="temp.itemId" :disabled="dialogStatus === 'update'"/>
    </el-form-item>
  </el-col>
</el-row><el-row :gutter="20">
  <el-col :span="12">
    <el-form-item label="项目名称" label-width="105px" prop="itemName">
      <el-input v-model="temp.itemName"/>
    </el-form-item>
  </el-col>
  <el-col :span="12">
    <el-form-item label="项目类型" label-width="105px" prop="itemType">
      <el-select v-model="temp.itemType" clearable class="filter-item" style="width: 150px">
        <el-option v-for="(value, key) in orderStatusObj" :key="key" :label="value+'('+key+')'" :value="key"/>
      </el-select>
    </el-form-item>
  </el-col>
</el-row>

去掉一些不需要校验的rules
排序号规则要调整一下,输入框也要加上number:

<el-form-item label="排序号" label-width="105px" prop="sortNo">
  <el-input v-model.number="temp.sortNo" auto-complete="off"/>
</el-form-item>

sortNo: [
  {
    type: 'number', required: false, message: '排序号必须为整数值', transform(value) {
      if (value === '' || value === null) {
        return 0
      }
      if (_.isInteger(value)) {
        return value
      } else {
        return false
      }
    }
  }
]

4.5、字典如果是列表的情况
注意,字典来源可能不是写死的,而是另外一张表,那就是需要先获取列表数据,赋值给一个数组属性,其涉及的全套代码具体如下:

<el-select v-model="listQuery.orgCode" placeholder="所属商家" :disabled="isOrg" clearable class="filter-item"
           style="width: 150px" @change="handleFilter">
  <el-option v-for="{orgCode, orgName} in orgs" :key="orgCode" :label="orgName"
             :value="orgCode"/>
</el-select>

<el-table-column label="所属商家" align="center" style="width: 10%">
  <template slot-scope="scope">
    <span>{{ scope.row.orgCode | orgFilter(orgs) }}</span>
  </template>
</el-table-column>

<el-col :span="12">
  <el-form-item label="所属商家" label-width="105px" prop="orgCode">
    <el-select v-model="temp.orgCode" clearable class="filter-item" style="width: 150px" :disabled="isOrg" >
      <el-option v-for="{orgCode, orgName} in orgs" :key="orgCode" :label="orgName"
                 :value="orgCode"/>
    </el-select>
  </el-form-item>
</el-col>

this.$http.all([SyCategoriesApi.getPage(this.listQuery), SyOrgDictApi.getList({validFlag: '1'})])
  .then(this.$http.spread(function (perms, two) {
    if(that.orgCode){
      that.orgs = two.filter(item => item.orgCode === that.orgCode)
    }else{
      that.orgs = two
    }
    that.list = perms.rows
    that.total = perms.total
    that.listLoading = false
  }));

4.6、文件上传处理
文件有两种方案,一种是数据库存绝对路径,一种是存相对路径,具体代码如下。
存相对路径的好处是,如果后期修改域名,数据库的图片地址不需要全部修改。
当然,有条件的还是使用OSS去存储。

//方案一:存绝对路径
uploadUrl: process.env.BASE_API + 'uploadOneImg',

//方案二:存相对路径
uploadUrl: process.env.BASE_API + 'uploadOneImg?handleFlag=only',
fileBefore: process.env.BASE_API + 'oa/',

涉及文件上传的,CSS样式要加上:

<style scoped>
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.avatar-uploader .el-upload:hover {
  border-color: #409EFF;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}

.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

表单部分的代码如下:

<el-row :gutter="20">
  <el-col :span="12">
    <el-form-item label="展示图片" label-width="120px" prop="itemImg">
      <el-upload
        with-credentials
        enctype="multipart/form-data"
        :show-file-list="false"
        :on-error="uploadError"
        :on-success="uploadSuccess"
        :before-upload="beforeUpload"
        :action="uploadUrl"
        class="avatar-uploader">
        <img v-if="temp.itemImg" :src="fileBefore + temp.itemImg" class="avatar">
        <i v-else class="el-icon-plus avatar-uploader-icon"/>
      </el-upload>
    </el-form-item>
  </el-col>
</el-row>

/**
 * 上传成功处理
 */
uploadSuccess(res, file) {
  this.temp.itemImg = res
  this.$notify({
    title: '成功',
    message: '图片上传成功',
    type: 'success',
    duration: 1000
  })
},
/**
 * 上传错误处理
 */
uploadError() {
  this.$message.error('上传失败,请重新上传')
},
/**
 * 上传前置处理
 */
beforeUpload(file) {
  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isLt2M) {
    this.$message.error('上传图片大小不能超过 2MB!')
  }
},

4.7、详情富文本编辑

 <el-row :gutter="20">
  <el-col :span="24">
    <el-form-item label="医院详情" label-width="105px" prop="orgContent">
      <tinymce :custom-modal="editModal" :upload-url="uploadUrl" :height="300" v-model="temp.orgContent"
               :reset="!dialogFormVisible"/>
    </el-form-item>
  </el-col>
</el-row>

import Tinymce from '@/components/Tinymce'
export default {
  directives: {waves},
  components: {Pagination, Tinymce},
<import src="../../../wxParse/wxParse.wxml"></import>
<block wx:if="{{productInfo.productDesc}}">
    <view class='good-desc'>
        <template is="wxParse" data="{{wxParseData:goodDesc.nodes}}"></template>
    </view>
</block>

//商品详情
if (data.productDesc) {
    WxParse.wxParse("goodDesc", "html", data.productDesc, that, 20);
}

问题记录

发布线上图标不显示
修改一下webpack.base.conf.js的limit

{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  loader: 'url-loader',
  options: {
    limit: 100000,
    name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
  }
}

参考:https://www.cnblogs.com/guobin-/p/16288255.html

08-13 08:19