first commit
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2023-2024 美天智能科技
|
||||
* @author 李志强
|
||||
* @link http://www.meteteme.com
|
||||
*/
|
||||
/**
|
||||
======================
|
||||
*模块数据获取公共文件
|
||||
======================
|
||||
*/
|
||||
use think\facade\Db;
|
||||
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2023-2024 美天智能科技
|
||||
* @name Index
|
||||
* @link http://www.meteteme.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\product\controller;
|
||||
|
||||
use app\base\BaseController;
|
||||
use app\model\Product as ProductList;
|
||||
use app\product\validate\ProductCheck;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
|
||||
class Index extends BaseController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$param = get_params();
|
||||
|
||||
$map1 = [
|
||||
['admin_id', '=', $this->uid],
|
||||
];
|
||||
$map2 = [
|
||||
['director_uid', '=', $this->uid],
|
||||
];
|
||||
$map3 = [
|
||||
['', 'exp', Db::raw("FIND_IN_SET({$this->uid},check_admin_ids)")],
|
||||
];
|
||||
$map4 = [
|
||||
['is_open', '=', 2],
|
||||
];
|
||||
|
||||
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$list = ProductList::withoutField('content,md_content')
|
||||
->where(function ($query) use ($map1, $map2, $map3, $map4) {
|
||||
$query->where($map1)->whereor($map2)->whereor($map3)->whereor($map4);
|
||||
})
|
||||
->where('delete_time', 0)
|
||||
->order('id desc')
|
||||
->paginate($rows, false, ['query' => $param])
|
||||
->each(function ($item, $key) {
|
||||
$item->is_own = Db::name('Product')->where('id', $item->id)->value('is_own');
|
||||
$item->director_name = Db::name('Admin')->where(['id' => $item->director_uid])->value('name');
|
||||
$item->admin_name = Db::name('Admin')->where(['id' => $item->admin_id])->value('name');
|
||||
$item->status_name = ProductList::$Status[(int) $item->status];
|
||||
$item->projects = Db::name('Project')->where(['delete_time' => 0, 'product_id' => $item->id])->count();
|
||||
|
||||
$project_ids = Db::name('Project')->where(['delete_time' => 0, 'product_id' => $item->id])->column('id');
|
||||
$task_map = [];
|
||||
$task_map[] = ['project_id', 'in', $project_ids];
|
||||
$task_map[] = ['delete_time', '=', 0];
|
||||
|
||||
//任务
|
||||
$task_map_a = $task_map;
|
||||
$task_map_a[] = ['is_bug', '=', 0];
|
||||
//任务总数
|
||||
$item->tasks_a_total = Db::name('Task')->where($task_map_a)->count();
|
||||
//已完成任务
|
||||
$task_map_a[] = ['flow_status', '>', 2]; //已完成
|
||||
$item->tasks_a_finish = Db::name('Task')->where($task_map_a)->count();
|
||||
//未完成任务
|
||||
$item->tasks_a_unfinish = $item->tasks_a_total - $item->tasks_a_finish;
|
||||
if ($item->tasks_a_total > 0) {
|
||||
$item->tasks_a_pensent = round($item->tasks_a_finish / $item->tasks_a_total * 100, 2) . "%";
|
||||
} else {
|
||||
$item->tasks_a_pensent = "100%";
|
||||
}
|
||||
|
||||
//缺陷
|
||||
$task_map_b = $task_map;
|
||||
$task_map_b[] = ['is_bug', '=', 1];
|
||||
//缺陷总数
|
||||
$item->tasks_b_total = Db::name('Task')->where($task_map_b)->count();
|
||||
//已完成缺陷
|
||||
$task_map_b[] = ['flow_status', '>', 2]; //已完成
|
||||
$item->tasks_b_finish = Db::name('Task')->where($task_map_b)->count();
|
||||
//未完成缺陷
|
||||
$item->tasks_b_unfinish = $item->tasks_b_total - $item->tasks_b_finish;
|
||||
if ($item->tasks_b_total > 0) {
|
||||
$item->tasks_b_pensent = round($item->tasks_b_finish / $item->tasks_b_total * 100, 2) . "%";
|
||||
} else {
|
||||
$item->tasks_b_pensent = "100%";
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
return table_assign(0, '', $list);
|
||||
} else {
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
//添加
|
||||
public function add()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isPost()) {
|
||||
//markdown数据处理
|
||||
if (isset($param['table-align'])) {
|
||||
unset($param['table-align']);
|
||||
}
|
||||
if (isset($param['docContent-html-code'])) {
|
||||
$param['content'] = $param['docContent-html-code'];
|
||||
$param['md_content'] = $param['docContent-markdown-doc'];
|
||||
unset($param['docContent-html-code']);
|
||||
unset($param['docContent-markdown-doc']);
|
||||
}
|
||||
if (isset($param['ueditorcontent'])) {
|
||||
$param['content'] = $param['ueditorcontent'];
|
||||
$param['md_content'] = '';
|
||||
}
|
||||
if (!empty($param['id']) && $param['id'] > 0) {
|
||||
$product = (new ProductList())->detail($param['id']);
|
||||
if ($this->uid == $product['admin_id'] || $this->uid == $product['director_uid']) {
|
||||
try {
|
||||
validate(ProductCheck::class)->scene('edit')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$param['update_time'] = time();
|
||||
$res = ProductList::where('id', $param['id'])->strict(false)->field(true)->update($param);
|
||||
if ($res) {
|
||||
add_log('edit', $param['id'], $param, $product);
|
||||
}
|
||||
return to_assign();
|
||||
} else {
|
||||
return to_assign(1, '只有创建人或者负责人才有权限编辑');
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
validate(ProductCheck::class)->scene('add')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$param['create_time'] = time();
|
||||
$param['admin_id'] = $this->uid;
|
||||
$sid = ProductList::strict(false)->field(true)->insertGetId($param);
|
||||
if ($sid) {
|
||||
add_log('add', $sid, $param);
|
||||
$log_data = array(
|
||||
'module' => 'product',
|
||||
'product_id' => $sid,
|
||||
'new_content' => $param['name'],
|
||||
'field' => 'new',
|
||||
'action' => 'add',
|
||||
'admin_id' => $this->uid,
|
||||
'create_time' => time(),
|
||||
);
|
||||
Db::name('Log')->strict(false)->field(true)->insert($log_data);
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
} else {
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
if ($id > 0) {
|
||||
$detail = (new ProductList())->detail($id);
|
||||
if (empty($detail)) {
|
||||
return to_assign(1, '产品不存在');
|
||||
}
|
||||
View::assign('detail', $detail);
|
||||
}
|
||||
View::assign('id', $id);
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
//查看
|
||||
public function view()
|
||||
{
|
||||
$param = get_params();
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
$detail = (new ProductList())->detail($id);
|
||||
if (empty($detail)) {
|
||||
return to_assign(1, '产品不存在');
|
||||
} else {
|
||||
$role_uid = [$detail['admin_id'], $detail['director_uid']];
|
||||
$role_edit = 'view';
|
||||
if (in_array($this->uid, $role_uid)) {
|
||||
$role_edit = 'edit';
|
||||
}
|
||||
$view_uid = $role_uid;
|
||||
if (!empty($detail['check_admin_ids'])) {
|
||||
$view_uid = array_merge($role_uid, explode(",", $detail['check_admin_ids']));
|
||||
}
|
||||
if (!in_array($this->uid, $view_uid) && $detail['is_open'] == 1) {
|
||||
return to_assign(1, '您没权限查看该产品');
|
||||
}
|
||||
$file_array = Db::name('FileInterfix')
|
||||
->field('i.id,i.topic_id,i.admin_id,f.name,f.filesize,f.filepath,a.name as admin_name')
|
||||
->alias('i')
|
||||
->join('File f', 'i.file_id = f.id', 'LEFT')
|
||||
->join('Admin a', 'i.admin_id = a.id', 'LEFT')
|
||||
->order('i.create_time desc')
|
||||
->where(array('i.topic_id' => $id, 'i.module' => 'product'))
|
||||
->select()->toArray();
|
||||
$link_array = Db::name('LinkInterfix')
|
||||
->field('i.id,i.topic_id,i.admin_id,i.desc,i.url,a.name as admin_name')
|
||||
->alias('i')
|
||||
->join('Admin a', 'i.admin_id = a.id', 'LEFT')
|
||||
->order('i.create_time desc')
|
||||
->where(array('i.topic_id' => $id, 'i.module' => 'product', 'delete_time' => 0))
|
||||
->select()->toArray();
|
||||
View::assign('detail', $detail);
|
||||
View::assign('file_array', $file_array);
|
||||
View::assign('link_array', $link_array);
|
||||
View::assign('role_edit', $role_edit);
|
||||
View::assign('id', $id);
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
//删除
|
||||
public function delete()
|
||||
{
|
||||
if (request()->isDelete()) {
|
||||
$id = get_params("id");
|
||||
$count = Db::name('Project')->where([['product_id', '=', $id], ['delete_time', '=', 0]])->count();
|
||||
if ($count > 0) {
|
||||
return to_assign(1, "该产品下有关联项目,无法删除");
|
||||
}
|
||||
$detail = Db::name('Product')->where('id', $id)->find();
|
||||
if ($detail['admin_id'] != $this->uid) {
|
||||
return to_assign(1, "你不是该产品的创建人,无权限删除");
|
||||
}
|
||||
if (Db::name('Product')->where('id', $id)->update(['delete_time' => time()]) !== false) {
|
||||
$log_data = array(
|
||||
'module' => 'product',
|
||||
'field' => 'delete',
|
||||
'action' => 'delete',
|
||||
'product_id' => $detail['id'],
|
||||
'admin_id' => $this->uid,
|
||||
'old_content' => '',
|
||||
'new_content' => $detail['name'],
|
||||
'create_time' => time(),
|
||||
);
|
||||
Db::name('Log')->strict(false)->field(true)->insert($log_data);
|
||||
return to_assign(0, "删除成功");
|
||||
} else {
|
||||
return to_assign(0, "删除失败");
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
// 这是系统自动生成的event定义文件
|
||||
return [
|
||||
|
||||
];
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2023-2024 美天智能科技
|
||||
* @author 李志强
|
||||
* @link http://www.meteteme.com
|
||||
*/
|
||||
|
||||
// 这是系统自动生成的middleware定义文件
|
||||
return [
|
||||
//开启session中间件
|
||||
//'think\middleware\SessionInit',
|
||||
\app\home\middleware\Install::class,
|
||||
];
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
namespace app\product\validate;
|
||||
use think\facade\Db;
|
||||
use think\Validate;
|
||||
|
||||
class ProductCheck extends Validate
|
||||
{
|
||||
// 自定义验证规则
|
||||
protected function checkOne($value,$rule,$data=[])
|
||||
{
|
||||
$count = Db::name('Product')->where(['name'=>$data['name'],'delete_time'=>0])->count();
|
||||
return $count == 0 ? true : false;
|
||||
}
|
||||
|
||||
protected $rule = [
|
||||
'name' => 'require|checkOne',
|
||||
'id' => 'require',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'name.require' => '产品名称不能为空',
|
||||
'name.checkOne' => '同样的产品名称已经存在',
|
||||
'id.require' => '缺少更新条件',
|
||||
];
|
||||
|
||||
protected $scene = [
|
||||
'add' => ['name'],
|
||||
'edit' => ['id'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
<form class="layui-form page-content p-4">
|
||||
<h3 class="h3-title">新建产品</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray-2">产品名称<font>*</font></td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
lay-verify="required"
|
||||
lay-reqText="请输入产品名称"
|
||||
placeholder="请输入产品名称"
|
||||
class="layui-input"
|
||||
value=""
|
||||
/>
|
||||
</td>
|
||||
<td class="layui-td-gray-2">产品负责人<font>*</font></td>
|
||||
<td>
|
||||
<input
|
||||
type="hidden"
|
||||
name="director_uid"
|
||||
lay-verify="required"
|
||||
readonly
|
||||
lay-reqText="请选择产品负责人"
|
||||
value=""
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
name="director_name"
|
||||
placeholder="请选择产品负责人"
|
||||
readonly
|
||||
class="layui-input"
|
||||
value=""
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray-2">参与评审人</td>
|
||||
<td colspan="2">
|
||||
<input
|
||||
type="hidden"
|
||||
id="check_admin_ids"
|
||||
name="check_admin_ids"
|
||||
readonly
|
||||
lay-verify="required"
|
||||
lay-reqText="请选择评审人"
|
||||
value=""
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
id="check_admin_names"
|
||||
name="check_admin_names"
|
||||
readonly
|
||||
class="layui-input"
|
||||
placeholder="请选择评审人"
|
||||
value=""
|
||||
/>
|
||||
</td>
|
||||
<td class="layui-td-gray-2">是否自研<font>*</font></td>
|
||||
<td>
|
||||
<!-- <input type="text" name="is_own" lay-verify="required" lay-reqText="请输入产品名称" placeholder="请输入产品名称"
|
||||
class="layui-input" value=""> -->
|
||||
<select name="is_own" lay-verify="required">
|
||||
<option value="">请选择</option>
|
||||
<option value="1" selected>自研</option>
|
||||
<option value="0">非自研</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray-2">访问权限</td>
|
||||
<td colspan="4">
|
||||
<input
|
||||
type="radio"
|
||||
name="is_open"
|
||||
lay-filter="checkopen"
|
||||
value="1"
|
||||
checked
|
||||
title="内部(仅创建人、负责人、评审人可访问)"
|
||||
/>
|
||||
<input
|
||||
type="radio"
|
||||
name="is_open"
|
||||
lay-filter="checkopen"
|
||||
value="2"
|
||||
title="公开(有产品视图权限员工均可访问)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div>
|
||||
<div class="py-2">产品描述<span style="color: red">*</span></div>
|
||||
<div>
|
||||
<textarea id="mdContent" style="display: none"></textarea>
|
||||
<div id="docContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-1">
|
||||
<input type="hidden" name="id" value="0" />
|
||||
<button
|
||||
class="layui-btn layui-btn-normal"
|
||||
lay-submit=""
|
||||
lay-filter="webform"
|
||||
>
|
||||
立即提交
|
||||
</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function openInit() {
|
||||
var form = layui.form,
|
||||
layer = layui.layer,
|
||||
tool = layui.tool,
|
||||
employeepicker = layui.employeepicker,
|
||||
editor = layui.editormd;
|
||||
|
||||
form.render();
|
||||
var edit = editor.render("docContent", {
|
||||
markdown: $("#mdContent").val(),
|
||||
imageUploadURL: "/api/index/md_upload",
|
||||
lineNumbers: false,
|
||||
toolbarIcons: function () {
|
||||
return [
|
||||
"undo",
|
||||
"redo",
|
||||
"bold",
|
||||
"del",
|
||||
"italic",
|
||||
"quote",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"h4",
|
||||
"h5",
|
||||
"list-ul",
|
||||
"list-ol",
|
||||
"hr",
|
||||
"link",
|
||||
"reference-link",
|
||||
"image",
|
||||
"code",
|
||||
"code-block",
|
||||
"table",
|
||||
"watch",
|
||||
"fullscreen",
|
||||
];
|
||||
},
|
||||
height: window.innerHeight - 120,
|
||||
});
|
||||
//选择产品负责人弹窗
|
||||
$(".page-content").on("click", '[name="director_name"]', function () {
|
||||
var ids = $('[name="director_uid"]').val(),
|
||||
names = $('[name="director_name"]').val();
|
||||
employeepicker.init({
|
||||
ids: ids,
|
||||
names: names,
|
||||
type: 0,
|
||||
department_url: "/api/index/get_department_tree",
|
||||
employee_url: "/api/index/get_employee",
|
||||
callback: function (ids, names, dids, departments) {
|
||||
$('[name="director_uid"]').val(ids);
|
||||
$('[name="director_name"]').val(names);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
//选择产品评审人弹窗
|
||||
$(".page-content").on("click", '[name="check_admin_names"]', function () {
|
||||
var ids = $('[name="check_admin_ids"]').val(),
|
||||
names = $('[name="check_admin_names"]').val(),
|
||||
check_admin_id_array = [],
|
||||
check_admin_name_array = [];
|
||||
if (ids.length > 0) {
|
||||
check_admin_id_array = ids.split(",");
|
||||
check_admin_name_array = names.split(",");
|
||||
}
|
||||
employeepicker.init({
|
||||
ids: check_admin_id_array,
|
||||
names: check_admin_name_array,
|
||||
department_url: "/api/index/get_department_tree",
|
||||
employee_url: "/api/index/get_employee",
|
||||
callback: function (ids, names, dids, departments) {
|
||||
$('[name="check_admin_ids"]').val(ids);
|
||||
$('[name="check_admin_names"]').val(names);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
//监听提交
|
||||
form.on("submit(webform)", function (data) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
tool.close(1000);
|
||||
}
|
||||
};
|
||||
tool.post("/product/index/add", data.field, callback);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,72 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="breadcrumb"}
|
||||
<span class="layui-breadcrumb">
|
||||
<a href="http://www.meteteme.com/" target="_blank">江苏美天科技</a>
|
||||
<a><cite>产品中心</cite></a>
|
||||
</span>
|
||||
{/block}
|
||||
{block name="body"}
|
||||
<div class="table-content p-3">
|
||||
<div class="layui-form-bar border-t border-x">
|
||||
<button class="layui-btn layui-btn-sm add-new">+ 新建产品</button>
|
||||
</div>
|
||||
<table class="layui-hide" id="product" lay-filter="product"></table>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const moduleInit = ['tool','gouguEdit','gouguComment'];
|
||||
function gouguInit() {
|
||||
var table = layui.table, tool = layui.tool;
|
||||
layui.pageTable = table.render({
|
||||
elem: '#product',
|
||||
title: '产品列表',
|
||||
cellMinWidth: 80,
|
||||
url: "/product/index/index", //数据接口
|
||||
page: true, //开启分页
|
||||
limit: 20,
|
||||
height: 'full-130',
|
||||
cols: [[
|
||||
{
|
||||
field: 'id', title: '产品编号', width: 100, align: 'center', fixed: 'left', rowspan: 2, templet: function (d) {
|
||||
return 'P' + d.id;
|
||||
}
|
||||
}
|
||||
, {
|
||||
field: 'status', title: '状态', align: 'center', width: 100, rowspan: 2, templet: function (d) {
|
||||
var html = '<span class="layui-btn layui-btn-xs bg-status-' + d.status + '">' + d.status_name + '</span>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
, {
|
||||
field: 'name', title: '产品名称', align: 'center', rowspan: 2, templet: function (d) {
|
||||
var className = d.is_own == 1 ? 'ziyan' : 'feiziyan';
|
||||
var text = d.is_own == 1 ? '自研' : '非自研';
|
||||
var html = '<div style="display:grid;justify-content:center"><a class="open-a" data-href="/product/index/view/id/' + d.id + '" style="display: flex;justify-content: center;align-items: center;"><span class="' + className + '" style="float:left">' + text + '</span>' + '<p style="float:left">' + d.name + '</p>' + '</a></div>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
, { field: 'director_name', title: '负责人', align: 'center', width: 80, rowspan: 2 }
|
||||
, { field: 'admin_name', title: '创建人', align: 'center', width: 80, rowspan: 2 }
|
||||
, { field: 'projects', title: '关联项目', align: 'center', width: 100, rowspan: 2 }
|
||||
, { align: 'center', title: '关联任务', colspan: 3 }
|
||||
, { align: 'center', title: 'BUG缺陷', colspan: 3 }
|
||||
], [
|
||||
{ field: 'tasks_a_unfinish', align: 'center', style: 'color: #91CC75;', width: 80, 'title': '进行中' }
|
||||
, { field: 'tasks_a_finish', align: 'center', style: 'color: #FAC858;', width: 80, 'title': '已完成' }
|
||||
, { field: 'tasks_a_pensent', align: 'center', style: 'color: #EE6666;', width: 80, 'title': '完成率' }
|
||||
, { field: 'tasks_b_unfinish', align: 'center', style: 'color: #91CC75;', width: 80, 'title': '进行中' }
|
||||
, { field: 'tasks_b_finish', align: 'center', style: 'color: #FAC858;', width: 80, 'title': '已完成' }
|
||||
, { field: 'tasks_b_pensent', align: 'center', style: 'color: #EE6666;', width: 80, 'title': '修复率' }
|
||||
]]
|
||||
});
|
||||
|
||||
$('.add-new').on('click', function () {
|
||||
tool.open('/product/index/add');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
@@ -0,0 +1,404 @@
|
||||
<div class="page-content">
|
||||
<div class="p-4 border-b">
|
||||
<h3 class="h3-title hover-{$role_edit}">
|
||||
<span class="layui-btn layui-btn-xs bg-status-{$detail.status}">{$detail.status_name}</span>
|
||||
<span id="name_{$detail.id}" data-val="">{$detail.name}</span><i class="iconfont icon-wodedianping"
|
||||
title="编辑" data-id="{$detail.id}" data-name="name"></i>
|
||||
</h3>
|
||||
<div>
|
||||
<span class="layui-badge layui-bg-gray">#P{$detail.id}</span>
|
||||
<span class="mx-2">{$detail.admin_name}</span>
|
||||
<span class="font-gray">创建于{$detail.times}<span id="editTips">{gt name="$detail.update_time"
|
||||
value="0"},最近更新于 {:time_trans($detail.update_time)}{/gt}</span></span>
|
||||
{eq name="$detail.admin_id" value="$params.uid"}
|
||||
<span class="layui-btn layui-btn-xs layui-btn-danger ml-4" id="delBtn"><i
|
||||
class="layui-icon"></i>删除</span>
|
||||
{/eq}
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row border-b">
|
||||
<div class="layui-col-md9 p-4 border-r">
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">负责人</td>
|
||||
<td class="hover-{$role_edit}"><span id="director_uid_{$detail.id}"
|
||||
data-val="{$detail.director_uid}">{$detail.director_name}</span><i
|
||||
class="iconfont icon-wodedianping" title="编辑" data-id="{$detail.id}"
|
||||
data-name="director_uid"></i></td>
|
||||
<td class="layui-td-gray">状态</td>
|
||||
<td class="hover-{$role_edit}"><span class="color-status-{$detail.status}" id="status_{$detail.id}"
|
||||
data-val="{$detail.status}">{$detail.status_name}</span><i
|
||||
class="iconfont icon-wodedianping" title="编辑" data-name="status"></i>
|
||||
</td>
|
||||
<td class="layui-td-gray">是否自研</td>
|
||||
<td class="hover-{$role_edit}"><span class="color-is_own-{$detail.is_own}" id="is_own_{$detail.id}"
|
||||
data-val="{$detail.is_own}">{$detail.is_own_name}</span><i
|
||||
class="iconfont icon-wodedianping" title="编辑" data-name="is_own"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">评审人</td>
|
||||
<td colspan="3" class="hover-{$role_edit}"><span id="check_admin_ids_{$detail.id}"
|
||||
data-val="{$detail.check_admin_ids}">{$detail.check_admin_names}</span><i
|
||||
class="iconfont icon-wodedianping" title="编辑" data-id="{$detail.id}"
|
||||
data-name="check_admin_ids"></i></td>
|
||||
<td class="layui-td-gray">访问权限</td>
|
||||
<td class="hover-{$role_edit}">
|
||||
<span id="is_open_{$detail.id}" data-val="{$detail.is_open}">
|
||||
{eq name="$detail.is_open" value="1" }
|
||||
内部 <span class="font-gray">(仅创建人、负责人、评审人可访问)</span>
|
||||
{/eq}
|
||||
{eq name="$detail.is_open" value="2" }公开 <span class="font-gray">(有产品视图权限员工均可访问)</span>{/eq}
|
||||
</span>
|
||||
<i class="iconfont icon-wodedianping" title="编辑" data-id="{$detail.id}" data-name="is_open"></i>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<div class="md-content-content hover-{$role_edit}">
|
||||
<h5 class="py-4">产品描述<i class="iconfont icon-wodedianping" title="编辑" data-id="{$detail.id}"
|
||||
data-name="md_content"></i></h5>
|
||||
<div id="md_content_{$detail.id}" data-val="{$detail.md_content}">{$detail.content|raw}</div>
|
||||
</div>
|
||||
<div class="detail-file">
|
||||
<h5 class="py-4">文件附件</h5>
|
||||
<div>
|
||||
{eq name="$role_edit" value="edit"}
|
||||
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" id="flieBtn">选择文件并上传</button>
|
||||
<span
|
||||
style="color:#FF5722; font-size:12px; margin-left: 8px;">上传前,请规范命名,最大只能上传{:get_system_info('upload_max_filesize')}的文件,超过请压缩成多个文件上传。</span>
|
||||
<div class="layui-upload-list" {empty name="$file_array" }style="display:none;" {/empty}>
|
||||
<table class="layui-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="60%">文件名</th>
|
||||
<th width="15%" style="text-align:center">文件大小</th>
|
||||
<th width="10%" style="text-align:center">上传人</th>
|
||||
<th width="15%" style="text-align:center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="flieList">
|
||||
{volist name="file_array" id="vo"}
|
||||
<tr>
|
||||
<td>{$vo.name}</td>
|
||||
<td style="text-align: center;">{$vo.filesize/1048576|round=2}MB</td>
|
||||
<td style="text-align: center;">{$vo.admin_name}</td>
|
||||
<td style="text-align: center;">
|
||||
<div class="layui-btn-group"><a class="layui-btn layui-btn-xs "
|
||||
href="{$vo.filepath}" download="{$vo.name}" data-id="{$vo.id}">下载</a>
|
||||
<span class="layui-btn layui-btn-xs layui-btn-danger file-delete"
|
||||
data-uid="{$vo.admin_id}" data-id="{$vo.id}">删除</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{else/}
|
||||
<table class="layui-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="60%">文件名</th>
|
||||
<th width="15%" style="text-align:center">文件大小</th>
|
||||
<th width="10%" style="text-align:center">上传人</th>
|
||||
<th width="15%" style="text-align:center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="flieList">
|
||||
{volist name="file_array" id="vo"}
|
||||
<tr data-id="{$vo.id}" id="flie_{$vo.id}">
|
||||
<td>{$vo.name}</td>
|
||||
<td style="text-align: center;">{$vo.filesize/1048576|round=2}MB</td>
|
||||
<td style="text-align: center;">{$vo.admin_name}</td>
|
||||
<td style="text-align: center;">
|
||||
<a class="layui-btn layui-btn-xs" href="{$vo.filepath}" download="{$vo.name}"
|
||||
data-id="{$vo.id}">下载</a>
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
{empty name="$file_array" }
|
||||
<tr>
|
||||
<td colspan="4" class="content-none">暂无附件</td>
|
||||
</tr>
|
||||
{/empty}
|
||||
</tbody>
|
||||
</table>
|
||||
{/eq}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-link">
|
||||
<h5 class="py-4">关联链接</h5>
|
||||
<div>
|
||||
{eq name="$role_edit" value="edit"}
|
||||
<button type="button" class="layui-btn layui-btn-sm" id="linkBtn">新增相关联链接</button>
|
||||
<span style="color:#FF5722; font-size:12px; margin-left: 8px;">请规范填写链接说明,方便大家查阅。</span>
|
||||
<div class="layui-upload-list" {empty name="$link_array" }style="display:none;" {/empty}>
|
||||
<table class="layui-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="60%">链接</th>
|
||||
<th width="15%" style="text-align:center">说明</th>
|
||||
<th width="10%" style="text-align:center">添加人</th>
|
||||
<th width="15%" style="text-align:center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="linkList">
|
||||
{volist name="link_array" id="vo"}
|
||||
<tr data-id="{$vo.id}" data-url="{$vo.url}" id="link_{$vo.id}">
|
||||
<td><a href="{$vo.url}" target="_blank">{$vo.url}</a></td>
|
||||
<td>{$vo.desc}</td>
|
||||
<td style="text-align: center;">{$vo.admin_name}</td>
|
||||
<td style="text-align: center;">
|
||||
<div class="layui-btn-group"><span class="layui-btn layui-btn-xs link-edit"
|
||||
data-id="{$vo.id}" data-url="{$vo.url}" data-href="{$vo.url}" data-desc="{$vo.desc}">编辑</span>
|
||||
<span class="layui-btn layui-btn-xs layui-btn-danger link-delete"
|
||||
data-uid="{$vo.admin_id}" data-id="{$vo.id}">删除</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{else/}
|
||||
<table class="layui-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="60%">链接</th>
|
||||
<th width="30%" style="text-align:center">说明</th>
|
||||
<th width="10%" style="text-align:center">添加人</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="linkList">
|
||||
{volist name="link_array" id="vo"}
|
||||
<tr>
|
||||
<td><a href="{$vo.url}" target="_blank">{$vo.url}</a></td>
|
||||
<td>{$vo.desc}</td>
|
||||
<td style="text-align: center;">{$vo.admin_name}</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
{empty name="$link_array" }
|
||||
<tr>
|
||||
<td colspan="3" class="content-none">暂无链接</td>
|
||||
</tr>
|
||||
{/empty}
|
||||
</tbody>
|
||||
</table>
|
||||
{/eq}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3 p-4">
|
||||
<div class="pb-4"><span class="font-gray">关联项目:</span>{$detail.projects}</div>
|
||||
{volist name="$detail.task_cate" id="vo"}
|
||||
<div class="pb-4"><span class="font-gray">{$vo.title}任务:</span>{$vo.count}</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-tab layui-tab-brief px-4" lay-filter="docDemoTabBrief">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">互动评论({$detail.comments})</li>
|
||||
<li>操作日志({$detail.logs})</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content p-0">
|
||||
<div class="layui-tab-item comment-list layui-show">
|
||||
<div class="comment-input my-2">
|
||||
<input type="text" id="commentInput" readonly placeholder="发表一下你的看法" class="layui-input" value="">
|
||||
</div>
|
||||
<div id="comment_product_{$detail.id}"></div>
|
||||
</div>
|
||||
<div class="layui-tab-item logs-list">
|
||||
<div id="log_product_{$detail.id}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function openInit() {
|
||||
const detail_id = '{$detail.id}';
|
||||
const opsData = {
|
||||
status: [
|
||||
{ 'id': 0, 'title': '关闭' },
|
||||
{ 'id': 1, 'title': '开启' }
|
||||
],
|
||||
is_own: [
|
||||
{ 'id': 0, 'title': '非自研' },
|
||||
{ 'id': 1, 'title': '自研' }
|
||||
]
|
||||
}
|
||||
var layer = layui.layer, tool = layui.tool, edit = layui.gouguEdit, comment = layui.gouguComment, upload = layui.upload;
|
||||
|
||||
$('.hover-edit').hover(function () {
|
||||
$(this).addClass('hover-on');
|
||||
}, function () {
|
||||
$(this).removeClass('hover-on');
|
||||
})
|
||||
|
||||
$('.hover-edit').on('click', 'i', function () {
|
||||
let name = $(this).data('name');
|
||||
let show_txt = $('#' + name + '_' + detail_id).text().replace(/[\r\n\t]/g, "");
|
||||
let real_txt = $('#' + name + '_' + detail_id).data('val');
|
||||
if (real_txt === '') {
|
||||
real_txt = show_txt;
|
||||
}
|
||||
editShow(detail_id, name, show_txt, real_txt);
|
||||
})
|
||||
|
||||
$('#delBtn').on('click', function () {
|
||||
layer.confirm('确定要删除该产品吗?请慎重', { icon: 3, title: '提示' }, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.closeAll();
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
setTimeout(function () {
|
||||
location.reload();
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
let postData = { "id": detail_id };
|
||||
tool.delete("/product/index/delete", postData, callback);
|
||||
});
|
||||
})
|
||||
|
||||
upload.render({
|
||||
elem: '#flieBtn'
|
||||
, url: '/api/index/upload'
|
||||
, accept: 'file' //普通文件
|
||||
, exts: 'jpeg|jpg|png|gif|doc|docx|ppt|pptx|xls|xlsx|pdf|zip|rar|7z' //只允许上传文件
|
||||
, before: function (obj) {
|
||||
layer.msg('上传中...', { time: 3600000 });
|
||||
}
|
||||
, done: function (res, index, upload) {
|
||||
let callback = function (e) {
|
||||
layer.msg('上传成功');
|
||||
tool.load("/product/index/view?id=" + detail_id);
|
||||
}
|
||||
let postData = { 'topic_id': detail_id, 'file_id': res.data.id, 'file_name': res.data.name, 'module': 'product' };
|
||||
tool.post("/api/appendix/add", postData, callback);
|
||||
}
|
||||
, error: function (index, upload) {
|
||||
layer.msg('上传失败');
|
||||
}
|
||||
});
|
||||
|
||||
$('#flieList').on('click', '.file-delete', function () {
|
||||
let id = $(this).data('id');
|
||||
layer.confirm('确定要删除该附件吗?', { icon: 3, title: '提示' }, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.closeAll();
|
||||
layer.msg(e.msg);
|
||||
tool.load("/product/index/view?id=" + detail_id);
|
||||
}
|
||||
let postData = { "id": id };
|
||||
tool.delete("/api/appendix/delete", postData, callback);
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
$('#linkBtn').on('click', function () {
|
||||
comment.addLink(0, detail_id, 'product', '', '');
|
||||
})
|
||||
$('#linkList').on('click', '.link-edit', function () {
|
||||
let id = $(this).data('id');
|
||||
let url = $(this).data('url');
|
||||
let desc = $(this).data('desc');
|
||||
console.log(url)
|
||||
comment.addLink(id, detail_id, 'product', url, desc);
|
||||
})
|
||||
$('#linkList').on('click', '.link-delete', function () {
|
||||
let id = $(this).data('id');
|
||||
layer.confirm('确定要删除该链接吗?', { icon: 3, title: '提示' }, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.closeAll();
|
||||
layer.msg(e.msg);
|
||||
tool.load("/product/index/view?id=" + detail_id);
|
||||
}
|
||||
let postData = { "id": id };
|
||||
tool.delete("/api/appendix/delete_link", postData, callback);
|
||||
});
|
||||
})
|
||||
|
||||
//评论
|
||||
comment.load(detail_id, 'product');
|
||||
$('#commentInput').on('click', function () {
|
||||
comment.editor(0, detail_id, 0, 0, 'product', '');
|
||||
})
|
||||
//回复
|
||||
$('#comment_product_' + detail_id).on('click', '[data-event="replay"]', function () {
|
||||
let pid = $(this).data('id');
|
||||
let padmin_id = $(this).data('uid');
|
||||
comment.editor(0, detail_id, pid, padmin_id, 'product', '');
|
||||
})
|
||||
//编辑
|
||||
$('#comment_product_' + detail_id).on('click', '[data-event="edit"]', function () {
|
||||
let id = $(this).data('id');
|
||||
let mdcontent = $('#comment_' + id).data('mdcontent');
|
||||
comment.editor(id, detail_id, 0, 0, 'product', mdcontent);
|
||||
})
|
||||
|
||||
//删除
|
||||
$('#comment_product_' + detail_id).on('click', '[data-event="del"]', function () {
|
||||
let id = $(this).data('id');
|
||||
comment.del(id, detail_id, 'product');
|
||||
})
|
||||
|
||||
//操作记录
|
||||
comment.log(detail_id, 'product');
|
||||
|
||||
let loading = false;
|
||||
let editPost = function (id, name, show_val, real_val) {
|
||||
let callback = function (e) {
|
||||
if (e.code == 0) {
|
||||
layer.closeAll();
|
||||
tool.load('/product/index/view/id/' + id);
|
||||
if (layui.pageTable) {
|
||||
setTimeout(function () {
|
||||
layui.pageTable.reload();
|
||||
}, 400)
|
||||
}
|
||||
} else {
|
||||
layer.msg(e.msg);
|
||||
}
|
||||
}
|
||||
let postData = { id: id };
|
||||
postData[name] = real_val;
|
||||
if (name == 'md_content') {
|
||||
postData['content'] = show_val;
|
||||
}
|
||||
tool.post("/product/index/add", postData, callback);
|
||||
}
|
||||
|
||||
function editShow(id, name, show_txt, real_txt) {
|
||||
if (loading == true) {
|
||||
return false;
|
||||
}
|
||||
if (name == "name") {
|
||||
edit.text(id, name, real_txt, editPost);
|
||||
}
|
||||
if (name == "director_uid") {
|
||||
edit.employee_one(id, name, show_txt, real_txt, editPost);
|
||||
}
|
||||
if (name == "check_admin_ids") {
|
||||
edit.employee_more(id, name, show_txt, real_txt, editPost);
|
||||
}
|
||||
if (name == "status") {
|
||||
edit.dropdown(id, name, real_txt, opsData[name], editPost);
|
||||
}
|
||||
if (name == "is_own") {
|
||||
edit.dropdown(id, name, real_txt, opsData[name], editPost);
|
||||
}
|
||||
if (name == "is_open") {
|
||||
let data = [
|
||||
{ 'id': 1, 'title': '内部(仅创建人、负责人、评审人可访问)' },
|
||||
{ 'id': 2, 'title': '公开(有产品视图权限员工均可访问)' }
|
||||
];
|
||||
edit.select_type(id, name, real_txt, data, editPost);
|
||||
}
|
||||
if (name == "md_content") {
|
||||
edit.editor(id, name, real_txt, editPost);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user