<repo_name>clockknock/CRM<file_sep>/src/org/itheima/crm/domain/PageBean.kt
package org.itheima.crm.domain

import org.itheima.crm.dao.impl.CustomerDaoImpl

/**
 * Created by 钟未鸣 on 2017/9/11 .
 */
//data class PageBean(var pageSize:Int?,var currentPage:Int?,var totalPage:Int?,var datas:List<T>)
class PageBean<T> {

    var currentPage: Int = 0// 当前页：1开始
    var totalPage: Int = 0// 总页数
    var totalCount: Long = 0// 总条数
    var pageSize: Int = 0// 每页显示的条数
    var datas: List<T>? = null

    override fun toString(): String {
        return "PageBean(currentPage=$currentPage, totalPage=$totalPage, totalCount=$totalCount, pageSize=$pageSize, datas=$datas)"
    }


}
<file_sep>/src/org/itheima/crm/dao/LinkmanDao.kt
package org.itheima.crm.dao

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.domain.Linkman

/**
 * Created by 钟未鸣 on 2017/9/13 .
 */
interface LinkmanDao {
    fun save(linkman: Linkman)
    fun totalCount(criteria: DetachedCriteria): Long
    fun findList(criteria: DetachedCriteria, start: Int, pageSize: Int): List<Linkman>
}<file_sep>/src/org/itheima/crm/utils/UploadUtil.kt
package org.itheima.crm.utils

import java.util.*

/**
 * Created by 钟未鸣 on 2017/9/11 .
 */
object UploadUtil{

    fun genUploadPath(imageUpLoadFileName: String):String{
        val sb = StringBuffer()
        val calendar = Calendar.getInstance()
        sb.append("/")
        sb.append(calendar.get(Calendar.YEAR))
        sb.append("/")
        sb.append(calendar.get(Calendar.MONTH)+1)
        sb.append("/")
        sb.append(calendar.get(Calendar.DAY_OF_MONTH))
        sb.append("/")
        sb.append(calendar.get(Calendar.HOUR_OF_DAY))
        sb.append("/")
        val suffix=imageUpLoadFileName.substring(imageUpLoadFileName.lastIndexOf("."))
        sb.append(UUID.randomUUID())
        sb.append(suffix)
        return sb.toString().replace("-","")

//        return sb.toString()
    }
}<file_sep>/src/org/itheima/crm/dao/impl/DictDaoImpl.kt
package org.itheima.crm.dao.impl

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.dao.DictDao
import org.itheima.crm.domain.BaseDict
import org.springframework.orm.hibernate5.support.HibernateDaoSupport

/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
class DictDaoImpl : DictDao,HibernateDaoSupport() {
    override fun findList(criteria: DetachedCriteria): List<BaseDict> {

        @Suppress("UNCHECKED_CAST")
        return hibernateTemplate.findByCriteria(criteria) as List<BaseDict>
    }

    override fun save(dict: BaseDict) {
        hibernateTemplate.save(dict)
    }
}<file_sep>/src/org/itheima/crm/web/interceptor/LoginInterceptor.kt
package org.itheima.crm.web.interceptor

import com.opensymphony.xwork2.ActionInvocation
import com.opensymphony.xwork2.interceptor.AbstractInterceptor
import org.apache.struts2.ServletActionContext
import org.itheima.crm.web.action.UserAction

/**
 * Created by 钟未鸣 on 2017/9/10 .
 * 登录拦截器
 */
class LoginInterceptor: AbstractInterceptor(){
    private val NEEDLOGIN="needLogin"

    override fun intercept(invocation: ActionInvocation?): String {
        //如果是UserAction,放行
        val action = invocation?.action
        if(action is UserAction){
            return invocation.invoke()
        }
        val user = ServletActionContext.getRequest().session.getAttribute("user")
        if(user !=null){
            //已经登录,放行
            if (invocation != null) {
                return invocation.invoke()
            }
        }
        return NEEDLOGIN
    }

}<file_sep>/src/org/itheima/crm/service/LinkmanService.kt
package org.itheima.crm.service

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.domain.Linkman
import org.itheima.crm.domain.PageBean

/**
 * Created by 钟未鸣 on 2017/9/13 .
 */
interface LinkmanService {
    fun save(linkman: Linkman)
    fun findPage(criteria: DetachedCriteria, currentPage: Int, pageSize: Int): PageBean<Linkman>
}<file_sep>/src/org/itheima/crm/web/action/UserAction.kt
package org.itheima.crm.web.action

import cn.dsna.util.images.ValidateCode
import com.opensymphony.xwork2.ActionSupport
import com.opensymphony.xwork2.ModelDriven
import org.apache.struts2.interceptor.ServletRequestAware
import org.itheima.crm.domain.User
import org.itheima.crm.service.UserService
import org.springframework.util.StringUtils
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.InputStream
import javax.servlet.http.HttpServletRequest

/**
 * Created by 钟未鸣 on 2017/9/8 .
 * userAction
 */
class UserAction : ActionSupport(), ModelDriven<User>, ServletRequestAware {
    private val LOGIN_SUCCESS = "loginSuccess"
    private val LOGIN_ERROR = "loginError"
    private val VALIDATECODE_SUCCESS = "validateCodeSuccess"
    private val LOGOUT_SUCCESS = "logoutSuccess"

    private var request: HttpServletRequest? = null
    override fun setServletRequest(request: HttpServletRequest?) {
        this.request = request
    }

    private var imageStream: InputStream? = null
    @Suppress("unused")
    fun getImageStream(): InputStream? {
        return imageStream
    }

    private var user: User? = null
    private var userService: UserService? = null
    fun setUserService(service: UserService) {
        this.userService = service
    }

    override fun getModel(): User {
        if (user == null) {
            user = User()
        }
        return user as User
    }

    @Suppress("unused")
    fun do_login(): String {
        if (StringUtils.isEmpty(user!!.userCode)) {
            addFieldError("userCode", "用户名不能为空")
            return LOGIN_ERROR
        }

        if (StringUtils.isEmpty(user!!.userPassword)) {
            addFieldError("userPassword", "密码不能为空")
            return LOGIN_ERROR
        }

        if (StringUtils.isEmpty(user!!.validateCode)) {
            addFieldError("validateCode", "验证码不能为空")
            return LOGIN_ERROR
        }

        /*  TODO 先不填验证码了
        val validateCode = request!!.session.getAttribute("validateCode") as String

          if(StringUtils.isEmpty(validateCode)){
              addFieldError("validateCode","无法刷新验证码")
              return LOGIN_ERROR
          }

          if(!validateCode.equals(user!!.validateCode,true)){
              addFieldError("validateCode","验证码错误")
              return LOGIN_ERROR
          }*/

        val loginUser: User = userService?.login(user!!) ?: return LOGIN_ERROR
        val session = request!!.session
        session.setAttribute("user", loginUser)
        return LOGIN_SUCCESS
    }

    @Suppress("unused")
    fun do_validateCode(): String {
        val code = ValidateCode(130, 28, 4, 4)
        request!!.session.setAttribute("validateCode", code.code)
        imageStream = code.getInputStream()
        return VALIDATECODE_SUCCESS
    }

    @Suppress("unused")
    fun do_logout(): String {
        request!!.session.removeAttribute("user")

        return LOGOUT_SUCCESS
    }

}

fun ValidateCode.getInputStream(): InputStream? {
    var baos: ByteArrayOutputStream? = null
    var bais: ByteArrayInputStream? = null
    try {
        baos = ByteArrayOutputStream()
        this.write(baos)
        bais = ByteArrayInputStream(baos.toByteArray())
    } catch (e: Exception) {

        e.printStackTrace()
    } finally {
        if (baos != null) {
            try {
                baos.close()
            } catch (e: Exception) {

                e.printStackTrace()
            }
            @Suppress("UNUSED_VALUE")
            baos = null
        }
    }
    return bais

}<file_sep>/src/org/itheima/crm/service/UserService.kt
package org.itheima.crm.service

import org.itheima.crm.domain.User

/**
 * Created by 钟未鸣 on 2017/9/8 .
 */
interface UserService{
    fun save(user: User)
    fun login(user: User): User ?
}<file_sep>/src/org/itheima/crm/web/action/CustomerAction.kt
package org.itheima.crm.web.action

import com.opensymphony.xwork2.ActionContext
import com.opensymphony.xwork2.ActionSupport
import com.opensymphony.xwork2.ModelDriven
import org.hibernate.criterion.DetachedCriteria
import org.hibernate.criterion.Restrictions
import org.itheima.crm.domain.BaseDict
import org.itheima.crm.domain.Customer
import org.itheima.crm.service.CustomerService
import org.itheima.crm.service.DictService
import org.itheima.crm.utils.PropertyPlaceholder
import org.itheima.crm.utils.UploadUtil
import org.springframework.util.StringUtils
import java.io.File

/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
class CustomerAction : ActionSupport(), ModelDriven<Customer> {
    private val SAVESUCCESS = "saveSuccess"
    private val SAVEERROR = "saveError"
    private val RESULTDICTSUCCESS = "resultDictSuccess"
    private val LISTSUCCESS = "listSuccess"
    private val EDITSUCCESS = "editSuccess"
    private val UPDATESUCCESS = "updateSuccess"
    private val UPDATEERROR = "updateError"
    private val DELETESUCCESS = "deleteSuccess"


    private var imageUpLoad: File? = null
    private var imageUpLoadContentType: String? = null
    private var imageUpLoadFileName: String? = null

    private var imgDir: String? = PropertyPlaceholder.getProperty("file.upload.dir")
    @Suppress("unused")
    fun setImageUpLoad(imageUpLoad: File) {
        this.imageUpLoad = imageUpLoad
    }

    @Suppress("unused")
    fun setImageUpLoadContentType(contentType: String) {
        this.imageUpLoadContentType = contentType
    }

    @Suppress("unused")
    fun setImageUpLoadFileName(fileName: String) {
        this.imageUpLoadFileName = fileName
    }


    private var dicts: ArrayList<*>? = null
    private fun setDicts(dicts: ArrayList<*>) {
        this.dicts = dicts
    }

    @Suppress("unused")
    fun getDicts(): ArrayList<*>? {
        return dicts
    }

    private var dictTypeCode: String? = null
    @Suppress("unused")
    fun setDictTypeCode(code: String) {
        dictTypeCode = code
    }

    private var currentPage: Int = 1
    @Suppress("unused")
    fun setCurrentPage(currentPage: Int) {
        this.currentPage = currentPage
    }

    private var pageSize: Int = 5
    @Suppress("unused")
    fun setPageSize(pageSize: Int) {
        this.pageSize = pageSize
    }

    private var customer: Customer? = null
    override fun getModel(): Customer {
        if (customer == null) {
            customer = Customer()

        }
        return customer as Customer
    }

    private var customerService: CustomerService? = null
    fun setCustomerService(customerService: CustomerService) {
        this.customerService = customerService
    }

    private var dictService: DictService? = null
    fun setDictService(dictService: DictService) {
        this.dictService = dictService
    }

    override fun hasErrors(): Boolean {
        return false
    }



    /**
     * Action
     * 操
     * 作
     */

    @Suppress("unused")
    fun do_save(): String {

        if (checkCustomerDataHasError(customer!!)) {
            return SAVEERROR
        }
        //处理文件上传


        if (StringUtils.isEmpty(imageUpLoadFileName)) {
            addActionError("未选择资质图片")
        } else {
            uploadImg()
        }

        customerService!!.saveCustomer(customer!!)
        return SAVESUCCESS
    }


    @Suppress("unused")
    fun do_dict(): String {
        try {
            val criteria = DetachedCriteria.forClass(BaseDict::class.java)
            criteria.add(Restrictions.eq("dictTypeCode", dictTypeCode))
            val findList = dictService!!.findList(criteria)
            setDicts(findList as ArrayList<BaseDict>)
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return RESULTDICTSUCCESS
    }


    @Suppress("unused")
    fun do_list(): String {
        val stack = ActionContext.getContext().valueStack
        var criteria = DetachedCriteria.forClass(Customer::class.java)

        criteria = handleQueryCriteria(customer!!, criteria)

        val pageBean = customerService!!.findBean(criteria, currentPage, pageSize)

        stack.push(pageBean)

        return LISTSUCCESS
    }

    /**
     * 通过id获取customer数据进入edit界面
     */
    @Suppress("unused")
    fun do_edit(): String {
        val findCust: Customer = customerService!!.findById(customer!!.custId!!)
        val stack = ActionContext.getContext().valueStack
        stack.push(findCust)
        return EDITSUCCESS
    }

    @Suppress("unused")
    fun do_update(): String {
        val hasError = checkCustomerDataHasError(customer!!)
        if (hasError) {
            return UPDATEERROR
        }
        if(imageUpLoad==null){
            addActionError("图片不能为空!")
            return UPDATEERROR
        }
        uploadImg()

        customerService!!.update(customer!!)
        return UPDATESUCCESS
    }

    @Suppress("unused")
    fun do_delete(): String{
        val find = customerService!!.findById(customer!!.custId!!)
        customerService!!.delete(find)

      /*不删图片
      val image = File(imgDir, find.cstImage)
        if(image.exists()){
            val delete = image.delete()
            println("delete:$delete")
        }*/

        return DELETESUCCESS
    }


    /**
     * 抽
     * 取
     * 的
     * 方
     * 法
     */

    /**
     * 校验customer的数据有没有错误,以决定返回resultType
     * @return true 有错误   false没错误
     */
    private fun checkCustomerDataHasError(customer: Customer): Boolean {
        if (StringUtils.isEmpty(customer.custName)) {
            addActionError("客户名不能为空")
            return true
        }

        if (StringUtils.isEmpty(customer.custPhone)) {
            addActionError("固定电话不能为空")
            return true
        }

        if (StringUtils.isEmpty(customer.custMobile)) {
            addActionError("移动电话不能为空")
            return true
        }

        //cstLevel为空或其id为0
        if (customer.cstLevel == null || customer.cstLevel?.dictId ==
                0L) {
            addActionError("客户级别不能为空")
            return true
        }

        //cstIndustry为空或其id为0
        if (customer.custIndustry == null || customer.custIndustry?.dictId ==
                0L) {
            addActionError("所属行业不能为空")
            return true
        }

        //cstSource为空或其id为0
        if (customer.custSource == null || customer.custSource?.dictId ==
                0L) {
            addActionError("信息来源不能为空")
            return true
        }


        return false
    }

    /**
     * 校验customer的数据添加criteria
     * @return 添加了新约束的criteria
     */
    private fun handleQueryCriteria(customer: Customer, criteria: DetachedCriteria): DetachedCriteria {
        if (!StringUtils.isEmpty(customer.custName)) {
            criteria.add(Restrictions.like("custName", "%${customer.custName}%"))
        }

        if (!StringUtils.isEmpty(customer.custPhone)) {
            criteria.add(Restrictions.like("custPhone", "%${customer.custPhone}%"))

        }

        if (!StringUtils.isEmpty(customer.custMobile)) {
            criteria.add(Restrictions.like("custMobile", "%${customer.custMobile}%"))
        }

        //cstLevel为空或其id为0
        if (customer.cstLevel != null && customer.cstLevel?.dictId != 0L) {
            criteria.add(Restrictions.eq("cstLevel.dictId", customer.cstLevel!!.dictId))
        }

        //cstIndustry为空或其id为0
        if (customer.custIndustry != null && customer.custIndustry?.dictId !=
                0L) {
            criteria.add(Restrictions.eq("custIndustry.dictId", customer.custIndustry!!.dictId))
        }

        //cstSource为空或其id为0
        if (customer.custSource != null && customer.custSource?.dictId !=
                0L) {
            criteria.add(Restrictions.eq("custSource.dictId", customer.custSource!!.dictId))
        }

        return criteria
    }

    private fun uploadImg() {
        val subPath = UploadUtil.genUploadPath(imageUpLoadFileName!!)
        imgDir += subPath
        val file = File(imgDir)
        if (!file.exists()) {
            file.mkdirs()
        }
        imageUpLoad?.copyTo(file, true)

        customer!!.cstImage = subPath
    }

}<file_sep>/src/org/itheima/crm/service/impl/CustomerServiceImpl.kt
package org.itheima.crm.service.impl

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.dao.CustomerDao
import org.itheima.crm.dao.impl.CustomerDaoImpl
import org.itheima.crm.domain.Customer
import org.itheima.crm.domain.PageBean
import org.itheima.crm.service.CustomerService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.transaction.annotation.Transactional

/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
@Transactional
open class CustomerServiceImpl : CustomerService {
    override fun findList(): ArrayList<Customer> {
        val criteria = DetachedCriteria.forClass(Customer::class.java)
        return customerDao.findList(criteria,0,0) as ArrayList<Customer>

    }

//    private var customerDao: CustomerDao? = null


    override fun delete(customer: Customer) {
        customerDao.delete(customer)
    }

    fun setCustomerDao(customerDao: CustomerDao){
        this.customerDao =customerDao
    }

    override fun update(customer: Customer) {
         customerDao.update(customer)
    }

    override fun findById(custId: Long): Customer {
        return customerDao.findById(custId)
    }

    override fun findBean(criteria: DetachedCriteria, currentPage: Int, pageSize: Int): PageBean<Customer> {
        val pageBean = PageBean<Customer>()
        val totalCount = customerDao.totalCount(criteria)
        criteria.setProjection(null)
        val start = (currentPage - 1) * pageSize
        pageBean.datas = customerDao.findList(criteria,start, pageSize)
        pageBean.totalCount = totalCount
        pageBean.currentPage = currentPage
        pageBean.pageSize = pageSize
        pageBean.totalPage = (totalCount * 1.0 /pageSize).toInt()
        return pageBean
    }

    override fun totalCount(criteria: DetachedCriteria): Long {
        return customerDao.totalCount(criteria)
    }

//    override fun findList(criteria: DetachedCriteria): List<Customer> {
//        return customerDao?.findList(criteria)!!
//    }


    override fun saveCustomer(customer: Customer) {
        println(customer)
        customerDao.saveCustomer(customer)
    }

      private lateinit var customerDao: CustomerDao
}<file_sep>/src/org/itheima/crm/dao/CustomerDao.kt
package org.itheima.crm.dao

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.domain.Customer

/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
interface CustomerDao {
    fun saveCustomer(customer: Customer)
    fun findList(criteria: DetachedCriteria, start: Int, end: Int): List<Customer>
    fun totalCount(criteria: DetachedCriteria): Long
    fun findById(custId: Long): Customer
    fun update(customer: Customer)
    fun delete(customer: Customer)
}<file_sep>/web/js/addOptions.js
/**
 * Created by zhong on 2017/9/13.
 */

function addOptions(typeCode, selectId) {
    var url = "${pageContext.request.contextPath}/customer/dict.action";
    var data = {"dictTypeCode": typeCode};
    var callback = function (dicts) {
        $(dicts).each(function (i, dict) {
            var idSelector = "#" + selectId;
            var idData = "#" + selectId + "_data";
            idData = $(idData).attr("data");
            console.log(idData);
            //处理数据回显的判断
            if (idData == dict.dictId) {
                $(idSelector).append("<option value='" + dict.dictId +
                    "' selected='selected'>" +
                    dict.dictItemName +
                    "</option>")
            } else {
                $(idSelector).append("<option value='" + dict.dictId + "' >" +
                    dict.dictItemName +
                    "</option>")
            }
        })
    };
    var type = "json";
    $.post(url, data, callback, type)
}


<file_sep>/README.md
# CRM

基于黑马程序员JavaEE课程的CRM小练习
<file_sep>/src/org/itheima/crm/domain/BaseDict.kt
package org.itheima.crm.domain

/**
 * Created by 钟未鸣 on 2017/9/10 .
private long dictId;
private String dictTypeCode;
private String dictTypeName;
private String dictItemName;
private String dictItemCode;
private Integer dictSort;
private Integer dictState;
private String dictComment;
 */
data class BaseDict(var dictId: Long?, var dictTypeCode: String?, var dictTypeName: String?, var
dictItemName: String?,
               var dictItemCode: String?, var dictSort: Int?, var dictState: Int?, var
               dictComment: String?) {
    constructor() : this(null, null, null, null, null, null, null, null)

}<file_sep>/src/org/itheima/crm/utils/PropertyPlaceHolder.kt
package org.itheima.crm.utils

import org.springframework.beans.BeansException
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
import java.util.*
import java.util.HashMap

/**
 * Created by 钟未鸣 on 2017/9/11 .
 */
object PropertyPlaceholder : PropertyPlaceholderConfigurer() {
    private var propertyMap: Map<String, String>? = null

     override fun processProperties(beanFactoryToProcess: ConfigurableListableBeanFactory, props: Properties) {

        super.processProperties(beanFactoryToProcess, props)
        propertyMap = HashMap()
        for ((key,value) in props) {
            (propertyMap as HashMap<String, String>).put(key as String, value as String)
        }
    }

    // static method for accessing context properties
    fun getProperty(name: String): String {
        return propertyMap!![name]!!
    }
}<file_sep>/src/org/itheima/crm/service/CustomerService.kt
package org.itheima.crm.service

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.domain.Customer
import org.itheima.crm.domain.PageBean

/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
interface CustomerService {
    fun saveCustomer(customer: Customer)
//    fun findList(criteria: DetachedCriteria): List<Customer>
    fun totalCount(criteria: DetachedCriteria): Long
    fun findBean(criteria: DetachedCriteria, currentPage: Int, pageSize: Int): PageBean<Customer>
    fun findById(custId: Long): Customer
    fun update(customer: Customer)
    fun delete(customer: Customer)
    fun findList(): ArrayList<Customer>

}<file_sep>/src/org/itheima/crm/service/impl/DictServiceImpl.kt
package org.itheima.crm.service.impl

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.dao.DictDao
import org.itheima.crm.domain.BaseDict
import org.itheima.crm.service.DictService
import org.springframework.transaction.annotation.Transactional

/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
@Transactional
open class DictServiceImpl : DictService{
    private var dictDao : DictDao?= null
    fun setDictDao(dictDao: DictDao){
        this.dictDao  = dictDao
    }
    override fun save(dict: BaseDict) {
        dictDao?.save(dict)
    }

    override fun findList(criteria: DetachedCriteria): List<BaseDict>? {
        return dictDao?.findList(criteria)
    }

}<file_sep>/src/org/itheima/crm/dao/impl/CustomerDaoImpl.kt
package org.itheima.crm.dao.impl

import org.hibernate.criterion.DetachedCriteria
import org.hibernate.criterion.Projections
import org.itheima.crm.dao.CustomerDao
import org.itheima.crm.domain.Customer
import org.springframework.orm.hibernate5.support.HibernateDaoSupport

/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
class CustomerDaoImpl : CustomerDao,HibernateDaoSupport() {


    override fun delete(customer: Customer) {
        hibernateTemplate.delete(customer)
    }

    override fun update(customer: Customer) {
        hibernateTemplate.update(customer)
    }

    override fun findById(custId: Long): Customer {
        return hibernateTemplate.get(Customer::class.java,custId)
    }

    override fun totalCount(criteria: DetachedCriteria): Long {
        criteria.setProjection(Projections.rowCount())
        return hibernateTemplate.findByCriteria(criteria)[0] as Long
    }

    override fun findList(criteria: DetachedCriteria, start: Int, end: Int): List<Customer> {
        @Suppress("UNCHECKED_CAST")
        if(start==0 && end ==0){
            return hibernateTemplate.findByCriteria(criteria) as List<Customer>
        }
        return hibernateTemplate.findByCriteria(criteria,start,end) as List<Customer>
    }

    override fun saveCustomer(customer: Customer) {
        hibernateTemplate.save(customer)
    }
}<file_sep>/src/org/itheima/crm/service/DictService.kt
package org.itheima.crm.service

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.domain.BaseDict

/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
interface DictService{
    fun save(dict: BaseDict)
    fun findList(criteria: DetachedCriteria) : List<BaseDict>?
}<file_sep>/src/test/itheima/crm/TestLinkman.kt
package test.itheima.crm

import org.itheima.crm.domain.Linkman
import org.itheima.crm.service.CustomerService
import org.itheima.crm.service.LinkmanService
import org.itheima.crm.service.impl.CustomerServiceImpl
import org.itheima.crm.service.impl.LinkmanServiceImpl
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner

/**
 * Created by 钟未鸣 on 2017/9/13 .
 */
@RunWith(SpringJUnit4ClassRunner::class)
@ContextConfiguration("classpath:applicationContext.xml")
class TestLinkman{
    @Autowired lateinit var linkmanService: LinkmanService
    @Autowired lateinit var customerService: CustomerService

    @Test
    fun testSave(){
        val findById = customerService.findById(11)
        val linkman = Linkman()
        linkman.customer = findById
        linkman.lkmMobile="133"
        linkman.lkmName="zs"
        linkman.lkmEmail="<EMAIL>"
        linkmanService.save(linkman)
    }


}
<file_sep>/src/org/itheima/crm/service/impl/LinkmanServiceImpl.kt
package org.itheima.crm.service.impl

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.dao.LinkmanDao
import org.itheima.crm.dao.LinkmanDaoImpl
import org.itheima.crm.domain.Linkman
import org.itheima.crm.domain.PageBean
import org.itheima.crm.service.LinkmanService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.transaction.annotation.Transactional

/**
 * Created by 钟未鸣 on 2017/9/13 .
 */
@Transactional
open class LinkmanServiceImpl : LinkmanService{
    override fun findPage(criteria: DetachedCriteria, currentPage: Int, pageSize: Int): PageBean<Linkman> {
        val pageBean = PageBean<Linkman>()
        pageBean.pageSize =pageSize
        pageBean.currentPage = currentPage
        val totalCount = linkmanDao.totalCount(criteria)
        pageBean.totalCount = totalCount
        val start = (currentPage -1) * pageSize
        pageBean.datas = linkmanDao.findList(criteria,start,pageSize)

        pageBean.totalPage = (totalCount * 1.0 / pageSize).toInt()

        return pageBean
    }

    override fun save(linkman: Linkman) {
        linkmanDao.save(linkman)
    }

    @Autowired lateinit var linkmanDao: LinkmanDao

}<file_sep>/src/org/itheima/crm/dao/DictDao.kt
package org.itheima.crm.dao

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.domain.BaseDict

/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
interface DictDao{
    fun save(dict: BaseDict)
    fun findList(criteria: DetachedCriteria) : List<BaseDict>
}<file_sep>/src/org/itheima/crm/domain/Customer.kt
package org.itheima.crm.domain

/**
 * Created by 钟未鸣 on 2017/9/10 .
private long custId;
private String custName;
private String custPhone;
private String custMobile;
private String cstImage;
private BaseDict custSource;
private BaseDict custIndustry;
private BaseDict cstLevel;
 */
data class Customer(var custId: Long?, var custName: String?, var custPhone: String?, var
custMobile:
String?, var cstImage: String?, var custSource: BaseDict?, var custIndustry: BaseDict?, var
               cstLevel: BaseDict?) {
    constructor() : this(null, null, null, null, null, null, null, null)
}<file_sep>/src/test/itheima/crm/TestCRM.kt
package test.itheima.crm

import org.itheima.crm.domain.User
import org.itheima.crm.service.UserService
import org.itheima.crm.utils.MD5Util
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner

/**
 * Created by 钟未鸣 on 2017/9/8.
 */
@RunWith(SpringJUnit4ClassRunner::class)
@ContextConfiguration("classpath:applicationContext.xml")
class TestCRM {

    @Autowired
    private var userService:UserService? = null

    @Test fun testAdd(){
        val user=User(null,"admin","admin","123",1,null)
        userService!!.save(user)
    }

    @Test fun testMd5(){
        val md5 = MD5Util.deafultMd5("123")
        println(md5)
    }

    @Test fun testLogin(){

        val user = User()
        user.userCode="admin"
        user.userPassword="123"
        val loginUser = userService?.login(user)
        println(loginUser)
    }

    @Test fun testStringEquals(){
        var s1 = "1a"
        var s2 = "1A"
        println(s1.equals(s2,true))
    }
}<file_sep>/src/org/itheima/crm/utils/MD5Util.kt
package org.itheima.crm.utils

import org.springframework.util.DigestUtils

/**
 * Created by 钟未鸣 on 2017/9/8 .
 */
object MD5Util{
    fun deafultMd5(msg: String): String{
        return md5(msg,5)
    }

    fun md5(msg: String): String {
        return DigestUtils.md5DigestAsHex(msg.byteInputStream())
    }

    /**
     * 加密多次
     *
     * @param password
     * @param count
     * @return
     */
    private fun md5(password: String, count: Int): String {
        @Suppress("NAME_SHADOWING")
        var password = <PASSWORD>
        for (i in 0 until count) {
            password = md5(password)
        }
        return password
    }
}<file_sep>/src/org/itheima/crm/dao/impl/UserDaoImpl.kt
package org.itheima.crm.dao.impl

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.dao.UserDao
import org.itheima.crm.domain.User
import org.itheima.crm.utils.MD5Util
import org.springframework.orm.hibernate5.support.HibernateDaoSupport
import org.springframework.transaction.annotation.Transactional

/**
* Created by 钟未鸣 on 2017/9/8 .
*/
open class UserDaoImpl : UserDao,HibernateDaoSupport() {
    override fun login(criteria: DetachedCriteria): MutableList<*>? {
       return hibernateTemplate.findByCriteria(criteria)

    }

    override fun save(user: User) {
        user.userPassword=MD5Util.<PASSWORD>(user.userPassword!!)
        hibernateTemplate.save(user)
    }
}<file_sep>/src/test/itheima/crm/TestBaseDictService.kt
package test.itheima.crm

import org.hibernate.Criteria
import org.hibernate.criterion.DetachedCriteria
import org.hibernate.criterion.Restrictions
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
import org.itheima.crm.domain.BaseDict
import org.itheima.crm.service.DictService
import org.springframework.beans.factory.annotation.Autowired


/**
 * Created by 钟未鸣 on 2017/9/10 .
 */
@RunWith(SpringJUnit4ClassRunner::class)
@ContextConfiguration("classpath:applicationContext.xml")
class  TestBaseDictService{
    @Autowired
    private var service: DictService?=null

    @Test fun testFindList(){
        val criteria = DetachedCriteria.forClass(BaseDict::class.java)
        criteria.add(Restrictions.eq("dictTypeCode","001"))
        val list = service!!.findList(criteria)
        if (list != null) {
            for(dict in list){
                println(dict)
            }
        }
    }

    @Test fun testSave(){
        service!!.save(BaseDict(null, "001", "客户行业", "教育培训 ", null, 1, 1, null))
        service!!.save(BaseDict(null, "001", "客户行业", "电子商务", null, 2, 1, null))
        service!!.save(BaseDict(null, "001", "客户行业", "对外贸易", null, 3, 1, null))
        service!!.save(BaseDict(null, "001", "客户行业", "酒店旅游", null, 4, 1, null))
        service!!.save(BaseDict(null, "001", "客户行业", "房地产", null, 5, 1, null))
        service!!.save(BaseDict(null, "002", "客户信息来源", "电话营销", null, 1, 1, null))
        service!!.save(BaseDict(null, "002", "客户信息来源", "网络营销", null, 2, 1, null))
        service!!.save(BaseDict(null, "003", "公司性质", "合资", null, 1, 1, null))
        service!!.save(BaseDict(null, "003", "公司性质", "国企", null, 2, 1, null))
        service!!.save(BaseDict(null, "003", "公司性质", "民企", null, 3, 1, null))
        service!!.save(BaseDict(null, "004", "年营业额", "1-10万", null, 1, 1, null))
        service!!.save(BaseDict(null, "004", "年营业额", "10-20万", null, 2, 1, null))
        service!!.save(BaseDict(null, "004", "年营业额", "20-50万", null, 3, 1, null))
        service!!.save(BaseDict(null, "004", "年营业额", "50-100万", null, 4, 1, null))
        service!!.save(BaseDict(null, "004", "年营业额", "100-500万", null, 5, 1, null))
        service!!.save(BaseDict(null, "004", "年营业额", "500-1000万", null, 6, 1, null))
        service!!.save(BaseDict(null, "005", "客户状态", "基础客户", null, 1, 1, null))
        service!!.save(BaseDict(null, "005", "客户状态", "潜在客户", null, 2, 1, null))
        service!!.save(BaseDict(null, "005", "客户状态", "成功客户", null, 3, 1, null))
        service!!.save(BaseDict(null, "005", "客户状态", "无效客户", null, 4, 1, null))
        service!!.save(BaseDict(null, "006", "客户级别", "普通客户", null, 1, 1, null))
        service!!.save(BaseDict(null, "006", "客户级别", "VIP客户", null, 2, 1, null))
        service!!.save(BaseDict(null, "007", "商机状态", "意向客户", null, 1, 1, null))
        service!!.save(BaseDict(null, "007", "商机状态", "初步沟通", null, 2, 1, null))
        service!!.save(BaseDict(null, "007", "商机状态", "深度沟通", null, 3, 1, null))
        service!!.save(BaseDict(null, "007", "商机状态", "签订合同", null, 4, 1, null))
        service!!.save(BaseDict(null, "008", "商机类型", "新业务", null, 1, 1, null))
        service!!.save(BaseDict(null, "008", "商机类型", "现有业务", null, 2, 1, null))
        service!!.save(BaseDict(null, "009", "商机来源", "电话营销", null, 1, 1, null))
        service!!.save(BaseDict(null, "009", "商机来源", "网络营销", null, 2, 1, null))
        service!!.save(BaseDict(null, "009", "商机来源", "推广活动", null, 3, 1, null))
    }
}<file_sep>/src/org/itheima/crm/web/action/LinkmanAction.kt
package org.itheima.crm.web.action

import com.opensymphony.xwork2.ActionContext
import com.opensymphony.xwork2.ActionSupport
import com.opensymphony.xwork2.ModelDriven
import org.hibernate.criterion.DetachedCriteria
import org.hibernate.criterion.Restrictions
import org.itheima.crm.domain.Linkman
import org.itheima.crm.service.CustomerService
import org.itheima.crm.service.LinkmanService
import org.springframework.beans.factory.annotation.Autowired

/**
 * Created by 钟未鸣 on 2017/9/13 .
 */
class LinkmanAction : ActionSupport(), ModelDriven<Linkman> {
    private var currentPage = 1
    private var pageSize = 10

    var linkman: Linkman? = null
    override fun getModel(): Linkman {
        if (linkman == null) {
            linkman = Linkman()
        }
        return linkman as Linkman
    }

    private val LISTSUCCESS = "listSuccess"
    private val ADDSUCCESS = "addSuccess"
    private val SAVESUCCESS = "saveSuccess"
    private val SAVEERROR = "saveError"

    override fun hasErrors(): Boolean {
        return false
    }

    @Suppress("unused")
    fun do_add(): String {
        val customers = customerService.findList()
        val stack = ActionContext.getContext().valueStack
        stack.set("customers", customers)
        return ADDSUCCESS
    }

    @Suppress("unused")
    fun do_list(): String {
        val criteria = DetachedCriteria.forClass(Linkman::class.java)

        //增加筛选条件
        criteria.addRestrictions(linkman!!)

        val pageBean =linkmanService.findPage(criteria, currentPage, pageSize)
        val stack = ActionContext.getContext().valueStack

        stack.push(pageBean)
        return LISTSUCCESS
    }

    @Suppress("unused")
    fun do_save(): String {
        val hasError: Boolean = checkLinkmanDataHasError()
        if (hasError) {
            return SAVEERROR
        }
        linkmanService.save(linkman!!)
        return SAVESUCCESS
    }

    /**
     * @return true:传过来的数据不齐全  false:传过来数据齐全
     */
    private fun checkLinkmanDataHasError(): Boolean {
        if (linkman!!.customer!!.custId == 0L) {
            addActionError("所属客户不能为空!")
            return true
        }

        if (linkman!!.lkmName.isNullOrEmpty()) {
            addActionError("联系人姓名不能为空!")
            return true
        }

        if (linkman!!.lkmPhone.isNullOrEmpty()) {
            addActionError("联系人办公电话不能为空!")
            return true
        }

        if (linkman!!.lkmMobile.isNullOrEmpty()) {
            addActionError("联系人手机不能为空!")
            return true
        }

        if (linkman!!.lkmEmail.isNullOrEmpty()) {
            addActionError("联系人邮箱不能为空!")
            return true
        }

        if (linkman!!.lkmQq.isNullOrEmpty()) {
            addActionError("联系人QQ不能为空!")
            return true
        }

        if (linkman!!.lkmPosition.isNullOrEmpty()) {
            addActionError("联系人职位不能为空!")
            return true
        }
        if (linkman!!.lkmComment.isNullOrEmpty()) {
            addActionError("联系人备注不能为空!")
            return true
        }

        return false
    }

    @Autowired private lateinit var linkmanService: LinkmanService
    @Autowired private lateinit var customerService: CustomerService
}

private fun DetachedCriteria.addRestrictions(linkman: Linkman) {
    val name = linkman.lkmName
    if(!name.isNullOrEmpty()){
        this.add(Restrictions.like("lkmName","%$name%"))
    }
    val lkmGender=linkman.lkmGender
    if(lkmGender!=0 && lkmGender!=null){
        this.add(Restrictions.eq("lkmGender",lkmGender))
    }
    val phone= linkman.lkmPhone
    if(!phone.isNullOrEmpty()){
        this.add(Restrictions.like("lkmPhone","%$phone%"))
    }
    val mobile= linkman.lkmMobile
    if(!mobile.isNullOrEmpty()){
        this.add(Restrictions.like("lkmMobile","%$mobile%"))
    }
    val email = linkman.lkmEmail
    if(!email.isNullOrEmpty()){
        this.add(Restrictions.like("lkmEmail","%$email%"))
    }
    val qq = linkman.lkmQq
    if(!qq.isNullOrEmpty()){
        this.add(Restrictions.like("lkmQq","%$qq%"))
    }

}
<file_sep>/src/org/itheima/crm/dao/LinkmanDaoImpl.kt
package org.itheima.crm.dao

import org.hibernate.criterion.DetachedCriteria
import org.hibernate.criterion.Projections
import org.itheima.crm.domain.Linkman
import org.springframework.orm.hibernate5.support.HibernateDaoSupport

/**
 * Created by 钟未鸣 on 2017/9/13 .
 */
class LinkmanDaoImpl : LinkmanDao,HibernateDaoSupport(){
    override fun findList(criteria: DetachedCriteria, start: Int, pageSize: Int): List<Linkman> {
        criteria.setProjection(null)
        @Suppress("UNCHECKED_CAST")
        return hibernateTemplate.findByCriteria(criteria,start,pageSize) as List<Linkman>
    }

    override fun totalCount(criteria: DetachedCriteria): Long {
        criteria.setProjection(Projections.rowCount())
        return hibernateTemplate.findByCriteria(criteria)[0] as Long
    }

    override fun save(linkman: Linkman) {
        hibernateTemplate.save(linkman)
    }

}<file_sep>/src/org/itheima/crm/service/impl/UserServiceImpl.kt
package org.itheima.crm.service.impl

import org.hibernate.criterion.DetachedCriteria
import org.hibernate.criterion.Restrictions
import org.itheima.crm.dao.UserDao
import org.itheima.crm.domain.User
import org.itheima.crm.service.UserService
import org.itheima.crm.utils.MD5Util
import org.springframework.transaction.annotation.Transactional

/**
 * Created by 钟未鸣 on 2017/9/8 .
 */
@Transactional
open class UserServiceImpl :UserService {
    private var userDao: UserDao? =null
    fun setUserDao(userDao: UserDao){
        this.userDao = userDao
    }

    override fun save(user: User) {
        userDao?.save(user)
    }

    override fun login(user: User): User? {
        val criteria = DetachedCriteria.forClass(User::class.java)
        user.userPassword=MD5Util.deafultMd5(user.userPassword!!)
        criteria.add(Restrictions.eq("userCode",user.userCode))
        criteria.add(Restrictions.eq("userPassword",user.userPassword))

        val users = userDao?.login(criteria)

        if(users==null || users.size==0  ){
            return null
        }
        return users[0] as User?
    }



}

<file_sep>/src/org/itheima/crm/domain/User.kt
package org.itheima.crm.domain

/**
 * Created by 钟未鸣 on 2017/9/8.
 */

data class User(var userId: Long?, var userCode: String?, var userName: String?,
                var userPassword: String?, var userState: Int?,var validateCode: String?) {
    constructor() :this(null,null,null,null,null,null)


}<file_sep>/src/org/itheima/crm/dao/UserDao.kt
package org.itheima.crm.dao

import org.hibernate.criterion.DetachedCriteria
import org.itheima.crm.domain.User

/**
 * Created by 钟未鸣 on 2017/9/8 .
 */
interface  UserDao {
    fun save(user: User)
    fun login(criteria: DetachedCriteria): MutableList<*>?
}<file_sep>/src/org/itheima/crm/domain/Linkman.kt
package org.itheima.crm.domain

/**
 * Created by 钟未鸣 on 2017/9/13 .
 */
class Linkman {
    var lkmId: Long = 0
    var lkmName: String? = null
    var lkmGender: Int? = null
    var lkmPhone: String? = null
    var lkmMobile: String? = null
    var lkmEmail: String? = null
    var lkmQq: String? = null
    var lkmPosition: String? = null
    var lkmComment: String? = null

    var customer:Customer? =null


    override fun toString(): String {
        return "Linkman(lkmId=$lkmId, lkmName=$lkmName, lkmGender=$lkmGender, lkmPhone=$lkmPhone, lkmMobile=$lkmMobile, lkmEmail=$lkmEmail, lkmQq=$lkmQq, lkmPosition=$lkmPosition, lkmComment=$lkmComment)"
    }


}
